linux-sgx.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: linux-sgx@vger.kernel.org
Subject: [PATCH for_v23 3/7] x86/sgx: Tweak ADD_PAGE ioctl to allow adding multiple pages
Date: Tue,  8 Oct 2019 21:42:37 -0700	[thread overview]
Message-ID: <20191009044241.3591-4-sean.j.christopherson@intel.com> (raw)
In-Reply-To: <20191009044241.3591-1-sean.j.christopherson@intel.com>

Add a nr_pages param to the ioctl for adding pages to the enclave so
that userspace can batch multiple pages in a single syscall.  Update the
offset, src and nr_pages params prior to returning to userspace so that
the caller has sufficient information to analyze failures and can easily
restart the ioctl when appropriate.

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

diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h
index 67583b046af1..84734229d8dd 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 \
+	_IOWR(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 \
@@ -29,17 +29,19 @@ struct sgx_enclave_create  {
 };
 
 /**
- * struct sgx_enclave_add_page - parameter structure for the
- *                               %SGX_IOC_ENCLAVE_ADD_PAGE ioctl
- * @offset:	page offset within the enclave
- * @src:	address for the page data
+ * struct sgx_enclave_add_pages - parameter structure for the
+ *                                %SGX_IOC_ENCLAVE_ADD_PAGE ioctl
+ * @offset:	starting page offset within the ELRANGE
+ * @src:	start address for the page data
+ * @nr_pages:	number of pages to add to enclave
  * @secinfo:	address for the SECINFO data
  * @mrmask:	bitmask for the measured 256 byte chunks
  * @reserved:	reserved for future use
  */
-struct sgx_enclave_add_page {
+struct sgx_enclave_add_pages {
 	__u64	offset;
 	__u64	src;
+	__u64	nr_pages;
 	__u64	secinfo;
 	__u16	mrmask;
 	__u8	reserved[6];
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
index f407dd35f9e3..4597dd8f5c91 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
@@ -360,7 +360,7 @@ static int __sgx_encl_extend(struct sgx_encl *encl,
 }
 
 static int sgx_encl_add_page(struct sgx_encl *encl,
-			     struct sgx_enclave_add_page *addp,
+			     struct sgx_enclave_add_pages *addp,
 			     struct sgx_secinfo *secinfo)
 {
 	struct sgx_encl_page *encl_page;
@@ -443,14 +443,19 @@ static int sgx_encl_add_page(struct sgx_encl *encl,
 }
 
 /**
- * sgx_ioc_enclave_add_page() - The handler for %SGX_IOC_ENCLAVE_ADD_PAGE
- * @filep:	open file to /dev/sgx
- * @arg:	a user pointer to a struct sgx_enclave_add_page instance
+ * sgx_ioc_enclave_add_pages() - The handler for %SGX_IOC_ENCLAVE_ADD_PAGES
+ * @encl:       pointer to an enclave instance (via ioctl() file pointer)
+ * @arg:	a user pointer to a struct sgx_enclave_add_pages instance
  *
- * Add (EADD) a page to an uninitialized enclave, and optionally extend
- * (EEXTEND) the measurement with the contents of the page. A SECINFO for a TCS
- * is required to always contain zero permissions because CPU silently zeros
- * them. Allowing anything else would cause a mismatch in the measurement.
+ * Add (EADD) one or more pages to an uninitialized enclave, and optionally
+ * extend (EEXTEND) the measurement with the contents of the page. The range of
+ * pages must be virtually contiguous. The SECINFO and measurement mask are
+ * applied to all pages, i.e. pages with different properties must be added in
+ * separate calls.
+ *
+ * A SECINFO for a TCS is required to always contain zero permissions because
+ * CPU silently zeros them. Allowing anything else would cause a mismatch in
+ * the measurement.
  *
  * mmap()'s protection bits are capped by the page permissions. For each page
  * address, the maximum protection bits are computed with the following
@@ -467,17 +472,25 @@ static int sgx_encl_add_page(struct sgx_encl *encl,
  * permissions. In effect, this allows mmap() with PROT_NONE to be used to seek
  * an address range for the enclave that can be then populated into SECS.
  *
+ * @arg->addr, @arg->src and @arg->nr_pages are adjusted to reflect the
+ * remaining pages that need to be added to the enclave, e.g. userspace can
+ * re-invoke SGX_IOC_ENCLAVE_ADD_PAGES using the same struct in response to an
+ * ERESTARTSYS error.
+ *
  * Return:
  *   0 on success,
- *   -EINVAL if the SECINFO contains invalid data,
- *   -EACCES if the source page is located in a noexec partition,
+ *   -EINVAL if any input param or the SECINFO contains invalid data,
+ *   -EACCES if an executable source page is located in a noexec partition,
  *   -ENOMEM if any memory allocation, including EPC, fails,
+ *   -ERESTARTSYS if a pending signal is recognized,
  *   -errno otherwise
+
  */
-static long sgx_ioc_enclave_add_page(struct sgx_encl *encl, void __user *arg)
+static long sgx_ioc_enclave_add_pages(struct sgx_encl *encl, void __user *arg)
 {
-	struct sgx_enclave_add_page addp;
+	struct sgx_enclave_add_pages addp;
 	struct sgx_secinfo secinfo;
+	int ret;
 
 	if (!(atomic_read(&encl->flags) & SGX_ENCL_CREATED))
 		return -EINVAL;
@@ -489,7 +502,10 @@ static long sgx_ioc_enclave_add_page(struct sgx_encl *encl, void __user *arg)
 	    !IS_ALIGNED(addp.src, PAGE_SIZE))
 		return -EINVAL;
 
-	if (addp.offset >= encl->size)
+	if (!addp.nr_pages)
+		return -EINVAL;
+
+	if (addp.offset + ((addp.nr_pages - 1) * PAGE_SIZE) >= encl->size)
 		return -EINVAL;
 
 	if (copy_from_user(&secinfo, (void __user *)addp.secinfo,
@@ -499,7 +515,27 @@ static long sgx_ioc_enclave_add_page(struct sgx_encl *encl, void __user *arg)
 	if (sgx_validate_secinfo(&secinfo))
 		return -EINVAL;
 
-	return sgx_encl_add_page(encl, &addp, &secinfo);
+	for ( ; addp.nr_pages > 0; addp.nr_pages--) {
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		if (need_resched())
+			cond_resched();
+
+		ret = sgx_encl_add_page(encl, &addp, &secinfo);
+		if (ret)
+			break;
+
+		addp.offset += PAGE_SIZE;
+		addp.src += PAGE_SIZE;
+	}
+
+	if (copy_to_user(arg, &addp, sizeof(addp)))
+		return -EFAULT;
+
+	return ret;
 }
 
 static int __sgx_get_key_hash(struct crypto_shash *tfm, const void *modulus,
@@ -702,8 +738,8 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 	case SGX_IOC_ENCLAVE_CREATE:
 		ret = sgx_ioc_enclave_create(encl, (void __user *)arg);
 		break;
-	case SGX_IOC_ENCLAVE_ADD_PAGE:
-		ret = sgx_ioc_enclave_add_page(encl, (void __user *)arg);
+	case SGX_IOC_ENCLAVE_ADD_PAGES:
+		ret = sgx_ioc_enclave_add_pages(encl, (void __user *)arg);
 		break;
 	case SGX_IOC_ENCLAVE_INIT:
 		ret = sgx_ioc_enclave_init(encl, (void __user *)arg);
-- 
2.22.0


  parent reply	other threads:[~2019-10-09  4:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-09  4:42 [PATCH for_v23 0/7] x86/sgx: Improve add pages ioctl Sean Christopherson
2019-10-09  4:42 ` [PATCH for_v23 1/7] x86/sgx: Modify ADD_PAGE ioctl to take offset instead of full address Sean Christopherson
2019-10-09  4:42 ` [PATCH for_v23 2/7] selftests/x86/sgx: Update test to account for ADD_PAGE change Sean Christopherson
2019-10-09  4:42 ` Sean Christopherson [this message]
2019-10-14 21:32   ` [PATCH for_v23 3/7] x86/sgx: Tweak ADD_PAGE ioctl to allow adding multiple pages Jarkko Sakkinen
2019-10-14 21:35     ` Jarkko Sakkinen
2019-10-14 23:31       ` Sean Christopherson
2019-10-16 10:17         ` Jarkko Sakkinen
2019-10-16 10:19           ` Jarkko Sakkinen
2019-10-16 10:29             ` Jarkko Sakkinen
2019-10-21 11:24               ` Jarkko Sakkinen
2019-10-09  4:42 ` [PATCH for_v23 4/7] selftests/x86/sgx: Update enclave build flow to do multi-page add Sean Christopherson
2019-10-09  4:42 ` [PATCH for_v23 5/7] x86/sgx: Add a flag to ADD_PAGES to allow replicating the source page Sean Christopherson
2019-10-09  4:42 ` [PATCH for_v23 6/7] selftests/x86/sgx: Update selftest to account for ADD_PAGES flag Sean Christopherson
2019-10-09  4:42 ` [PATCH for_v23 7/7] selftests/x86/sgx: Add test coverage for reclaim and replicate Sean Christopherson
2019-10-10  3:28 ` [PATCH for_v23 0/7] x86/sgx: Improve add pages ioctl Haitao Huang
2019-10-11 14:37   ` Sean Christopherson
2019-10-13 15:15     ` Dr. Greg

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=20191009044241.3591-4-sean.j.christopherson@intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=linux-sgx@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).