All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>,
	Cedric Xing <cedric.xing@intel.com>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	James Morris <jmorris@namei.org>,
	"Serge E . Hallyn" <serge@hallyn.com>,
	LSM List <linux-security-module@vger.kernel.org>,
	Paul Moore <paul@paul-moore.com>,
	Eric Paris <eparis@parisplace.org>,
	selinux@vger.kernel.org, Jethro Beekman <jethro@fortanix.com>,
	Dave Hansen <dave.hansen@intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>, X86 ML <x86@kernel.org>,
	linux-sgx@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	nhorman@redhat.com, npmccallum@redhat.com,
	Serge Ayoun <serge.ayoun@intel.com>,
	Shay Katz-zamir <shay.katz-zamir@intel.com>,
	Haitao Huang <haitao.huang@intel.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Kai Svahn <kai.svahn@intel.com>, Borislav Petkov <bp@alien8.de>,
	Josh Triplett <josh@joshtriplett.org>,
	Kai Huang <kai.huang@intel.com>,
	David Rientjes <rientjes@google.com>,
	William Roberts <william.c.roberts@intel.com>,
	Philip Tricca <philip.b.tricca@intel.com>
Subject: [RFC PATCH 3/9] x86/sgx: Allow userspace to add multiple pages in single ioctl()
Date: Fri, 31 May 2019 16:31:53 -0700	[thread overview]
Message-ID: <20190531233159.30992-4-sean.j.christopherson@intel.com> (raw)
In-Reply-To: <20190531233159.30992-1-sean.j.christopherson@intel.com>

...to improve performance when building enclaves by reducing the number
of user<->system transitions.  Rather than provide arbitrary batching,
e.g. with per-page SECINFO and mrmask, take advantage of the fact that
any sane enclave will have large swaths of pages with identical
properties, e.g. code vs. data sections.

For simplicity and stability in the initial implementation, loop over
the existing add page flow instead of taking a more agressive approach,
which would require tracking transitions between VMAs and holding
mmap_sem for an extended duration.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 arch/x86/include/uapi/asm/sgx.h        |  21 ++---
 arch/x86/kernel/cpu/sgx/driver/ioctl.c | 104 +++++++++++++++----------
 2 files changed, 74 insertions(+), 51 deletions(-)

diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h
index 9ed690a38c70..4a12d6abbcb7 100644
--- a/arch/x86/include/uapi/asm/sgx.h
+++ b/arch/x86/include/uapi/asm/sgx.h
@@ -12,8 +12,8 @@
 
 #define SGX_IOC_ENCLAVE_CREATE \
 	_IOW(SGX_MAGIC, 0x00, struct sgx_enclave_create)
-#define SGX_IOC_ENCLAVE_ADD_PAGE \
-	_IOW(SGX_MAGIC, 0x01, struct sgx_enclave_add_page)
+#define SGX_IOC_ENCLAVE_ADD_PAGES \
+	_IOW(SGX_MAGIC, 0x01, struct sgx_enclave_add_pages)
 #define SGX_IOC_ENCLAVE_INIT \
 	_IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init)
 #define SGX_IOC_ENCLAVE_SET_ATTRIBUTE \
@@ -32,21 +32,22 @@ struct sgx_enclave_create  {
 };
 
 /**
- * struct sgx_enclave_add_page - parameter structure for the
- *                               %SGX_IOC_ENCLAVE_ADD_PAGE ioctl
- * @addr:	address within the ELRANGE
- * @src:	address for the page data
- * @secinfo:	address for the SECINFO data
- * @mrmask:	bitmask for the measured 256 byte chunks
+ * struct sgx_enclave_add_pages - parameter structure for the
+ *                                %SGX_IOC_ENCLAVE_ADD_PAGES ioctl
+ * @addr:	start address within the ELRANGE
+ * @src:	start address for the pages' data
+ * @secinfo:	address for the SECINFO data (common to all pages)
+ * @nr_pages:	number of pages (must be virtually contiguous)
+ * @mrmask:	bitmask for the measured 256 byte chunks (common to all pages)
  */
-struct sgx_enclave_add_page {
+struct sgx_enclave_add_pages {
 	__u64	addr;
 	__u64	src;
 	__u64	secinfo;
+	__u32	nr_pages;
 	__u16	mrmask;
 } __attribute__((__packed__));
 
-
 /**
  * struct sgx_enclave_init - parameter structure for the
  *                           %SGX_IOC_ENCLAVE_INIT ioctl
diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c
index a27ec26a9350..6acfcbdeca9a 100644
--- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c
@@ -487,10 +487,9 @@ static int sgx_validate_tcs(struct sgx_encl *encl, struct sgx_tcs *tcs)
 	return 0;
 }
 
-static int __sgx_encl_add_page(struct sgx_encl *encl,
+static int sgx_encl_queue_page(struct sgx_encl *encl,
 			       struct sgx_encl_page *encl_page,
-			       void *data,
-			       struct sgx_secinfo *secinfo,
+			       void *data, struct sgx_secinfo *secinfo,
 			       unsigned int mrmask)
 {
 	unsigned long page_index = sgx_encl_get_index(encl, encl_page);
@@ -529,9 +528,9 @@ static int __sgx_encl_add_page(struct sgx_encl *encl,
 	return 0;
 }
 
-static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr,
-			     void *data, struct sgx_secinfo *secinfo,
-			     unsigned int mrmask)
+static int __sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr,
+			       void *data, struct sgx_secinfo *secinfo,
+			       unsigned int mrmask)
 {
 	u64 page_type = secinfo->flags & SGX_SECINFO_PAGE_TYPE_MASK;
 	struct sgx_encl_page *encl_page;
@@ -563,7 +562,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr,
 		goto out;
 	}
 
-	ret = __sgx_encl_add_page(encl, encl_page, data, secinfo, mrmask);
+	ret = sgx_encl_queue_page(encl, encl_page, data, secinfo, mrmask);
 	if (ret) {
 		radix_tree_delete(&encl_page->encl->page_tree,
 				  PFN_DOWN(encl_page->desc));
@@ -575,56 +574,79 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr,
 	return ret;
 }
 
-/**
- * sgx_ioc_enclave_add_page - handler for %SGX_IOC_ENCLAVE_ADD_PAGE
- *
- * @filep:	open file to /dev/sgx
- * @cmd:	the command value
- * @arg:	pointer to an &sgx_enclave_add_page instance
- *
- * Add a page to an uninitialized enclave (EADD), and optionally extend the
- * enclave's measurement with the contents of the page (EEXTEND).  EADD and
- * EEXTEND are done asynchronously via worker threads.  A successful
- * sgx_ioc_enclave_add_page() only indicates the page has been added to the
- * work queue, it does not guarantee adding the page to the enclave will
- * succeed.
- *
- * Return:
- *   0 on success,
- *   -errno otherwise
- */
-static long sgx_ioc_enclave_add_page(struct file *filep, unsigned int cmd,
-				     unsigned long arg)
+static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr,
+			     unsigned long src, struct sgx_secinfo *secinfo,
+			     unsigned int mrmask)
 {
-	struct sgx_enclave_add_page *addp = (void *)arg;
-	struct sgx_encl *encl = filep->private_data;
-	struct sgx_secinfo secinfo;
 	struct page *data_page;
 	void *data;
 	int ret;
 
-	if (copy_from_user(&secinfo, (void __user *)addp->secinfo,
-			   sizeof(secinfo)))
-		return -EFAULT;
-
 	data_page = alloc_page(GFP_HIGHUSER);
 	if (!data_page)
 		return -ENOMEM;
 
 	data = kmap(data_page);
 
-	if (copy_from_user((void *)data, (void __user *)addp->src, PAGE_SIZE)) {
+	if (copy_from_user((void *)data, (void __user *)src, PAGE_SIZE)) {
 		ret = -EFAULT;
 		goto out;
 	}
 
-	ret = sgx_encl_add_page(encl, addp->addr, data, &secinfo, addp->mrmask);
-	if (ret)
-		goto out;
-
+	ret = __sgx_encl_add_page(encl, addr, data, secinfo, mrmask);
 out:
 	kunmap(data_page);
 	__free_page(data_page);
+
+	return ret;
+}
+
+/**
+ * sgx_ioc_enclave_add_pages - handler for %SGX_IOC_ENCLAVE_ADD_PAGES
+ *
+ * @filep:	open file to /dev/sgx
+ * @cmd:	the command value
+ * @arg:	pointer to an &sgx_enclave_add_page instance
+ *
+ * Add a range of pages to an uninitialized enclave (EADD), and optionally
+ * extend the enclave's measurement with the contents of the page (EEXTEND).
+ * The range of pages must be virtually contiguous.  The SECINFO and
+ * measurement maskare applied to all pages, i.e. pages with different
+ * properties must be added in separate calls.
+ *
+ * EADD and EEXTEND are done asynchronously via worker threads.  A successful
+ * sgx_ioc_enclave_add_page() only indicates the pages have been added to the
+ * work queue, it does not guarantee adding the pages to the enclave will
+ * succeed.
+ *
+ * Return:
+ *   0 on success,
+ *   -errno otherwise
+ */
+static long sgx_ioc_enclave_add_pages(struct file *filep, unsigned int cmd,
+				      unsigned long arg)
+{
+	struct sgx_enclave_add_pages *addp = (void *)arg;
+	struct sgx_encl *encl = filep->private_data;
+	struct sgx_secinfo secinfo;
+	unsigned int i;
+	int ret;
+
+	if (copy_from_user(&secinfo, (void __user *)addp->secinfo,
+			   sizeof(secinfo)))
+		return -EFAULT;
+
+	for (i = 0, ret = 0; i < addp->nr_pages && !ret; i++) {
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+
+		if (need_resched())
+			cond_resched();
+
+		ret = sgx_encl_add_page(encl, addp->addr + i*PAGE_SIZE,
+					addp->src + i*PAGE_SIZE,
+					&secinfo, addp->mrmask);
+	}
 	return ret;
 }
 
@@ -823,8 +845,8 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 	case SGX_IOC_ENCLAVE_CREATE:
 		handler = sgx_ioc_enclave_create;
 		break;
-	case SGX_IOC_ENCLAVE_ADD_PAGE:
-		handler = sgx_ioc_enclave_add_page;
+	case SGX_IOC_ENCLAVE_ADD_PAGES:
+		handler = sgx_ioc_enclave_add_pages;
 		break;
 	case SGX_IOC_ENCLAVE_INIT:
 		handler = sgx_ioc_enclave_init;
-- 
2.21.0


  parent reply	other threads:[~2019-05-31 23:32 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-31 23:31 [RFC PATCH 0/9] security: x86/sgx: SGX vs. LSM Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 1/9] x86/sgx: Remove unused local variable in sgx_encl_release() Sean Christopherson
2019-06-04 11:41   ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 2/9] x86/sgx: Do not naturally align MAP_FIXED address Sean Christopherson
2019-06-04 11:49   ` Jarkko Sakkinen
2019-06-04 20:16     ` Andy Lutomirski
2019-06-04 22:10       ` Xing, Cedric
2019-06-05 14:08         ` Sean Christopherson
2019-06-05 15:17         ` Jarkko Sakkinen
2019-06-05 20:14           ` Andy Lutomirski
2019-06-06 15:37             ` Jarkko Sakkinen
2019-06-13 13:48               ` Jarkko Sakkinen
2019-06-13 16:47                 ` Xing, Cedric
2019-06-13 17:14                   ` Sean Christopherson
2019-06-14 15:18                     ` Jarkko Sakkinen
2019-06-05 15:15       ` Jarkko Sakkinen
2019-05-31 23:31 ` Sean Christopherson [this message]
2019-06-03  6:26   ` [RFC PATCH 3/9] x86/sgx: Allow userspace to add multiple pages in single ioctl() Xing, Cedric
2019-06-03 20:08     ` Sean Christopherson
2019-06-03 20:39       ` Sean Christopherson
2019-06-03 23:45         ` Xing, Cedric
2019-06-04  0:54           ` Sean Christopherson
2019-06-04 20:18         ` Andy Lutomirski
2019-06-04 22:02           ` Xing, Cedric
2019-06-03 20:14   ` Dave Hansen
2019-06-03 20:37     ` Sean Christopherson
2019-06-03 20:39       ` Dave Hansen
2019-06-03 23:48       ` Xing, Cedric
2019-06-04  0:55         ` Sean Christopherson
2019-06-04 11:55   ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 4/9] mm: Introduce vm_ops->mprotect() Sean Christopherson
2019-06-03  6:27   ` Xing, Cedric
2019-06-04 12:24   ` Jarkko Sakkinen
2019-06-04 14:51   ` Andy Lutomirski
2019-05-31 23:31 ` [RFC PATCH 5/9] x86/sgx: Restrict mapping without an enclave page to PROT_NONE Sean Christopherson
2019-06-03  6:28   ` Xing, Cedric
2019-06-04 15:32   ` Jarkko Sakkinen
2019-05-31 23:31 ` [RFC PATCH 6/9] x86/sgx: Require userspace to provide allowed prots to ADD_PAGES Sean Christopherson
2019-06-03  6:28   ` Xing, Cedric
2019-06-04 16:23   ` Jarkko Sakkinen
2019-06-04 16:45     ` Sean Christopherson
2019-06-05 15:06       ` Jarkko Sakkinen
2019-06-04 20:23   ` Andy Lutomirski
2019-06-05 11:10   ` Ayoun, Serge
2019-06-05 23:58     ` Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 7/9] x86/sgx: Enforce noexec filesystem restriction for enclaves Sean Christopherson
2019-06-03  6:29   ` Xing, Cedric
2019-06-04 20:26     ` Andy Lutomirski
2019-06-04 16:25   ` Jarkko Sakkinen
2019-06-04 20:25     ` Andy Lutomirski
2019-06-04 20:34       ` Sean Christopherson
2019-06-04 21:54       ` Xing, Cedric
2019-06-05 15:10       ` Jarkko Sakkinen
2019-06-06  1:01         ` Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 8/9] LSM: x86/sgx: Introduce ->enclave_load() hook for Intel SGX Sean Christopherson
2019-06-03  6:28   ` Xing, Cedric
2019-06-03 14:19   ` Stephen Smalley
2019-06-03 14:42     ` Sean Christopherson
2019-06-03 18:38       ` Stephen Smalley
2019-06-03 18:45         ` Dave Hansen
2019-06-04 20:29   ` Andy Lutomirski
2019-06-04 20:36     ` Sean Christopherson
2019-06-04 21:43       ` Xing, Cedric
2019-06-06  2:04         ` Sean Christopherson
2019-05-31 23:31 ` [RFC PATCH 9/9] security/selinux: Add enclave_load() implementation Sean Christopherson
2019-06-03 15:01   ` Stephen Smalley
2019-06-03 15:50     ` Sean Christopherson
2019-06-02  7:29 ` [RFC PATCH 0/9] security: x86/sgx: SGX vs. LSM Xing, Cedric
2019-06-03 17:15   ` Sean Christopherson
2019-06-03 18:30     ` Xing, Cedric
2019-06-04  1:36       ` Sean Christopherson
2019-06-04 15:33       ` Stephen Smalley
2019-06-04 16:30         ` Sean Christopherson
2019-06-04 21:38         ` Xing, Cedric
2019-06-03 17:47   ` Stephen Smalley
2019-06-03 18:02     ` Xing, Cedric
2019-06-04 11:15 ` Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190531233159.30992-4-sean.j.christopherson@intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=cedric.xing@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=eparis@parisplace.org \
    --cc=haitao.huang@intel.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jethro@fortanix.com \
    --cc=jmorris@namei.org \
    --cc=josh@joshtriplett.org \
    --cc=kai.huang@intel.com \
    --cc=kai.svahn@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-sgx@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=nhorman@redhat.com \
    --cc=npmccallum@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=philip.b.tricca@intel.com \
    --cc=rientjes@google.com \
    --cc=sds@tycho.nsa.gov \
    --cc=selinux@vger.kernel.org \
    --cc=serge.ayoun@intel.com \
    --cc=serge@hallyn.com \
    --cc=shay.katz-zamir@intel.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=william.c.roberts@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.