From patchwork Wed Jun 5 19:48:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977717 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BE0306C5 for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B31A12833E for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A78CA28908; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D152C2890F for ; Wed, 5 Jun 2019 19:49:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726532AbfFETt2 (ORCPT ); Wed, 5 Jun 2019 15:49:28 -0400 Received: from mga01.intel.com ([192.55.52.88]:2918 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726512AbfFETt2 (ORCPT ); Wed, 5 Jun 2019 15:49:28 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:27 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 1/7] x86/sgx: Remove dead code to handle non-existent IOR ioctl Date: Wed, 5 Jun 2019 12:48:39 -0700 Message-Id: <20190605194845.926-2-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There are currently no SGX ioctls that require writing data back to userspace. Signed-off-by: Sean Christopherson --- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index a27ec26a9350..cc057d487499 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -839,11 +839,5 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) if (copy_from_user(data, (void __user *)arg, _IOC_SIZE(cmd))) return -EFAULT; - ret = handler(filep, cmd, (unsigned long)((void *)data)); - if (!ret && (cmd & IOC_OUT)) { - if (copy_to_user((void __user *)arg, data, _IOC_SIZE(cmd))) - return -EFAULT; - } - - return ret; + return handler(filep, cmd, (unsigned long)((void *)data)); } From patchwork Wed Jun 5 19:48:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977711 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3599615E6 for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 29ECE28757 for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 280DB28892; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6291B288ED for ; Wed, 5 Jun 2019 19:49:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726535AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 Received: from mga01.intel.com ([192.55.52.88]:2918 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726501AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:28 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 2/7] x86/sgx: Remove unnecessary @cmd parameter from ioctl helpers Date: Wed, 5 Jun 2019 12:48:40 -0700 Message-Id: <20190605194845.926-3-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Each ioctl command is directly and uniquely associated with a handler, i.e. the command is implied by the function itself. Signed-off-by: Sean Christopherson --- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index cc057d487499..a0742d18aa36 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -383,7 +383,6 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs) /** * sgx_ioc_enclave_create - handler for %SGX_IOC_ENCLAVE_CREATE * @filep: open file to /dev/sgx - * @cmd: the command value * @arg: pointer to an &sgx_enclave_create instance * * Allocate kernel data structures for a new enclave and execute ECREATE after @@ -397,8 +396,7 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs) * 0 on success, * -errno otherwise */ -static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, - unsigned long arg) +static long sgx_ioc_enclave_create(struct file *filep, unsigned long arg) { struct sgx_enclave_create *createp = (struct sgx_enclave_create *)arg; struct sgx_encl *encl = filep->private_data; @@ -579,7 +577,6 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, * 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 @@ -593,8 +590,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, * 0 on success, * -errno otherwise */ -static long sgx_ioc_enclave_add_page(struct file *filep, unsigned int cmd, - unsigned long arg) +static long sgx_ioc_enclave_add_page(struct file *filep, unsigned long arg) { struct sgx_enclave_add_page *addp = (void *)arg; struct sgx_encl *encl = filep->private_data; @@ -721,7 +717,6 @@ static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct, * sgx_ioc_enclave_init - handler for %SGX_IOC_ENCLAVE_INIT * * @filep: open file to /dev/sgx - * @cmd: the command value * @arg: pointer to an &sgx_enclave_init instance * * Flush any outstanding enqueued EADD operations and perform EINIT. The @@ -733,8 +728,7 @@ static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct, * SGX error code on EINIT failure, * -errno otherwise */ -static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd, - unsigned long arg) +static long sgx_ioc_enclave_init(struct file *filep, unsigned long arg) { struct sgx_enclave_init *initp = (struct sgx_enclave_init *)arg; struct sgx_encl *encl = filep->private_data; @@ -770,7 +764,6 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd, /** * sgx_ioc_enclave_set_attribute - handler for %SGX_IOC_ENCLAVE_SET_ATTRIBUTE * @filep: open file to /dev/sgx - * @cmd: the command value * @arg: pointer to a struct sgx_enclave_set_attribute instance * * Mark the enclave as being allowed to access a restricted attribute bit. @@ -786,8 +779,7 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd, * * Return: 0 on success, -errno otherwise */ -static long sgx_ioc_enclave_set_attribute(struct file *filep, unsigned int cmd, - unsigned long arg) +static long sgx_ioc_enclave_set_attribute(struct file *filep, unsigned long arg) { struct sgx_enclave_set_attribute *params = (void *)arg; struct sgx_encl *encl = filep->private_data; @@ -810,8 +802,7 @@ static long sgx_ioc_enclave_set_attribute(struct file *filep, unsigned int cmd, return ret; } -typedef long (*sgx_ioc_t)(struct file *filep, unsigned int cmd, - unsigned long arg); +typedef long (*sgx_ioc_t)(struct file *filep, unsigned long arg); long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { @@ -839,5 +830,5 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) if (copy_from_user(data, (void __user *)arg, _IOC_SIZE(cmd))) return -EFAULT; - return handler(filep, cmd, (unsigned long)((void *)data)); + return handler(filep, (unsigned long)((void *)data)); } From patchwork Wed Jun 5 19:48:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977723 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0204C15E6 for ; Wed, 5 Jun 2019 19:49:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9A9B288F7 for ; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DE3042833E; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A2E522890E for ; Wed, 5 Jun 2019 19:49:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726541AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 Received: from mga01.intel.com ([192.55.52.88]:2918 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726512AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:28 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 3/7] x86/sgx: Let ioctl helpers do copy to/from user Date: Wed, 5 Jun 2019 12:48:41 -0700 Message-Id: <20190605194845.926-4-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A future patch will extend SGX_IOC_ENCLAVE_ADD_PAGE to allow userspace to add multiple pages in a single ioctl. Because the number of pages could be quite high, it's possible the ioctl could be interrupted, in which case the driver will need to "return" the number of pages that have been queued, e.g. so that userspace can restart the ioctl in the event that the signal wasn't fatal. In short, SGX_IOC_ENCLAVE_ADD_PAGE will become a conditional _IOWR and will only do copy_to_user() on a non-zero return value. Rather than implement funky logic, pass the raw userspace argument to the helpers so that they may do copy_{to,from}_user() at will. This kills pre-copying the data, but the value added by pre-copy is tenuous, e.g. it consolidates two lines of code but requires use of a fixed size buffer as well as an indirect handler and thus retpoline. And the pre-copy may lead to reader confusion due to @arg being a user pointer in some flows and a kernel pointer in others. Lastly, in the event that a pure _IOR ioctl is added, there won't be a need to update the existing code (to skip copy_from_user()). Signed-off-by: Sean Christopherson --- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 73 ++++++++++++-------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index a0742d18aa36..d17c60dca114 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -383,7 +383,7 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs) /** * sgx_ioc_enclave_create - handler for %SGX_IOC_ENCLAVE_CREATE * @filep: open file to /dev/sgx - * @arg: pointer to an &sgx_enclave_create instance + * @arg: userspace pointer to a struct sgx_enclave_create instance * * Allocate kernel data structures for a new enclave and execute ECREATE after * verifying the correctness of the provided SECS. @@ -396,25 +396,27 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs) * 0 on success, * -errno otherwise */ -static long sgx_ioc_enclave_create(struct file *filep, unsigned long arg) +static long sgx_ioc_enclave_create(struct file *filep, void __user *arg) { - struct sgx_enclave_create *createp = (struct sgx_enclave_create *)arg; struct sgx_encl *encl = filep->private_data; + struct sgx_enclave_create ecreate; struct page *secs_page; struct sgx_secs *secs; int ret; + if (copy_from_user(&ecreate, arg, sizeof(ecreate))) + return -EFAULT; + secs_page = alloc_page(GFP_HIGHUSER); if (!secs_page) return -ENOMEM; secs = kmap(secs_page); - if (copy_from_user(secs, (void __user *)createp->src, sizeof(*secs))) { + if (copy_from_user(secs, (void __user *)ecreate.src, sizeof(*secs))) { ret = -EFAULT; goto out; } - ret = sgx_encl_create(encl, secs); out: @@ -577,7 +579,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, * sgx_ioc_enclave_add_page - handler for %SGX_IOC_ENCLAVE_ADD_PAGE * * @filep: open file to /dev/sgx - * @arg: pointer to an &sgx_enclave_add_page instance + * @arg: userspace pointer to a struct 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 @@ -590,16 +592,19 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, * 0 on success, * -errno otherwise */ -static long sgx_ioc_enclave_add_page(struct file *filep, unsigned long arg) +static long sgx_ioc_enclave_add_page(struct file *filep, void __user *arg) { - struct sgx_enclave_add_page *addp = (void *)arg; struct sgx_encl *encl = filep->private_data; + struct sgx_enclave_add_page addp; struct sgx_secinfo secinfo; struct page *data_page; void *data; int ret; - if (copy_from_user(&secinfo, (void __user *)addp->secinfo, + if (copy_from_user(&addp, arg, sizeof(addp))) + return -EFAULT; + + if (copy_from_user(&secinfo, (void __user *)addp.secinfo, sizeof(secinfo))) return -EFAULT; @@ -609,12 +614,12 @@ static long sgx_ioc_enclave_add_page(struct file *filep, unsigned long arg) data = kmap(data_page); - if (copy_from_user((void *)data, (void __user *)addp->src, PAGE_SIZE)) { + if (copy_from_user((void *)data, (void __user *)addp.src, PAGE_SIZE)) { ret = -EFAULT; goto out; } - ret = sgx_encl_add_page(encl, addp->addr, data, &secinfo, addp->mrmask); + ret = sgx_encl_add_page(encl, addp.addr, data, &secinfo, addp.mrmask); if (ret) goto out; @@ -717,7 +722,7 @@ static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct, * sgx_ioc_enclave_init - handler for %SGX_IOC_ENCLAVE_INIT * * @filep: open file to /dev/sgx - * @arg: pointer to an &sgx_enclave_init instance + * @arg: userspace pointer to a struct sgx_enclave_init instance * * Flush any outstanding enqueued EADD operations and perform EINIT. The * Launch Enclave Public Key Hash MSRs are rewritten as necessary to match @@ -728,15 +733,18 @@ static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct, * SGX error code on EINIT failure, * -errno otherwise */ -static long sgx_ioc_enclave_init(struct file *filep, unsigned long arg) +static long sgx_ioc_enclave_init(struct file *filep, void __user *arg) { - struct sgx_enclave_init *initp = (struct sgx_enclave_init *)arg; struct sgx_encl *encl = filep->private_data; struct sgx_einittoken *einittoken; struct sgx_sigstruct *sigstruct; + struct sgx_enclave_init einit; struct page *initp_page; int ret; + if (copy_from_user(&einit, arg, sizeof(einit))) + return -EFAULT; + initp_page = alloc_page(GFP_HIGHUSER); if (!initp_page) return -ENOMEM; @@ -746,13 +754,12 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned long arg) ((unsigned long)sigstruct + PAGE_SIZE / 2); memset(einittoken, 0, sizeof(*einittoken)); - if (copy_from_user(sigstruct, (void __user *)initp->sigstruct, + if (copy_from_user(sigstruct, (void __user *)einit.sigstruct, sizeof(*sigstruct))) { ret = -EFAULT; goto out; } - ret = sgx_encl_init(encl, sigstruct, einittoken); out: @@ -764,7 +771,7 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned long arg) /** * sgx_ioc_enclave_set_attribute - handler for %SGX_IOC_ENCLAVE_SET_ATTRIBUTE * @filep: open file to /dev/sgx - * @arg: pointer to a struct sgx_enclave_set_attribute instance + * @arg: userspace pointer to a struct sgx_enclave_set_attribute instance * * Mark the enclave as being allowed to access a restricted attribute bit. * The requested attribute is specified via the attribute_fd field in the @@ -779,14 +786,17 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned long arg) * * Return: 0 on success, -errno otherwise */ -static long sgx_ioc_enclave_set_attribute(struct file *filep, unsigned long arg) +static long sgx_ioc_enclave_set_attribute(struct file *filep, void __user *arg) { - struct sgx_enclave_set_attribute *params = (void *)arg; struct sgx_encl *encl = filep->private_data; + struct sgx_enclave_set_attribute params; struct file *attribute_file; int ret; - attribute_file = fget(params->attribute_fd); + if (copy_from_user(¶ms, arg, sizeof(params))) + return -EFAULT; + + attribute_file = fget(params.attribute_fd); if (!attribute_file->f_op) return -EINVAL; @@ -802,33 +812,18 @@ static long sgx_ioc_enclave_set_attribute(struct file *filep, unsigned long arg) return ret; } -typedef long (*sgx_ioc_t)(struct file *filep, unsigned long arg); - long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { - char data[256]; - sgx_ioc_t handler = NULL; - long ret; - switch (cmd) { case SGX_IOC_ENCLAVE_CREATE: - handler = sgx_ioc_enclave_create; - break; + return sgx_ioc_enclave_create(filep, (void __user *)arg); case SGX_IOC_ENCLAVE_ADD_PAGE: - handler = sgx_ioc_enclave_add_page; - break; + return sgx_ioc_enclave_add_page(filep, (void __user *)arg); case SGX_IOC_ENCLAVE_INIT: - handler = sgx_ioc_enclave_init; - break; + return sgx_ioc_enclave_init(filep, (void __user *)arg); case SGX_IOC_ENCLAVE_SET_ATTRIBUTE: - handler = sgx_ioc_enclave_set_attribute; - break; + return sgx_ioc_enclave_set_attribute(filep, (void __user *)arg); default: return -ENOIOCTLCMD; } - - if (copy_from_user(data, (void __user *)arg, _IOC_SIZE(cmd))) - return -EFAULT; - - return handler(filep, (unsigned long)((void *)data)); } From patchwork Wed Jun 5 19:48:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977721 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22F7A427D for ; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 17091288FC for ; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 155822890F; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 589EF28901 for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726512AbfFETta (ORCPT ); Wed, 5 Jun 2019 15:49:30 -0400 Received: from mga01.intel.com ([192.55.52.88]:2919 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726501AbfFETta (ORCPT ); Wed, 5 Jun 2019 15:49:30 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:28 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 4/7] x86/sgx: Allow userspace to add multiple pages in single ioctl() Date: Wed, 5 Jun 2019 12:48:42 -0700 Message-Id: <20190605194845.926-5-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP ...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. On an error, update the userspace struct to reflect progress made, e.g. so that the ioctl can be re-invoked to finish adding pages after a non- fatal error. Signed-off-by: Sean Christopherson --- Documentation/x86/sgx/3.API.rst | 2 +- arch/x86/include/uapi/asm/sgx.h | 21 ++-- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 128 +++++++++++++++++-------- 3 files changed, 98 insertions(+), 53 deletions(-) diff --git a/Documentation/x86/sgx/3.API.rst b/Documentation/x86/sgx/3.API.rst index b113aeb05f54..44550aa41073 100644 --- a/Documentation/x86/sgx/3.API.rst +++ b/Documentation/x86/sgx/3.API.rst @@ -22,6 +22,6 @@ controls the `PROVISON_KEY` attribute. .. kernel-doc:: arch/x86/kernel/cpu/sgx/driver/ioctl.c :functions: sgx_ioc_enclave_create - sgx_ioc_enclave_add_page + sgx_ioc_enclave_add_region sgx_ioc_enclave_init sgx_ioc_enclave_set_attribute diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h index 9ed690a38c70..30d114f6b3bd 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_REGION \ + _IOWR(SGX_MAGIC, 0x01, struct sgx_enclave_add_region) #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_region - parameter structure for the + * %SGX_IOC_ENCLAVE_ADD_REGION ioctl + * @addr: start address within the ELRANGE + * @src: start address for the pages' data + * @size: size of region, in bytes + * @secinfo: address of the SECINFO data (common to the entire region) + * @mrmask: bitmask of 256 byte chunks to measure (applied per 4k page) */ -struct sgx_enclave_add_page { +struct sgx_enclave_add_region { __u64 addr; __u64 src; + __u64 size; __u64 secinfo; __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 d17c60dca114..b69350696b87 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,57 +574,102 @@ 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 - * @arg: userspace pointer to a struct 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, void __user *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_encl *encl = filep->private_data; - struct sgx_enclave_add_page addp; - struct sgx_secinfo secinfo; struct page *data_page; void *data; int ret; - if (copy_from_user(&addp, arg, sizeof(addp))) - return -EFAULT; - - 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_region - handler for %SGX_IOC_ENCLAVE_ADD_REGION + * + * @filep: open file to /dev/sgx + * @arg: userspace pointer to a struct sgx_enclave_add_region 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_region() only indicates the pages have been added to the + * work queue, it does not guarantee adding the pages to the enclave will + * succeed. + * + * On failure, @arg->addr, @arg->src and @arg->size are adjusted to reflect + * the remaining pages that need to be added to the enclave, i.e. userspace + * can re-invoke SGX_IOC_ENCLAVE_ADD_REGION using the same struct. + * + * Return: + * 0 on success, + * -errno otherwise + */ +static long sgx_ioc_enclave_add_region(struct file *filep, void __user *arg) +{ + struct sgx_encl *encl = filep->private_data; + struct sgx_enclave_add_region region; + struct sgx_secinfo secinfo; + unsigned long i; + int ret; + + if (copy_from_user(®ion, arg, sizeof(region))) + return -EFAULT; + + if (!IS_ALIGNED(region.addr, 4096) || !IS_ALIGNED(region.size, 4096)) + return -EINVAL; + + if (!region.size) + return 0; + + if (copy_from_user(&secinfo, (void __user *)region.secinfo, + sizeof(secinfo))) + return -EFAULT; + + ret = 0; + for (i = 0; i < region.size; i += PAGE_SIZE) { + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + if (need_resched()) + cond_resched(); + + ret = sgx_encl_add_page(encl, region.addr + i, region.src + i, + &secinfo, region.mrmask); + if (ret) + break; + } + if (ret && i) { + region.addr += i; + region.src += i; + region.size -= i; + + if (copy_to_user(arg, ®ion, sizeof(region))) + return -EFAULT; + } return ret; } @@ -817,8 +861,8 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) switch (cmd) { case SGX_IOC_ENCLAVE_CREATE: return sgx_ioc_enclave_create(filep, (void __user *)arg); - case SGX_IOC_ENCLAVE_ADD_PAGE: - return sgx_ioc_enclave_add_page(filep, (void __user *)arg); + case SGX_IOC_ENCLAVE_ADD_REGION: + return sgx_ioc_enclave_add_region(filep, (void __user *)arg); case SGX_IOC_ENCLAVE_INIT: return sgx_ioc_enclave_init(filep, (void __user *)arg); case SGX_IOC_ENCLAVE_SET_ATTRIBUTE: From patchwork Wed Jun 5 19:48:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977713 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 758EF3E8C for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 66C9928908 for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5ABE32833E; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D8998288FC for ; Wed, 5 Jun 2019 19:49:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726554AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 Received: from mga01.intel.com ([192.55.52.88]:2918 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726537AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:28 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 5/7] x86/sgx: Add flag to zero added region instead of copying from source Date: Wed, 5 Jun 2019 12:48:43 -0700 Message-Id: <20190605194845.926-6-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For some enclaves, e.g. an enclave with a small code footprint and a large working set, the vast majority of pages added to the enclave are zero pages. Introduce a flag to denote such zero pages. The major benefit of the flag will be realized in a future patch to use Linux's actual zero page as the source, as opposed to explicitly zeroing the enclave's backing memory. Use bit 8 for the SGX_ZERO_REGION flag to avoid an anticipated conflict with passing PROT_{READ,WRITE,EXEC} in bits 2:0, and to leave room in case there is a need for additional protection related bits. Signed-off-by: Sean Christopherson --- arch/x86/include/uapi/asm/sgx.h | 5 +++++ arch/x86/kernel/cpu/sgx/driver/ioctl.c | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h index 30d114f6b3bd..18204722f238 100644 --- a/arch/x86/include/uapi/asm/sgx.h +++ b/arch/x86/include/uapi/asm/sgx.h @@ -31,6 +31,9 @@ struct sgx_enclave_create { __u64 src; }; +/* Zero an added region instead of copying data from a source page. */ +#define SGX_ZERO_REGION 0x100 + /** * struct sgx_enclave_add_region - parameter structure for the * %SGX_IOC_ENCLAVE_ADD_REGION ioctl @@ -38,6 +41,7 @@ struct sgx_enclave_create { * @src: start address for the pages' data * @size: size of region, in bytes * @secinfo: address of the SECINFO data (common to the entire region) + * @flags: miscellaneous flags * @mrmask: bitmask of 256 byte chunks to measure (applied per 4k page) */ struct sgx_enclave_add_region { @@ -45,6 +49,7 @@ struct sgx_enclave_add_region { __u64 src; __u64 size; __u64 secinfo; + __u32 flags; __u16 mrmask; } __attribute__((__packed__)); diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index b69350696b87..c35264ea0c93 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -459,6 +459,9 @@ static int sgx_validate_tcs(struct sgx_encl *encl, struct sgx_tcs *tcs) { int i; + if (!tcs) + return -EINVAL; + if (tcs->flags & SGX_TCS_RESERVED_MASK) return -EINVAL; @@ -510,7 +513,10 @@ static int sgx_encl_queue_page(struct sgx_encl *encl, } backing_ptr = kmap(backing); - memcpy(backing_ptr, data, PAGE_SIZE); + if (data) + memcpy(backing_ptr, data, PAGE_SIZE); + else + memset(backing_ptr, 0, PAGE_SIZE); kunmap(backing); if (page_type == SGX_SECINFO_TCS) encl_page->desc |= SGX_ENCL_PAGE_TCS; @@ -576,12 +582,15 @@ static int __sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, unsigned long src, struct sgx_secinfo *secinfo, - unsigned int mrmask) + unsigned int mrmask, unsigned long flags) { struct page *data_page; void *data; int ret; + if (flags & SGX_ZERO_REGION) + return __sgx_encl_add_page(encl, addr, NULL, secinfo, mrmask); + data_page = alloc_page(GFP_HIGHUSER); if (!data_page) return -ENOMEM; @@ -658,7 +667,7 @@ static long sgx_ioc_enclave_add_region(struct file *filep, void __user *arg) cond_resched(); ret = sgx_encl_add_page(encl, region.addr + i, region.src + i, - &secinfo, region.mrmask); + &secinfo, region.mrmask, region.flags); if (ret) break; } From patchwork Wed Jun 5 19:48:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977715 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 90CAC3A3F for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8550328908 for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 83E6428917; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 198D92891B for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726555AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 Received: from mga01.intel.com ([192.55.52.88]:2918 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726512AbfFETt3 (ORCPT ); Wed, 5 Jun 2019 15:49:29 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:28 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 6/7] x86/sgx: Use the actual zero page as the source when adding zero pages Date: Wed, 5 Jun 2019 12:48:44 -0700 Message-Id: <20190605194845.926-7-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Using the zero page avoids dirtying the backing page, inserting TLB entries, the cost of memset, etc... For some enclaves, e.g. an enclave with a small code footprint and a large working set, this results in a 20%+ reduction in enclave build time. Signed-off-by: Sean Christopherson --- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 50 ++++++++++++++++---------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index c35264ea0c93..e05a539e96fc 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -19,6 +19,7 @@ struct sgx_add_page_req { struct sgx_secinfo secinfo; unsigned long mrmask; struct list_head list; + bool zero_page; }; static int sgx_encl_grow(struct sgx_encl *encl) @@ -76,6 +77,7 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req, struct sgx_pageinfo pginfo; struct page *backing; unsigned long addr; + void *contents; int ret; int i; @@ -84,9 +86,15 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req, addr = SGX_ENCL_PAGE_ADDR(encl_page); - backing = sgx_encl_get_backing_page(encl, page_index); - if (IS_ERR(backing)) - return false; + if (!req->zero_page) { + backing = sgx_encl_get_backing_page(encl, page_index); + if (IS_ERR(backing)) + return false; + contents = kmap_atomic(backing); + } else { + backing = NULL; + contents = __va(page_to_pfn(ZERO_PAGE(0)) << PAGE_SHIFT); + } /* * The SECINFO field must be 64-byte aligned, copy it to a local @@ -99,11 +107,13 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req, pginfo.secs = (unsigned long)sgx_epc_addr(encl->secs.epc_page); pginfo.addr = addr; pginfo.metadata = (unsigned long)&secinfo; - pginfo.contents = (unsigned long)kmap_atomic(backing); + pginfo.contents = (unsigned long)contents; ret = __eadd(&pginfo, sgx_epc_addr(epc_page)); - kunmap_atomic((void *)(unsigned long)pginfo.contents); - put_page(backing); + if (backing) { + kunmap_atomic(contents); + put_page(backing); + } if (ret) { if (encls_failed(ret)) @@ -506,18 +516,20 @@ static int sgx_encl_queue_page(struct sgx_encl *encl, if (!req) return -ENOMEM; - backing = sgx_encl_get_backing_page(encl, page_index); - if (IS_ERR(backing)) { - kfree(req); - return PTR_ERR(backing); - } + if (data) { + backing = sgx_encl_get_backing_page(encl, page_index); + if (IS_ERR(backing)) { + kfree(req); + return PTR_ERR(backing); + } - backing_ptr = kmap(backing); - if (data) + backing_ptr = kmap(backing); memcpy(backing_ptr, data, PAGE_SIZE); - else - memset(backing_ptr, 0, PAGE_SIZE); - kunmap(backing); + kunmap(backing); + } else { + backing = NULL; + req->zero_page = true; + } if (page_type == SGX_SECINFO_TCS) encl_page->desc |= SGX_ENCL_PAGE_TCS; memcpy(&req->secinfo, secinfo, sizeof(*secinfo)); @@ -529,8 +541,10 @@ static int sgx_encl_queue_page(struct sgx_encl *encl, list_add_tail(&req->list, &encl->add_page_reqs); if (empty) queue_work(sgx_encl_wq, &encl->work); - set_page_dirty(backing); - put_page(backing); + if (backing) { + set_page_dirty(backing); + put_page(backing); + } return 0; } From patchwork Wed Jun 5 19:48:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 10977719 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0DEEF15E6 for ; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 02D0C28917 for ; Wed, 5 Jun 2019 19:49:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EBA932890F; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CA7F288FC for ; Wed, 5 Jun 2019 19:49:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726501AbfFETta (ORCPT ); Wed, 5 Jun 2019 15:49:30 -0400 Received: from mga01.intel.com ([192.55.52.88]:2918 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726537AbfFETta (ORCPT ); Wed, 5 Jun 2019 15:49:30 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2019 12:49:28 -0700 X-ExtLoop1: 1 Received: from sjchrist-coffee.jf.intel.com ([10.54.74.36]) by orsmga008.jf.intel.com with ESMTP; 05 Jun 2019 12:49:27 -0700 From: Sean Christopherson To: Jarkko Sakkinen Cc: linux-sgx@vger.kernel.org, Dave Hansen , Cedric Xing , Andy Lutomirski , Jethro Beekman , "Dr . Greg Wettstein" Subject: [PATCH 7/7] x86/sgx: Add a reserved field to sgx_enclave_add_region to drop 'packed' Date: Wed, 5 Jun 2019 12:48:45 -0700 Message-Id: <20190605194845.926-8-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190605194845.926-1-sean.j.christopherson@intel.com> References: <20190605194845.926-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 Sender: linux-sgx-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A reserved field could prove useful in the future, and packed structs can result in inefficiencies due to its impact on alignment. Signed-off-by: Sean Christopherson --- arch/x86/include/uapi/asm/sgx.h | 4 +++- arch/x86/kernel/cpu/sgx/driver/ioctl.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h index 18204722f238..e2d9b3d512ef 100644 --- a/arch/x86/include/uapi/asm/sgx.h +++ b/arch/x86/include/uapi/asm/sgx.h @@ -43,6 +43,7 @@ struct sgx_enclave_create { * @secinfo: address of the SECINFO data (common to the entire region) * @flags: miscellaneous flags * @mrmask: bitmask of 256 byte chunks to measure (applied per 4k page) + * @reserved: reserved for future use, must be zero */ struct sgx_enclave_add_region { __u64 addr; @@ -51,7 +52,8 @@ struct sgx_enclave_add_region { __u64 secinfo; __u32 flags; __u16 mrmask; -} __attribute__((__packed__)); + __u16 reserved; +}; /** * struct sgx_enclave_init - parameter structure for the diff --git a/arch/x86/kernel/cpu/sgx/driver/ioctl.c b/arch/x86/kernel/cpu/sgx/driver/ioctl.c index e05a539e96fc..bae5f3155376 100644 --- a/arch/x86/kernel/cpu/sgx/driver/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/driver/ioctl.c @@ -663,6 +663,9 @@ static long sgx_ioc_enclave_add_region(struct file *filep, void __user *arg) if (!IS_ALIGNED(region.addr, 4096) || !IS_ALIGNED(region.size, 4096)) return -EINVAL; + if (region.reserved) + return -EINVAL; + if (!region.size) return 0;