From patchwork Fri Dec 30 16:19:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 9492321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2DB2662AB9 for ; Fri, 30 Dec 2016 16:19:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19E741FF15 for ; Fri, 30 Dec 2016 16:19:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E0B622638; Fri, 30 Dec 2016 16:19:22 +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=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 84A921FF15 for ; Fri, 30 Dec 2016 16:19:21 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 8215B81864 for ; Fri, 30 Dec 2016 08:19:21 -0800 (PST) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 01B2181864 for ; Fri, 30 Dec 2016 08:19:19 -0800 (PST) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP; 30 Dec 2016 08:19:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,432,1477983600"; d="scan'208";a="47862477" Received: from arsehgal-mobl1.ger.corp.intel.com (HELO localhost) ([10.252.6.21]) by orsmga005.jf.intel.com with ESMTP; 30 Dec 2016 08:19:17 -0800 From: Jarkko Sakkinen To: intel-sgx-kernel-dev@lists.01.org Date: Fri, 30 Dec 2016 18:19:04 +0200 Message-Id: <20161230161904.20777-4-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161230161904.20777-1-jarkko.sakkinen@linux.intel.com> References: <20161230161904.20777-1-jarkko.sakkinen@linux.intel.com> Subject: [intel-sgx-kernel-dev] [PATCH 3/3] intel_sgx: backing storage file for PCMD X-BeenThere: intel-sgx-kernel-dev@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Project: Intel® Software Guard Extensions for Linux*: https://01.org/intel-software-guard-extensions" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-sgx-kernel-dev-bounces@lists.01.org Sender: "intel-sgx-kernel-dev" X-Virus-Scanned: ClamAV using ClamSMTP Move PCMD's to a backing storage file in order to give more control to do swapping and discarding. Signed-off-by: Jarkko Sakkinen --- drivers/platform/x86/intel_sgx.h | 5 ++++- drivers/platform/x86/intel_sgx_ioctl.c | 12 ++++++++++ drivers/platform/x86/intel_sgx_page_cache.c | 19 ++++++++++++++-- drivers/platform/x86/intel_sgx_util.c | 30 +++++++++++++++++++++++++ drivers/platform/x86/intel_sgx_vma.c | 34 ++++++++++++++++++++--------- 5 files changed, 87 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index ed9e8e6..1d03606 100644 --- a/drivers/platform/x86/intel_sgx.h +++ b/drivers/platform/x86/intel_sgx.h @@ -115,7 +115,6 @@ struct sgx_encl_page { struct list_head load_list; struct sgx_va_page *va_page; unsigned int va_offset; - struct sgx_pcmd pcmd; }; struct sgx_tgid_ctx { @@ -141,6 +140,7 @@ struct sgx_encl { struct task_struct *owner; struct mm_struct *mm; struct file *backing; + struct file *pcmd; struct list_head load_list; struct kref refcount; unsigned long base; @@ -198,6 +198,9 @@ void sgx_put_epc_page(void *epc_page_vaddr); struct page *sgx_get_backing(struct sgx_encl *encl, struct sgx_encl_page *entry); void sgx_put_backing(struct page *backing, bool write); +struct page *sgx_get_pcmd(struct sgx_encl *encl, + struct sgx_encl_page *entry); +void sgx_put_pcmd(struct page *pcmd_page, bool write); void sgx_insert_pte(struct sgx_encl *encl, struct sgx_encl_page *encl_page, struct sgx_epc_page *epc_page, diff --git a/drivers/platform/x86/intel_sgx_ioctl.c b/drivers/platform/x86/intel_sgx_ioctl.c index 3a4a8fa..dec136a 100644 --- a/drivers/platform/x86/intel_sgx_ioctl.c +++ b/drivers/platform/x86/intel_sgx_ioctl.c @@ -477,6 +477,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, struct vm_area_struct *vma; void *secs_vaddr = NULL; struct file *backing; + struct file *pcmd; long ret; secs = kzalloc(sizeof(*secs), GFP_KERNEL); @@ -501,9 +502,19 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, goto out; } + pcmd = shmem_file_setup("dev/sgx", + ((secs->size >> PAGE_SHIFT) + 1) * 128, + VM_NORESERVE); + if (IS_ERR(pcmd)) { + fput(backing); + ret = PTR_ERR(pcmd); + goto out; + } + encl = kzalloc(sizeof(*encl), GFP_KERNEL); if (!encl) { fput(backing); + fput(pcmd); ret = -ENOMEM; goto out; } @@ -522,6 +533,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd, encl->base = secs->base; encl->size = secs->size; encl->backing = backing; + encl->pcmd = pcmd; secs_epc = sgx_alloc_page(encl->tgid_ctx, 0); if (IS_ERR(secs_epc)) { diff --git a/drivers/platform/x86/intel_sgx_page_cache.c b/drivers/platform/x86/intel_sgx_page_cache.c index d073057..56000fb 100644 --- a/drivers/platform/x86/intel_sgx_page_cache.c +++ b/drivers/platform/x86/intel_sgx_page_cache.c @@ -237,10 +237,14 @@ static int __sgx_ewb(struct sgx_encl *encl, { struct sgx_page_info pginfo; struct page *backing; + struct page *pcmd; + unsigned long pcmd_offset; void *epc; void *va; int ret; + pcmd_offset = ((encl_page->addr >> PAGE_SHIFT) & 31) * 128; + backing = sgx_get_backing(encl, encl_page); if (IS_ERR(backing)) { ret = PTR_ERR(backing); @@ -249,21 +253,32 @@ static int __sgx_ewb(struct sgx_encl *encl, return ret; } + pcmd = sgx_get_pcmd(encl, encl_page); + if (IS_ERR(pcmd)) { + ret = PTR_ERR(pcmd); + sgx_warn(encl, "pinning the pcmd page for EWB failed with %d\n", + ret); + goto out; + } + epc = sgx_get_epc_page(encl_page->epc_page); va = sgx_get_epc_page(encl_page->va_page->epc_page); pginfo.srcpge = (unsigned long)kmap_atomic(backing); - pginfo.pcmd = (unsigned long)&encl_page->pcmd; + pginfo.pcmd = (unsigned long)kmap_atomic(pcmd) + pcmd_offset; pginfo.linaddr = 0; pginfo.secs = 0; ret = __ewb(&pginfo, epc, (void *)((unsigned long)va + encl_page->va_offset)); + kunmap_atomic((void *)(unsigned long)(pginfo.pcmd - pcmd_offset)); kunmap_atomic((void *)(unsigned long)pginfo.srcpge); sgx_put_epc_page(va); sgx_put_epc_page(epc); - sgx_put_backing(backing, true); + sgx_put_pcmd(pcmd, true); +out: + sgx_put_backing(backing, true); return ret; } diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c index 2c390c5..40f5839 100644 --- a/drivers/platform/x86/intel_sgx_util.c +++ b/drivers/platform/x86/intel_sgx_util.c @@ -105,6 +105,33 @@ void sgx_put_backing(struct page *backing_page, bool write) put_page(backing_page); } +struct page *sgx_get_pcmd(struct sgx_encl *encl, + struct sgx_encl_page *entry) +{ + struct page *pcmd; + struct inode *inode; + struct address_space *mapping; + gfp_t gfpmask; + pgoff_t index; + + inode = encl->pcmd->f_path.dentry->d_inode; + mapping = inode->i_mapping; + gfpmask = mapping_gfp_mask(mapping); + /* 32 PCMD's per page */ + index = (entry->addr - encl->base) >> (PAGE_SHIFT + 5); + pcmd = shmem_read_mapping_page_gfp(mapping, index, gfpmask); + + return pcmd; +} + +void sgx_put_pcmd(struct page *pcmd_page, bool write) +{ + if (write) + set_page_dirty(pcmd_page); + + put_page(pcmd_page); +} + struct vm_area_struct *sgx_find_vma(struct sgx_encl *encl, unsigned long addr) { struct vm_area_struct *vma; @@ -245,5 +272,8 @@ void sgx_encl_release(struct kref *ref) if (encl->backing) fput(encl->backing); + if (encl->pcmd) + fput(encl->pcmd); + kfree(encl); } diff --git a/drivers/platform/x86/intel_sgx_vma.c b/drivers/platform/x86/intel_sgx_vma.c index ff72e63..db812ac 100644 --- a/drivers/platform/x86/intel_sgx_vma.c +++ b/drivers/platform/x86/intel_sgx_vma.c @@ -116,12 +116,16 @@ static int sgx_eldu(struct sgx_encl *encl, bool is_secs) { struct page *backing; + struct page *pcmd; + unsigned long pcmd_offset; struct sgx_page_info pginfo; void *secs_ptr = NULL; void *epc_ptr; void *va_ptr; int ret; + pcmd_offset = ((encl_page->addr >> PAGE_SHIFT) & 31) * 128; + backing = sgx_get_backing(encl, encl_page); if (IS_ERR(backing)) { ret = PTR_ERR(backing); @@ -130,36 +134,46 @@ static int sgx_eldu(struct sgx_encl *encl, return ret; } - pginfo.srcpge = (unsigned long)kmap_atomic(backing); + pcmd = sgx_get_pcmd(encl, encl_page); + if (IS_ERR(pcmd)) { + ret = PTR_ERR(pcmd); + sgx_warn(encl, "pinning the pcmd page for EWB failed with %d\n", + ret); + goto out; + } + if (!is_secs) secs_ptr = sgx_get_epc_page(encl->secs_page.epc_page); - pginfo.secs = (unsigned long)secs_ptr; epc_ptr = sgx_get_epc_page(epc_page); va_ptr = sgx_get_epc_page(encl_page->va_page->epc_page); + pginfo.srcpge = (unsigned long)kmap_atomic(backing); + pginfo.pcmd = (unsigned long)kmap_atomic(pcmd) + pcmd_offset; pginfo.linaddr = is_secs ? 0 : encl_page->addr; - pginfo.pcmd = (unsigned long)&encl_page->pcmd; + pginfo.secs = (unsigned long)secs_ptr; ret = __eldu((unsigned long)&pginfo, (unsigned long)epc_ptr, (unsigned long)va_ptr + encl_page->va_offset); + if (ret) { + sgx_err(encl, "ELDU returned %d\n", ret); + ret = -EFAULT; + } + kunmap_atomic((void *)(unsigned long)(pginfo.pcmd - pcmd_offset)); + kunmap_atomic((void *)(unsigned long)pginfo.srcpge); sgx_put_epc_page(va_ptr); sgx_put_epc_page(epc_ptr); if (!is_secs) sgx_put_epc_page(secs_ptr); - sgx_put_backing(backing, 0); - - kunmap_atomic((void *)(unsigned long)pginfo.srcpge); - if (ret) { - sgx_err(encl, "ELDU returned %d\n", ret); - return -EFAULT; - } + sgx_put_pcmd(pcmd, true); +out: + sgx_put_backing(backing, 0); return 0; }