From patchwork Fri May 26 11:51:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ayoun, Serge" X-Patchwork-Id: 9595393 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 2EEEB601D7 for ; Tue, 28 Feb 2017 12:51:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EE48284F9 for ; Tue, 28 Feb 2017 12:51:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1364B28504; Tue, 28 Feb 2017 12:51:06 +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.3 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_96_Q, RCVD_IN_DNSWL_NONE autolearn=no 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 A3A52284F9 for ; Tue, 28 Feb 2017 12:51:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id E5B2181D77 for ; Tue, 28 Feb 2017 04:51:04 -0800 (PST) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 CC90381D77 for ; Tue, 28 Feb 2017 04:51:02 -0800 (PST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Feb 2017 04:51:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,219,1484035200"; d="scan'208";a="230584344" Received: from skl-ubu14-02.iil.intel.com ([143.185.111.42]) by fmsmga004.fm.intel.com with ESMTP; 28 Feb 2017 04:51:01 -0800 From: Serge Ayoun To: intel-sgx-kernel-dev@lists.01.org Date: Fri, 26 May 2017 14:51:13 +0300 Message-Id: <1495799473-3053-1-git-send-email-serge.ayoun@intel.com> X-Mailer: git-send-email 1.9.1 Subject: [intel-sgx-kernel-dev] [PATCH] intel_isgx: adding multiple EPC support 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: , Cc: jarkko.sakkinen@intel.com 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 For systems with multiple EPC regions cpuidid leaf 18 sub leaf 3, 4,... describes those regions. At driver initialization time, cpuid leaf 18 subleaf 2 and beyond are invoked in order to enumerate those different EPC chunks and until valid bit is not set. Epc pages are inserted to the free list accordingly. Signed-off-by: Serge Ayoun --- drivers/platform/x86/intel_sgx.h | 13 ++++-- drivers/platform/x86/intel_sgx_main.c | 83 +++++++++++++++++++++++------------ drivers/platform/x86/intel_sgx_util.c | 12 ++++- 3 files changed, 74 insertions(+), 34 deletions(-) diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index ed9e8e6..6b0c043 100644 --- a/drivers/platform/x86/intel_sgx.h +++ b/drivers/platform/x86/intel_sgx.h @@ -155,12 +155,17 @@ struct sgx_encl { struct mmu_notifier mmu_notifier; }; -extern struct workqueue_struct *sgx_add_page_wq; -extern unsigned long sgx_epc_base; -extern unsigned long sgx_epc_size; +struct sgx_epc_bank { #ifdef CONFIG_X86_64 -extern void *sgx_epc_mem; + void *mem; #endif + unsigned long start; + unsigned long end; +}; + +extern struct workqueue_struct *sgx_add_page_wq; +extern struct sgx_epc_bank sgx_epcs[]; +extern int sgx_num_epc; extern u64 sgx_encl_size_max_32; extern u64 sgx_encl_size_max_64; extern u64 sgx_xfrm_mask; diff --git a/drivers/platform/x86/intel_sgx_main.c b/drivers/platform/x86/intel_sgx_main.c index 63cca6a..ed136db 100644 --- a/drivers/platform/x86/intel_sgx_main.c +++ b/drivers/platform/x86/intel_sgx_main.c @@ -83,11 +83,9 @@ */ struct workqueue_struct *sgx_add_page_wq; -unsigned long sgx_epc_base; -unsigned long sgx_epc_size; -#ifdef CONFIG_X86_64 -void *sgx_epc_mem; -#endif +#define MAX_EPCS 8 +struct sgx_epc_bank sgx_epcs[MAX_EPCS]; +int sgx_num_epc; u64 sgx_encl_size_max_32 = ENCL_SIZE_MAX_32; u64 sgx_encl_size_max_64 = ENCL_SIZE_MAX_64; u64 sgx_xfrm_mask = 0x3; @@ -164,7 +162,8 @@ static unsigned long sgx_get_unmapped_area(struct file *file, static int sgx_init_platform(void) { unsigned int eax, ebx, ecx, edx; - int i; + unsigned long size; + int i, leaf; cpuid(0, &eax, &ebx, &ecx, &edx); if (eax < SGX_CPUID) { @@ -203,19 +202,32 @@ static int sgx_init_platform(void) sgx_encl_size_max_32 = 1ULL << ((edx >> 8) & 0xFF); } - cpuid_count(SGX_CPUID, 0x2, &eax, &ebx, &ecx, &edx); - - /* The should be at least one EPC area or something is wrong. */ - if ((eax & 0xf) != 0x1) - return -ENODEV; - - sgx_epc_base = (((u64)(ebx & 0xfffff)) << 32) + - (u64)(eax & 0xfffff000); - sgx_epc_size = (((u64)(edx & 0xfffff)) << 32) + - (u64)(ecx & 0xfffff000); + leaf = 2; + sgx_num_epc = 0; + do { + cpuid_count(SGX_CPUID, leaf, &eax, &ebx, &ecx, &edx); + if (eax & 0xf) { + sgx_epcs[sgx_num_epc].start = + (((u64) (ebx & 0xfffff)) << 32) + + (u64) (eax & 0xfffff000); + size = (((u64) (edx & 0xfffff)) << 32) + + (u64) (ecx & 0xfffff000); + sgx_epcs[sgx_num_epc].end = + sgx_epcs[sgx_num_epc].start + size; + if (!sgx_epcs[sgx_num_epc].start) + return -ENODEV; + sgx_num_epc++; + leaf++; + } else { + break; + } + } while (sgx_num_epc < MAX_EPCS); - if (!sgx_epc_base) + /* There should be at least one EPC area or something is wrong. */ + if (!sgx_num_epc) { + WARN(); return -ENODEV; + } return 0; } @@ -250,7 +262,7 @@ static int sgx_pm_resume(struct device *dev) static int sgx_dev_init(struct device *dev) { unsigned int wq_flags; - int ret; + int ret, i; pr_info("intel_sgx: " DRV_DESCRIPTION " v" DRV_VERSION "\n"); @@ -261,18 +273,27 @@ static int sgx_dev_init(struct device *dev) if (ret) return ret; - pr_info("intel_sgx: EPC memory range 0x%lx-0x%lx\n", sgx_epc_base, - sgx_epc_base + sgx_epc_size); + pr_info("intel_sgx: Number of EPCs %d\n", sgx_num_epc); + for (i = 0; i < sgx_num_epc; i++) { + pr_info("intel_sgx: EPC memory range 0x%lx-0x%lx\n", + sgx_epcs[i].start, sgx_epcs[i].end); #ifdef CONFIG_X86_64 - sgx_epc_mem = ioremap_cache(sgx_epc_base, sgx_epc_size); - if (!sgx_epc_mem) - return -ENOMEM; + sgx_epcs[i].mem = ioremap_cache(sgx_epcs[i].start, + sgx_epcs[i].end - sgx_epcs[i].start); + if (!sgx_epcs[i].mem) { + sgx_num_epc = i; + ret = -ENOMEM; + goto out_iounmap; + } #endif - - ret = sgx_page_cache_init(sgx_epc_base, sgx_epc_size); - if (ret) - goto out_iounmap; + ret = sgx_page_cache_init(sgx_epcs[i].start, + sgx_epcs[i].end - sgx_epcs[i].start); + if (ret) { + sgx_num_epc = i+1; + goto out_iounmap; + } + } wq_flags = WQ_UNBOUND | WQ_FREEZABLE; #ifdef WQ_NON_REENETRANT @@ -297,7 +318,8 @@ static int sgx_dev_init(struct device *dev) destroy_workqueue(sgx_add_page_wq); out_iounmap: #ifdef CONFIG_X86_64 - iounmap(sgx_epc_mem); + for (i = 0; i < sgx_num_epc; i++) + iounmap(sgx_epcs[i].mem); #endif return ret; } @@ -352,10 +374,13 @@ static int sgx_drv_probe(struct platform_device *pdev) static int sgx_drv_remove(struct platform_device *pdev) { + int i; + misc_deregister(&sgx_dev); destroy_workqueue(sgx_add_page_wq); #ifdef CONFIG_X86_64 - iounmap(sgx_epc_mem); + for (i = 0; i < sgx_num_epc; i++) + iounmap(sgx_epcs[i].mem); #endif sgx_page_cache_teardown(); diff --git a/drivers/platform/x86/intel_sgx_util.c b/drivers/platform/x86/intel_sgx_util.c index 2c390c5..b921fa7 100644 --- a/drivers/platform/x86/intel_sgx_util.c +++ b/drivers/platform/x86/intel_sgx_util.c @@ -66,7 +66,17 @@ void *sgx_get_epc_page(struct sgx_epc_page *entry) #ifdef CONFIG_X86_32 return kmap_atomic_pfn(PFN_DOWN(entry->pa)); #else - return sgx_epc_mem + (entry->pa - sgx_epc_base); + int i; + + for (i = 0; i < sgx_num_epc; i++) { + if (entry->pa < sgx_epcs[i].end && + entry->pa >= sgx_epcs[i].start) { + return sgx_epcs[i].mem + + (entry->pa - sgx_epcs[i].start); + } + } + + return NULL; #endif }