From patchwork Fri May 26 14:28:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ayoun, Serge" X-Patchwork-Id: 9596011 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 8FF3B60453 for ; Tue, 28 Feb 2017 15:28:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7ED2927BE5 for ; Tue, 28 Feb 2017 15:28:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7358A28524; Tue, 28 Feb 2017 15:28:53 +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.8 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_96_Q, RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM 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 E7DDA2807B for ; Tue, 28 Feb 2017 15:28:52 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 6647E821AD for ; Tue, 28 Feb 2017 07:28:52 -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 CFFE7821AD for ; Tue, 28 Feb 2017 07:28:50 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Feb 2017 07:28:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.35,220,1484035200"; d="scan'208"; a="1116630143" Received: from skl-ubu14-02.iil.intel.com ([143.185.111.42]) by fmsmga001.fm.intel.com with ESMTP; 28 Feb 2017 07:28:46 -0800 From: Serge Ayoun To: intel-sgx-kernel-dev@lists.01.org Date: Fri, 26 May 2017 17:28:58 +0300 Message-Id: <1495808938-10262-1-git-send-email-serge.ayoun@intel.com> X-Mailer: git-send-email 1.9.1 Subject: [intel-sgx-kernel-dev] [PATCH-v2] 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 This commit enables allocation from multiple EPC banks on systems where they are available instead of assuming that there is only one EPC bank. The banks can be enumerated by calling CPUID.0x12.0x2 sub leaf functions up until (eax & 0xf) is zero, which indicates that the sub leaf is invalid and does not describe an EPC bank. Signed-off-by: Serge Ayoun --- drivers/platform/x86/intel_sgx.h | 13 ++++-- drivers/platform/x86/intel_sgx_main.c | 81 +++++++++++++++++++++++------------ drivers/platform/x86/intel_sgx_util.c | 12 +++++- 3 files changed, 73 insertions(+), 33 deletions(-) diff --git a/drivers/platform/x86/intel_sgx.h b/drivers/platform/x86/intel_sgx.h index ed9e8e6..466dc0f 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_epc_banks[]; +extern int sgx_nr_epc_banks; 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..8361f28 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 SGX_MAX_EPC_BANKS 8 +struct sgx_epc_bank sgx_epc_banks[SGX_MAX_EPC_BANKS]; +int sgx_nr_epc_banks; 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,6 +162,7 @@ static unsigned long sgx_get_unmapped_area(struct file *file, static int sgx_init_platform(void) { unsigned int eax, ebx, ecx, edx; + unsigned long size; int i; cpuid(0, &eax, &ebx, &ecx, &edx); @@ -203,19 +202,31 @@ 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); + sgx_nr_epc_banks = 0; + do { + cpuid_count(SGX_CPUID, sgx_nr_epc_banks + 2, + &eax, &ebx, &ecx, &edx); + if (eax & 0xf) { + sgx_epc_banks[sgx_nr_epc_banks].start = + (((u64) (ebx & 0xfffff)) << 32) + + (u64) (eax & 0xfffff000); + size = (((u64) (edx & 0xfffff)) << 32) + + (u64) (ecx & 0xfffff000); + sgx_epc_banks[sgx_nr_epc_banks].end = + sgx_epc_banks[sgx_nr_epc_banks].start + size; + if (!sgx_epc_banks[sgx_nr_epc_banks].start) + return -ENODEV; + sgx_nr_epc_banks++; + } else { + break; + } + } while (sgx_nr_epc_banks < SGX_MAX_EPC_BANKS); - if (!sgx_epc_base) - return -ENODEV; + /* There should be at least one EPC area or something is wrong. */ + if (!sgx_nr_epc_banks) { + WARN_ON(1); + return 1; + } return 0; } @@ -251,6 +262,7 @@ static int sgx_dev_init(struct device *dev) { unsigned int wq_flags; int ret; + int 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_nr_epc_banks); + for (i = 0; i < sgx_nr_epc_banks; i++) { + pr_info("intel_sgx: EPC memory range 0x%lx-0x%lx\n", + sgx_epc_banks[i].start, sgx_epc_banks[i].end); #ifdef CONFIG_X86_64 - sgx_epc_mem = ioremap_cache(sgx_epc_base, sgx_epc_size); - if (!sgx_epc_mem) - return -ENOMEM; + sgx_epc_banks[i].mem = ioremap_cache(sgx_epc_banks[i].start, + sgx_epc_banks[i].end - sgx_epc_banks[i].start); + if (!sgx_epc_banks[i].mem) { + sgx_nr_epc_banks = 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_epc_banks[i].start, + sgx_epc_banks[i].end - sgx_epc_banks[i].start); + if (ret) { + sgx_nr_epc_banks = 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_nr_epc_banks; i++) + iounmap(sgx_epc_banks[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_nr_epc_banks; i++) + iounmap(sgx_epc_banks[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..089530b 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_nr_epc_banks; i++) { + if (entry->pa < sgx_epc_banks[i].end && + entry->pa >= sgx_epc_banks[i].start) { + return sgx_epc_banks[i].mem + + (entry->pa - sgx_epc_banks[i].start); + } + } + + return NULL; #endif }