From patchwork Wed Jun 14 17:37:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 9787109 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 7C4666038E for ; Wed, 14 Jun 2017 17:38:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 635DD26E3A for ; Wed, 14 Jun 2017 17:38:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 589D3268AE; Wed, 14 Jun 2017 17:38:03 +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 5586A26861 for ; Wed, 14 Jun 2017 17:38:01 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0F08921A16E4A; Wed, 14 Jun 2017 10:36:45 -0700 (PDT) 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 AA5E821A16EC1 for ; Wed, 14 Jun 2017 10:36:43 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Jun 2017 10:37:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,341,1493708400"; d="scan'208";a="113210015" Received: from sjchrist-ts.jf.intel.com ([10.54.74.20]) by orsmga005.jf.intel.com with ESMTP; 14 Jun 2017 10:37:45 -0700 From: Sean Christopherson To: intel-sgx-kernel-dev@lists.01.org Date: Wed, 14 Jun 2017 10:37:27 -0700 Message-Id: <1497461858-20309-2-git-send-email-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497461858-20309-1-git-send-email-sean.j.christopherson@intel.com> References: <1497461858-20309-1-git-send-email-sean.j.christopherson@intel.com> Subject: [intel-sgx-kernel-dev] [RFC][PATCH 01/12] intel_sgx: reuse sgx_epc_page list for loaded pages X-BeenThere: intel-sgx-kernel-dev@lists.01.org X-Mailman-Version: 2.1.22 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 Use struct sgx_epc_page's list_head member to track an EPC page in both its "free" and "loaded" states. Add a back-pointer to the EPC page to associate a loaded EPC page with its enclave. Signed-off-by: Sean Christopherson Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen --- arch/x86/include/asm/sgx.h | 3 +- drivers/platform/x86/intel_sgx/sgx.h | 1 - drivers/platform/x86/intel_sgx/sgx_ioctl.c | 3 +- drivers/platform/x86/intel_sgx/sgx_page_cache.c | 53 ++++++++++++------------- drivers/platform/x86/intel_sgx/sgx_util.c | 9 +++-- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/arch/x86/include/asm/sgx.h b/arch/x86/include/asm/sgx.h index 31bce3f..e1f27fd 100644 --- a/arch/x86/include/asm/sgx.h +++ b/arch/x86/include/asm/sgx.h @@ -343,7 +343,8 @@ struct sgx_encl; struct sgx_epc_page { resource_size_t pa; - struct list_head free_list; + struct list_head list; + struct sgx_encl_page *encl_page; }; enum sgx_alloc_flags { diff --git a/drivers/platform/x86/intel_sgx/sgx.h b/drivers/platform/x86/intel_sgx/sgx.h index d5cdf96..78d048e 100644 --- a/drivers/platform/x86/intel_sgx/sgx.h +++ b/drivers/platform/x86/intel_sgx/sgx.h @@ -107,7 +107,6 @@ struct sgx_encl_page { unsigned long addr; unsigned int flags; struct sgx_epc_page *epc_page; - struct list_head load_list; struct sgx_va_page *va_page; unsigned int va_offset; }; diff --git a/drivers/platform/x86/intel_sgx/sgx_ioctl.c b/drivers/platform/x86/intel_sgx/sgx_ioctl.c index 70d7417..0741e6c 100644 --- a/drivers/platform/x86/intel_sgx/sgx_ioctl.c +++ b/drivers/platform/x86/intel_sgx/sgx_ioctl.c @@ -267,9 +267,10 @@ static bool sgx_process_add_page_req(struct sgx_add_page_req *req) goto out; } + epc_page->encl_page = encl_page; encl_page->epc_page = epc_page; sgx_test_and_clear_young(encl_page, encl); - list_add_tail(&encl_page->load_list, &encl->load_list); + list_add_tail(&epc_page->list, &encl->load_list); mutex_unlock(&encl->lock); up_read(&encl->mm->mmap_sem); diff --git a/drivers/platform/x86/intel_sgx/sgx_page_cache.c b/drivers/platform/x86/intel_sgx/sgx_page_cache.c index 8e01427..0829ee0 100644 --- a/drivers/platform/x86/intel_sgx/sgx_page_cache.c +++ b/drivers/platform/x86/intel_sgx/sgx_page_cache.c @@ -193,7 +193,7 @@ static void sgx_isolate_pages(struct sgx_encl *encl, struct list_head *dst, unsigned long nr_to_scan) { - struct sgx_encl_page *entry; + struct sgx_epc_page *entry; int i; mutex_lock(&encl->lock); @@ -206,15 +206,15 @@ static void sgx_isolate_pages(struct sgx_encl *encl, break; entry = list_first_entry(&encl->load_list, - struct sgx_encl_page, - load_list); + struct sgx_epc_page, + list); - if (!sgx_test_and_clear_young(entry, encl) && - !(entry->flags & SGX_ENCL_PAGE_RESERVED)) { - entry->flags |= SGX_ENCL_PAGE_RESERVED; - list_move_tail(&entry->load_list, dst); + if (!sgx_test_and_clear_young(entry->encl_page, encl) && + !(entry->encl_page->flags & SGX_ENCL_PAGE_RESERVED)) { + entry->encl_page->flags |= SGX_ENCL_PAGE_RESERVED; + list_move_tail(&entry->list, dst); } else { - list_move_tail(&entry->load_list, &encl->load_list); + list_move_tail(&entry->list, &encl->load_list); } } out: @@ -304,25 +304,25 @@ static void sgx_evict_page(struct sgx_encl_page *entry, static void sgx_write_pages(struct sgx_encl *encl, struct list_head *src) { - struct sgx_encl_page *entry; - struct sgx_encl_page *tmp; + struct sgx_epc_page *entry; + struct sgx_epc_page *tmp; struct vm_area_struct *vma; if (list_empty(src)) return; - entry = list_first_entry(src, struct sgx_encl_page, load_list); + entry = list_first_entry(src, struct sgx_epc_page, list); mutex_lock(&encl->lock); /* EBLOCK */ - list_for_each_entry_safe(entry, tmp, src, load_list) { - vma = sgx_find_vma(encl, entry->addr); + list_for_each_entry_safe(entry, tmp, src, list) { + vma = sgx_find_vma(encl, entry->encl_page->addr); if (vma) { - zap_vma_ptes(vma, entry->addr, PAGE_SIZE); + zap_vma_ptes(vma, entry->encl_page->addr, PAGE_SIZE); } - sgx_eblock(encl, entry->epc_page); + sgx_eblock(encl, entry); } /* ETRACK */ @@ -330,10 +330,9 @@ static void sgx_write_pages(struct sgx_encl *encl, struct list_head *src) /* EWB */ while (!list_empty(src)) { - entry = list_first_entry(src, struct sgx_encl_page, - load_list); - list_del(&entry->load_list); - sgx_evict_page(entry, encl); + entry = list_first_entry(src, struct sgx_epc_page, list); + list_del(&entry->list); + sgx_evict_page(entry->encl_page, encl); encl->secs_child_cnt--; } @@ -397,7 +396,7 @@ int sgx_add_epc_bank(resource_size_t start, unsigned long size) new_epc_page->pa = start + i; spin_lock(&sgx_free_list_lock); - list_add_tail(&new_epc_page->free_list, &sgx_free_list); + list_add_tail(&new_epc_page->list, &sgx_free_list); sgx_nr_total_epc_pages++; sgx_nr_free_pages++; spin_unlock(&sgx_free_list_lock); @@ -407,8 +406,8 @@ int sgx_add_epc_bank(resource_size_t start, unsigned long size) err_freelist: list_for_each_safe(parser, temp, &sgx_free_list) { spin_lock(&sgx_free_list_lock); - entry = list_entry(parser, struct sgx_epc_page, free_list); - list_del(&entry->free_list); + entry = list_entry(parser, struct sgx_epc_page, list); + list_del(&entry->list); spin_unlock(&sgx_free_list_lock); kfree(entry); } @@ -432,8 +431,8 @@ void sgx_page_cache_teardown(void) spin_lock(&sgx_free_list_lock); list_for_each_safe(parser, temp, &sgx_free_list) { - entry = list_entry(parser, struct sgx_epc_page, free_list); - list_del(&entry->free_list); + entry = list_entry(parser, struct sgx_epc_page, list); + list_del(&entry->list); kfree(entry); } spin_unlock(&sgx_free_list_lock); @@ -447,8 +446,8 @@ static struct sgx_epc_page *sgx_alloc_page_fast(void) if (!list_empty(&sgx_free_list)) { entry = list_first_entry(&sgx_free_list, struct sgx_epc_page, - free_list); - list_del(&entry->free_list); + list); + list_del(&entry->list); sgx_nr_free_pages--; } @@ -533,7 +532,7 @@ int sgx_free_page(struct sgx_epc_page *entry, struct sgx_encl *encl) } spin_lock(&sgx_free_list_lock); - list_add(&entry->free_list, &sgx_free_list); + list_add(&entry->list, &sgx_free_list); sgx_nr_free_pages++; spin_unlock(&sgx_free_list_lock); diff --git a/drivers/platform/x86/intel_sgx/sgx_util.c b/drivers/platform/x86/intel_sgx/sgx_util.c index a8a954a..021e789 100644 --- a/drivers/platform/x86/intel_sgx/sgx_util.c +++ b/drivers/platform/x86/intel_sgx/sgx_util.c @@ -110,9 +110,11 @@ struct vm_area_struct *sgx_find_vma(struct sgx_encl *encl, unsigned long addr) void sgx_zap_tcs_ptes(struct sgx_encl *encl, struct vm_area_struct *vma) { + struct sgx_epc_page *tmp; struct sgx_encl_page *entry; - list_for_each_entry(entry, &encl->load_list, load_list) { + list_for_each_entry(tmp, &encl->load_list, list) { + entry = tmp->encl_page; if ((entry->flags & SGX_ENCL_PAGE_TCS) && entry->addr >= vma->vm_start && entry->addr < vma->vm_end) @@ -335,6 +337,7 @@ static struct sgx_encl_page *sgx_do_fault(struct vm_area_struct *vma, */ encl->secs_child_cnt++; + epc_page->encl_page = entry; entry->epc_page = epc_page; if (reserve) @@ -342,7 +345,7 @@ static struct sgx_encl_page *sgx_do_fault(struct vm_area_struct *vma, /* Do not free */ epc_page = NULL; - list_add_tail(&entry->load_list, &encl->load_list); + list_add_tail(&entry->epc_page->list, &encl->load_list); rc = vm_insert_pfn(vma, entry->addr, PFN_DOWN(entry->epc_page->pa)); if (rc) { @@ -399,7 +402,7 @@ void sgx_encl_release(struct kref *ref) radix_tree_for_each_slot(slot, &encl->page_tree, &iter, 0) { entry = *slot; if (entry->epc_page) { - list_del(&entry->load_list); + list_del(&entry->epc_page->list); sgx_free_page(entry->epc_page, encl); } radix_tree_delete(&encl->page_tree, entry->addr >> PAGE_SHIFT);