Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp3133297yba; Mon, 22 Apr 2019 20:55:29 -0700 (PDT) X-Google-Smtp-Source: APXvYqyk0ZpUOevxB0LtF2SuzuAPyH+qCBieqjlxW5TCmToWT5/951BDoRbA0nh+ydFowC0roVzl X-Received: by 2002:a63:c61:: with SMTP id 33mr22989030pgm.293.1555991729786; Mon, 22 Apr 2019 20:55:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555991729; cv=none; d=google.com; s=arc-20160816; b=DOVr4vsegVFOJI9RZBMS/4Tkv8qhn6qlLC14DSmf/S5sojXDe6cV/vFDx1sfBMWfKw 06mIR7ZQaofIh98wspRAA+qCQkt1fGKKWnkZl3aARV24Zv2wqUzY8SROWp55khxFraf5 F72m+HTLdkDsWXaWwt6Qt/4AbJlCuaI8yt7bAqJJYwQ1WS3IVcO9o2Tmo9IYVsqH/nSG fSJ7zhluhEcQXDlQMi8SvpKB1exIyOhoi9yWdu6G5JcbHtRC1g2x0wwZxqi2gjzTjq91 9GVgBiEI9UH0a1GDtlcnDSCtFOcRA6VP73zL9Ggp2owVY6BWS5ItMZFUG0Dtz3bEabOL iV3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from; bh=k4aGr8LCUmRb0Cmt6OJ8VwfrheixZ+Dwg9t5t4dEhgQ=; b=U4D1af4n0yteaDpNY8GoRl+7A62wtjdAMWDfSNhQ72Fi84x7EO0dTuuE63O2Bg8/u3 6KwzuiXxWyEvsSTv3ibwL+Puh9MKLzLTKlCBSFVPVTJMOnh5FWPexXiU9Rnubd/JU8U0 uA0+b0CfCOVOchOnPG8xuSz+sBRbe6G5FTaFsICSheyCAkdHddT8xFjv1/RAuChjIQ2p ZCHmH78Kw1bEnFI+d+U4goSdWP8OdZapQ0fAh+pTeE+iuG2hoUUePtGm4V9ROPtXSa7w sK/qia+V6O1OBgJ7BiDNqQa+0ImJG9MHZCByZqdSwE5Su+LvKiC/m1fG3Baj6ZruA71D 3v9Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r77si4341907pgr.140.2019.04.22.20.55.14; Mon, 22 Apr 2019 20:55:29 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731070AbfDWAhc (ORCPT + 99 others); Mon, 22 Apr 2019 20:37:32 -0400 Received: from mga11.intel.com ([192.55.52.93]:13164 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731026AbfDWAh2 (ORCPT ); Mon, 22 Apr 2019 20:37:28 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Apr 2019 17:37:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,383,1549958400"; d="scan'208";a="225774539" Received: from bxing-ubuntu.jf.intel.com ([10.23.30.27]) by orsmga001.jf.intel.com with ESMTP; 22 Apr 2019 17:37:25 -0700 From: Cedric Xing To: linux-kernel@vger.kernel.org, x86@kernel.org, linux-sgx@vger.kernel.org Cc: akpm@linux-foundation.org, Hansen@vger.kernel.org, Dave , Christopherson@vger.kernel.org, Sean J , nhorman@redhat.com, npmccallum@redhat.com, Ayoun@vger.kernel.org, Serge , Katz-zamir@vger.kernel.org, Shay , Huang@vger.kernel.org, Haitao , andriy.shevchenko@linux.intel.com, tglx@linutronix.de, Svahn@vger.kernel.org, Kai , bp@alien8.de, josh@joshtriplett.org, luto@kernel.org, Kai , rientjes@google.com, Jarkko Sakkinen , Cedric Xing Subject: [RFC PATCH v1 3/3] selftests/x86: Augment SGX selftest to test new __vdso_sgx_enter_enclave() and its callback interface Date: Mon, 22 Apr 2019 17:37:25 -0700 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: <20190417103938.7762-1-jarkko.sakkinen@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Given the changes to __vdso_sgx_enter_enclave(), the selftest is augmented to test the newly added callback interface. This addtional test marks the whole enclave range as PROT_READ, and calls mprotect() upon #PFs to add necessary PTE permissions per PFEC (#PF Error Code) until the enclave finishes. Signed-off-by: Cedric Xing --- tools/testing/selftests/x86/sgx/main.c | 123 ++++++++++++++++++--- tools/testing/selftests/x86/sgx/sgx_call.S | 40 ++++++- 2 files changed, 142 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/x86/sgx/main.c b/tools/testing/selftests/x86/sgx/main.c index e2265f841fb0..234cfbad14a5 100644 --- a/tools/testing/selftests/x86/sgx/main.c +++ b/tools/testing/selftests/x86/sgx/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,10 @@ #include "../../../../../arch/x86/kernel/cpu/sgx/arch.h" #include "../../../../../arch/x86/include/uapi/asm/sgx.h" +#define _Q(x) __Q(x) +#define __Q(x) #x +#define ERRLN "Line " _Q(__LINE__) + static const uint64_t MAGIC = 0x1122334455667788ULL; struct vdso_symtab { @@ -138,7 +143,7 @@ static bool encl_create(int dev_fd, unsigned long bin_size, base = mmap(NULL, secs->size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, dev_fd, 0); if (base == MAP_FAILED) { - perror("mmap"); + perror(ERRLN); return false; } @@ -224,24 +229,113 @@ static bool encl_load(struct sgx_secs *secs, unsigned long bin_size) return false; } -void sgx_call(void *rdi, void *rsi, void *tcs, - struct sgx_enclave_exception *exception, - void *eenter); +int sgx_call(void *rdi, void *rsi, long rdx, void *rcx, void *r8, void *r9, + void *tcs, struct sgx_enclave_exinfo *ei, void *cb, void *eenter); + +static void show_enclave_exinfo(const struct sgx_enclave_exinfo *exinfop, + const char *header) +{ + printf("%s: leaf:%d", header, exinfop->leaf); + if (exinfop->leaf != 4) + printf(" trap#:%d ec:%d addr:0x%llx\n", exinfop->trapnr, + exinfop->error_code, exinfop->address); + else printf("\n"); +} + +static void test1(void *eenter, struct sgx_secs *secs) +{ + uint64_t result = 0; + struct sgx_enclave_exinfo exinfo; + + printf("[1] Entering the enclave without callback.\n"); + + printf("Input: 0x%lx\n Expect: Same as input\n", MAGIC); + sgx_call((void *)&MAGIC, &result, 0, NULL, NULL, NULL, + (void *)secs->base, &exinfo, NULL, eenter); + if (result != MAGIC) { + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); + exit(1); + } + printf(" Output: 0x%lx\n", result); + + printf("Input: Null TCS\n Expect: #PF at EENTER\n"); + sgx_call((void *)&MAGIC, &result, 0, NULL, NULL, NULL, + NULL, &exinfo, NULL, eenter); + show_enclave_exinfo(&exinfo, " Exit"); + if (exinfo.leaf != 2 /*EENTER*/ || exinfo.trapnr != 14 /*#PF*/) + exit(1); +} + +static int enclave_ex_callback(long rdi, long rsi, long rdx, + struct sgx_enclave_exinfo *ei, long r8, long r9, void *tcs, long ursp) +{ + show_enclave_exinfo(ei, " callback"); + + switch (ei->leaf) + { + case 4: + return 0; + case 3: + case 2: + if (ei->trapnr != 14 /*#PF*/ || (ei->error_code & 1) == 0) { + fprintf(stderr, ERRLN ": Unexpected exception\n"); + exit(1); + } + + if (mprotect((void*)(ei->address & -0x1000), 0x1000, + ((ei->error_code & 2) ? PROT_WRITE : 0) | + ((ei->error_code & 0x10) ? PROT_EXEC : 0) | + PROT_READ)) { + perror(ERRLN); + exit(1); + } + + return ei->leaf == 2 ? -EAGAIN : ei->leaf; + } + return -EINVAL; +} + +static void test2(void *eenter, struct sgx_secs *secs) +{ + uint64_t result = 0; + struct sgx_enclave_exinfo exinfo; + + printf("[2] Entering the enclave with callback.\n"); + + printf("Input: 0x%lx\n Expect: Same as input\n", MAGIC); + sgx_call((void *)&MAGIC, &result, 0, NULL, NULL, NULL, + (void *)secs->base, &exinfo, enclave_ex_callback, eenter); + if (result != MAGIC) { + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); + exit(1); + } + printf(" Output: 0x%lx\n", result); + + printf("Input: Read-only enclave (0x%lx-0x%lx)\n" + " Expect: #PFs to be fixed by callback\n", + secs->base, secs->base + (encl_bin_end - encl_bin) - 1); + if (mprotect((void*)secs->base, encl_bin_end - encl_bin, PROT_READ)) { + perror(ERRLN); + exit(1); + } + while (sgx_call((void *)&MAGIC, &result, 0, NULL, NULL, NULL, + (void*)secs->base, &exinfo, enclave_ex_callback, + eenter) == -EAGAIN); + show_enclave_exinfo(&exinfo, " Exit"); + if (exinfo.leaf != 4 /*EEXIT*/) + exit(1); +} int main(int argc, char *argv[], char *envp[]) { unsigned long bin_size = encl_bin_end - encl_bin; unsigned long ss_size = encl_ss_end - encl_ss; - struct sgx_enclave_exception exception; Elf64_Sym *eenter_sym; struct vdso_symtab symtab; struct sgx_secs secs; - uint64_t result = 0; void *eenter; void *addr; - memset(&exception, 0, sizeof(exception)); - addr = vdso_get_base_addr(envp); if (!addr) exit(1); @@ -266,14 +360,7 @@ int main(int argc, char *argv[], char *envp[]) if (!encl_load(&secs, bin_size)) exit(1); - printf("Input: 0x%lx\n", MAGIC); - sgx_call((void *)&MAGIC, &result, (void *)secs.base, &exception, - eenter); - if (result != MAGIC) { - fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); - exit(1); - } - - printf("Output: 0x%lx\n", result); - exit(0); + test1(eenter, &secs); + test2(eenter, &secs); + return 0; } diff --git a/tools/testing/selftests/x86/sgx/sgx_call.S b/tools/testing/selftests/x86/sgx/sgx_call.S index 14bd0a044199..da8f687a60d2 100644 --- a/tools/testing/selftests/x86/sgx/sgx_call.S +++ b/tools/testing/selftests/x86/sgx/sgx_call.S @@ -7,9 +7,43 @@ .global sgx_call sgx_call: + .cfi_startproc + push %r15 + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset %r15, 0 + push %r14 + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset %r14, 0 + push %r13 + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset %r13, 0 + push %r12 + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset %r12, 0 push %rbx - mov $0x02, %rax - mov %rdx, %rbx - call *%r8 + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset %rbx, 0 + push $0 + .cfi_adjust_cfa_offset 8 + push 0x48(%rsp) + .cfi_adjust_cfa_offset 8 + push 0x48(%rsp) + .cfi_adjust_cfa_offset 8 + push 0x48(%rsp) + .cfi_adjust_cfa_offset 8 + mov $2, %eax + call *0x68(%rsp) + add $0x20, %rsp + .cfi_adjust_cfa_offset -0x20 pop %rbx + .cfi_adjust_cfa_offset -8 + pop %r12 + .cfi_adjust_cfa_offset -8 + pop %r13 + .cfi_adjust_cfa_offset -8 + pop %r14 + .cfi_adjust_cfa_offset -8 + pop %r15 + .cfi_adjust_cfa_offset -8 ret + .cfi_endproc -- 2.17.1