From patchwork Thu Sep 14 19:54:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 9953809 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 D23E1602C9 for ; Thu, 14 Sep 2017 19:55:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC5FD29262 for ; Thu, 14 Sep 2017 19:55:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D103D29265; Thu, 14 Sep 2017 19:55:19 +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 7CF6629262 for ; Thu, 14 Sep 2017 19:55:19 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 8FD1921CEB0EA; Thu, 14 Sep 2017 12:52:19 -0700 (PDT) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (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 2EFCE20945BE0 for ; Thu, 14 Sep 2017 12:52:18 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP; 14 Sep 2017 12:55:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.42,394,1500966000"; d="scan'208"; a="1218933077" Received: from sjchrist-coffee.jf.intel.com ([10.54.74.137]) by fmsmga002.fm.intel.com with ESMTP; 14 Sep 2017 12:55:16 -0700 From: Sean Christopherson To: intel-sgx-kernel-dev@lists.01.org Date: Thu, 14 Sep 2017 12:54:18 -0700 Message-Id: <20170914195418.16672-1-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.14.1 Subject: [intel-sgx-kernel-dev] [PATCH] intel_sgx: add ENCLS macros for returning exact fault vector 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 When trapping EINIT, KVM needs the vector if EINIT faults in order to inject the correct fault back into the guest. Add "_raw" suffixed ENCLS macros that utilize _ASM_EXTABLE_FAULT to return the raw fault vector to the caller. The fault vector is shifted into bits 31:16 so that the caller can distinguish between faults and SGX error codes. Modify the existing __encls_ret and __encls macros to return -EFAULT if a fault occurs on ENCLS. This provides userspace with an API that is more consistent with other IOCTLs, and obviates the need for the caller to adjust return values, e.g. sgx_ioc_enclave_create no longer needs to manually return -EFAULT on any __ecreate failure. Coincidentally, these changes also fix a bug where __encls_ret did not update EAX after a fault, e.g. __einit would always return '2' if it faulted. Signed-off-by: Sean Christopherson --- arch/x86/include/asm/sgx.h | 44 +++++++++++++++---------------- drivers/platform/x86/intel_sgx/sgx_encl.c | 1 - 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/sgx.h b/arch/x86/include/asm/sgx.h index 541abddab6c7..38a088c28d69 100644 --- a/arch/x86/include/asm/sgx.h +++ b/arch/x86/include/asm/sgx.h @@ -84,24 +84,27 @@ enum sgx_commands { EMODT = 0xF, }; -#define __encls_ret(rax, rbx, rcx, rdx) \ +#define IS_ENCLS_FAULT(r) ((r) & 0xffff0000) +#define ENCLS_FAULT_VECTOR(r) ((r) >> 16) + +#define __encls_ret_raw(rax, rbx, rcx, rdx) \ ({ \ int ret; \ asm volatile( \ "1: .byte 0x0f, 0x01, 0xcf;\n\t" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ - "3: jmp 2b\n" \ + "3: shll $16,%%eax\n" \ + " jmp 2b\n" \ ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ + _ASM_EXTABLE_FAULT(1b, 3b) \ : "=a"(ret) \ : "a"(rax), "b"(rbx), "c"(rcx), "d"(rdx) \ : "memory"); \ ret; \ }) -#ifdef CONFIG_X86_64 -#define __encls(rax, rbx, rcx, rdx...) \ +#define __encls_raw(rax, rbx, rcx, rdx...) \ ({ \ int ret; \ asm volatile( \ @@ -109,36 +112,31 @@ enum sgx_commands { " xor %%eax,%%eax;\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ - "3: movq $-1,%%rax\n" \ + "3: shll $16,%%eax\n" \ " jmp 2b\n" \ ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ + _ASM_EXTABLE_FAULT(1b, 3b) \ : "=a"(ret), "=b"(rbx), "=c"(rcx) \ : "a"(rax), "b"(rbx), "c"(rcx), rdx \ : "memory"); \ ret; \ }) -#else + +#define __encls_ret(rax, rbx, rcx, rdx) \ + ({ \ + int ret = __encls_ret_raw(rax, rbx, rcx, rdx); \ + ret = IS_ENCLS_FAULT(ret) ? -EFAULT : ret; \ + ret; \ + }) + #define __encls(rax, rbx, rcx, rdx...) \ ({ \ - int ret; \ - asm volatile( \ - "1: .byte 0x0f, 0x01, 0xcf;\n\t" \ - " xor %%eax,%%eax;\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: mov $-1,%%eax\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : "=a"(ret), "=b"(rbx), "=c"(rcx) \ - : "a"(rax), "b"(rbx), "c"(rcx), rdx \ - : "memory"); \ + int ret = __encls_raw(rax, rbx, rcx, rdx); \ + ret = IS_ENCLS_FAULT(ret) ? -EFAULT : ret; \ ret; \ }) -#endif -static inline unsigned long __ecreate(struct sgx_pageinfo *pginfo, void *secs) +static inline int __ecreate(struct sgx_pageinfo *pginfo, void *secs) { return __encls(ECREATE, pginfo, secs, "d"(0)); } diff --git a/drivers/platform/x86/intel_sgx/sgx_encl.c b/drivers/platform/x86/intel_sgx/sgx_encl.c index cde732bb6e83..9451369ae43a 100644 --- a/drivers/platform/x86/intel_sgx/sgx_encl.c +++ b/drivers/platform/x86/intel_sgx/sgx_encl.c @@ -524,7 +524,6 @@ int sgx_encl_create(struct sgx_secs *secs) if (ret) { sgx_dbg(encl, "ECREATE returned %ld\n", ret); - ret = -EFAULT; goto out; }