From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99AD1C433E0 for ; Tue, 16 Feb 2021 04:56:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3376F64DCF for ; Tue, 16 Feb 2021 04:56:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229811AbhBPE4c convert rfc822-to-8bit (ORCPT ); Mon, 15 Feb 2021 23:56:32 -0500 Received: from mga14.intel.com ([192.55.52.115]:26399 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229617AbhBPE4b (ORCPT ); Mon, 15 Feb 2021 23:56:31 -0500 IronPort-SDR: Maq4h7EdeMC+Y1Id6xiSvl5XmUr/W4yHEfuG3cwUudmd9P6fM3zfZNCPam+rj+A1m7qWb4AJko dYXMJY081Pmw== X-IronPort-AV: E=McAfee;i="6000,8403,9896"; a="182027946" X-IronPort-AV: E=Sophos;i="5.81,182,1610438400"; d="scan'208";a="182027946" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Feb 2021 20:55:50 -0800 IronPort-SDR: O+lSEm6mgqWNk4lQuXOAwBngnMV5wmAi1XyttmDzx5FZEbeUSpZiwtiVXu9mUgrm8HqilbE89g p8SEjTuZH5Hg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,182,1610438400"; d="scan'208";a="417958707" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by fmsmga004.fm.intel.com with ESMTP; 15 Feb 2021 20:55:50 -0800 Received: from orsmsx612.amr.corp.intel.com (10.22.229.25) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Mon, 15 Feb 2021 20:55:50 -0800 Received: from orsmsx602.amr.corp.intel.com (10.22.229.15) by ORSMSX612.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Mon, 15 Feb 2021 20:55:49 -0800 Received: from orsmsx602.amr.corp.intel.com ([10.22.229.15]) by ORSMSX602.amr.corp.intel.com ([10.22.229.15]) with mapi id 15.01.2106.002; Mon, 15 Feb 2021 20:55:49 -0800 From: "Huang, Kai" To: Jarkko Sakkinen CC: "linux-sgx@vger.kernel.org" , "kvm@vger.kernel.org" , "x86@kernel.org" , "seanjc@google.com" , "luto@kernel.org" , "Hansen, Dave" , "Edgecombe, Rick P" , "Huang, Haitao" , "pbonzini@redhat.com" , "bp@alien8.de" , "tglx@linutronix.de" , "mingo@redhat.com" , "hpa@zytor.com" Subject: RE: [RFC PATCH v5 13/26] x86/sgx: Add helpers to expose ECREATE and EINIT to KVM Thread-Topic: [RFC PATCH v5 13/26] x86/sgx: Add helpers to expose ECREATE and EINIT to KVM Thread-Index: AQHXAgqQS1vAJ1WsIEqPe3ZtzCQoJapao/iAgAAARAD//5VNEA== Date: Tue, 16 Feb 2021 04:55:49 +0000 Message-ID: <87b9c4bfe61545c0803f7a46b177e10e@intel.com> References: <4b8921da8e0d037b1e99d5cc92eea8f8470cf2e0.1613221549.git.kai.huang@intel.com> In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.5.1.3 dlp-product: dlpe-windows dlp-reaction: no-action x-originating-ip: [10.1.200.100] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org > > On Tue, Feb 16, 2021 at 05:08:20AM +0200, Jarkko Sakkinen wrote: > > On Sun, Feb 14, 2021 at 02:29:15AM +1300, Kai Huang wrote: > > > From: Sean Christopherson > > > > > > The host kernel must intercept ECREATE to be able to impose policies > > > on guests. When it does this, the host kernel runs ECREATE against > > > the userspace mapping of the virtualized EPC. > > > > > > Provide wrappers around __ecreate() and __einit() to hide the > > > ugliness of overloading the ENCLS return value to encode multiple > > > error formats in a single int. KVM will trap-and-execute ECREATE > > > and EINIT as part of SGX virtualization, and on an exception, KVM > > > needs the trapnr so that it can inject the correct fault into the guest. > > > > > > Signed-off-by: Sean Christopherson > > > Signed-off-by: Kai Huang > > > --- > > > v4->v5: > > > > > > - No code change. > > > > > > v3->v4: > > > > > > - Added one new line before last return in sgx_virt_einit(), per Jarkko. > > > > > > v2->v3: > > > > > > - Added kdoc for sgx_virt_ecreate() and sgx_virt_einit(), per Jarkko. > > > - Changed to use CONFIG_X86_SGX_KVM. > > > > > > --- > > > arch/x86/include/asm/sgx.h | 16 ++++++ > > > arch/x86/kernel/cpu/sgx/virt.c | 94 > > > ++++++++++++++++++++++++++++++++++ > > > 2 files changed, 110 insertions(+) > > > create mode 100644 arch/x86/include/asm/sgx.h > > > > > > diff --git a/arch/x86/include/asm/sgx.h b/arch/x86/include/asm/sgx.h > > > new file mode 100644 index 000000000000..8a3ea3e1efbe > > > --- /dev/null > > > +++ b/arch/x86/include/asm/sgx.h > > > @@ -0,0 +1,16 @@ > > > +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SGX_H > > > +#define _ASM_X86_SGX_H > > > + > > > +#include > > > + > > > +#ifdef CONFIG_X86_SGX_KVM > > > +struct sgx_pageinfo; > > > + > > > +int sgx_virt_ecreate(struct sgx_pageinfo *pageinfo, void __user *secs, > > > + int *trapnr); > > > +int sgx_virt_einit(void __user *sigstruct, void __user *token, > > > + void __user *secs, u64 *lepubkeyhash, int *trapnr); > > > > s/virt/vepc/g No. The two are related to enclave construction (from guest), not EPC. For instance, what does ECREATE mean for virtual EPC? ECREATE is meaningful for enclave. > > > > > +#endif > > > + > > > +#endif /* _ASM_X86_SGX_H */ > > > diff --git a/arch/x86/kernel/cpu/sgx/virt.c > > > b/arch/x86/kernel/cpu/sgx/virt.c index 47542140f8c1..016bad7cff8d > > > 100644 > > > --- a/arch/x86/kernel/cpu/sgx/virt.c > > > +++ b/arch/x86/kernel/cpu/sgx/virt.c > > > > Rename as vepc.c. No. This file contains more than virtual EPC implementation, but also other staff like sgx_virt_ecreate()/sgx_virt_einit(), which are used by KVM to run ECREATE/EINIT on behalf of guest. > > > > > @@ -257,3 +257,97 @@ int __init sgx_vepc_init(void) > > > > > > return misc_register(&sgx_vepc_dev); } > > > + > > > +/** > > > + * sgx_virt_ecreate() - Run ECREATE on behalf of guest > > > + * @pageinfo: Pointer to PAGEINFO structure > > > + * @secs: Userspace pointer to SECS page > > > + * @trapnr: trap number injected to guest in case of ECREATE error > > > + * > > > + * Run ECREATE on behalf of guest after KVM traps ECREATE for the > > > +purpose > > > + * of enforcing policies of guest's enclaves, and return the trap > > > +number > > > + * which should be injected to guest in case of any ECREATE error. > > > + * > > > + * Return: > > > + * - 0: ECREATE was successful. > > > + * - -EFAULT: ECREATE returned error. > > > + */ > > > +int sgx_virt_ecreate(struct sgx_pageinfo *pageinfo, void __user *secs, > > > + int *trapnr) > > > +{ > > > + int ret; > > > + > > > + /* > > > + * @secs is userspace address, and it's not guaranteed @secs points at > > > + * an actual EPC page. It's also possible to generate a kernel mapping > > > + * to physical EPC page by resolving PFN but using __uaccess_xx() is > > > + * simpler. > > > + */ > > > + __uaccess_begin(); > > > + ret = __ecreate(pageinfo, (void *)secs); > > > + __uaccess_end(); > > > + > > > + if (encls_faulted(ret)) { > > > + *trapnr = ENCLS_TRAPNR(ret); > > > + return -EFAULT; > > > + } > > > + > > > + /* ECREATE doesn't return an error code, it faults or succeeds. */ > > > + WARN_ON_ONCE(ret); > > > > Empty line. > > > > > + return 0; > > > +} > > > +EXPORT_SYMBOL_GPL(sgx_virt_ecreate); > > > + > > > +static int __sgx_virt_einit(void __user *sigstruct, void __user *token, > > > + void __user *secs) > > > +{ > > > + int ret; > > > + > > > + __uaccess_begin(); > > > + ret = __einit((void *)sigstruct, (void *)token, (void *)secs); > > > + __uaccess_end(); > > > > Ditto. > > > > > + return ret; > > > +} > > > + > > > +/** > > > + * sgx_virt_einit() - Run EINIT on behalf of guest > > > + * @sigstruct: Userspace pointer to SIGSTRUCT structure > > > + * @token: Userspace pointer to EINITTOKEN structure > > > + * @secs: Userspace pointer to SECS page > > > + * @lepubkeyhash: Pointer to guest's *virtual* SGX_LEPUBKEYHASH MSR > > > + * values > > > + * @trapnr: trap number injected to guest in case of EINIT error > > > + * > > > + * Run EINIT on behalf of guest after KVM traps EINIT. If SGX_LC is > > > +available > > > + * in host, SGX driver may rewrite the hardware values at wish, > > > +therefore KVM > > > + * needs to update hardware values to guest's virtual MSR values in > > > +order to > > > + * ensure EINIT is executed with expected hardware values. > > > + * > > > + * Return: > > > + * - 0: EINIT was successful. > > > + * - -EFAULT: EINIT returned error. > > > + */ > > > +int sgx_virt_einit(void __user *sigstruct, void __user *token, > > > + void __user *secs, u64 *lepubkeyhash, int *trapnr) { > > > + int ret; > > > + > > > + if (!boot_cpu_has(X86_FEATURE_SGX_LC)) { > > > + ret = __sgx_virt_einit(sigstruct, token, secs); > > > + } else { > > > + preempt_disable(); > > > + > > > + sgx_update_lepubkeyhash(lepubkeyhash); > > > + > > > + ret = __sgx_virt_einit(sigstruct, token, secs); > > > + preempt_enable(); > > > + } > > > + > > > + if (encls_faulted(ret)) { > > > + *trapnr = ENCLS_TRAPNR(ret); > > > + return -EFAULT; > > > + } > > > + > > > + return ret; > > > +} > > > +EXPORT_SYMBOL_GPL(sgx_virt_einit); > > Remove exports. Why? KVM needs to use them in later patches.