From patchwork Mon Oct 4 20:49:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zixuan Wang X-Patchwork-Id: 12534815 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5E24C433EF for ; Mon, 4 Oct 2021 20:49:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A081261357 for ; Mon, 4 Oct 2021 20:49:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236912AbhJDUvm (ORCPT ); Mon, 4 Oct 2021 16:51:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236830AbhJDUvk (ORCPT ); Mon, 4 Oct 2021 16:51:40 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07AC5C061753 for ; Mon, 4 Oct 2021 13:49:51 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id on6so1590269pjb.5 for ; Mon, 04 Oct 2021 13:49:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=q/9RWqqT6mvxnBHido+m9H97/Yh27gw6y1a2mB+sxQ4=; b=QEOaElUWguXWk03z5E2sYH8GZtAdeYj2kdTUvkSWZdLAP+KELrOVT1EX96pSeRcHOa Z7VvJF/2bcq/K0Md+haBjsg16jo5b+NEJgwJ0KFsB9fFLnML5AhGG2n1uMblvEtBQq5f S50x2xl6Z7+u9ksU+jydvEuejPhR72YncTxL8cFdCBMAzS7n8gSA7iyUI/aEhtacuSRS sr4StvI20IB31pJ2ukZBZsCu5MNQnrT26yxNySSC6lrwa9Gdk/xq1T8qZEepoMBbr9Yk TmIC2r+ku/icRQzD7Nob/L/nyHm9Cyc47Sj42iut28qaW1auYmEMkbX5XqThzW/5frKS ZEgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=q/9RWqqT6mvxnBHido+m9H97/Yh27gw6y1a2mB+sxQ4=; b=HDJgXVegfLg5zbPFHjaMNa345cdLYNjBII0RcdARALfwJlAD6y+mjMjuJ+s20aY8nO 1PdDwNLeY7rrWbYNfl3OIpoc1HR2G/lN/Uax9XZotk/IaG5uDEoRd8wIPUhwAjEJ0MCg yD9YCDg+5vrXziB8XfRATjSa1NVcynT4g3pcJdCKrNZPNkZtS7HrZcFD9H6TdQwdMv3F LWHdRA5Ig5trUBK/MDJ6Wy0bYF9cAd9gPcuJ+j7XNXxsJ9HJwgs/yogdYfKV9qKSyskS zHh5NI2Uc2kTSNt34rw9o9AxQ6YEIgEorkMGmRV6buP0AuqTlfKYJpG9RYjGWd4zpTRp oO4w== X-Gm-Message-State: AOAM531Npiv82mOzb230HOhXGr4MML0WgX8G8Llp9ycpR/kE/c3EJRk3 0t9UoiUCacccpnsdOmwSSKQnIyN3pnTLLw== X-Google-Smtp-Source: ABdhPJydoi2W5det4uQPuy7wOncFSAWlcE6xBllEMS/nHNyceSO13OwWozBqU5imjGF314qfXmQKwg== X-Received: by 2002:a17:90a:d58b:: with SMTP id v11mr32358188pju.207.1633380590146; Mon, 04 Oct 2021 13:49:50 -0700 (PDT) Received: from localhost.localdomain (netadmin.ucsd.edu. [137.110.160.224]) by smtp.gmail.com with ESMTPSA id o12sm13635063pjm.57.2021.10.04.13.49.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 13:49:49 -0700 (PDT) From: Zixuan Wang To: kvm@vger.kernel.org, pbonzini@redhat.com, drjones@redhat.com Cc: marcorr@google.com, baekhw@google.com, tmroeder@google.com, erdemaktas@google.com, rientjes@google.com, seanjc@google.com, brijesh.singh@amd.com, Thomas.Lendacky@amd.com, varad.gautam@suse.com, jroedel@suse.de, bp@suse.de Subject: [kvm-unit-tests PATCH v3 11/17] x86 UEFI: Convert x86 test cases to PIC Date: Mon, 4 Oct 2021 13:49:25 -0700 Message-Id: <20211004204931.1537823-12-zxwang42@gmail.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211004204931.1537823-1-zxwang42@gmail.com> References: <20211004204931.1537823-1-zxwang42@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Zixuan Wang UEFI loads EFI applications to dynamic runtime addresses, so it requires all applications to be compiled as PIC (position independent code). PIC does not allow the usage of compile time absolute address. This commit converts multiple x86 test cases to PIC so they can compile and run in UEFI: - x86/cet.efi - x86/emulator.c: x86/emulator.c depends on lib/x86/usermode.c. But usermode.c contains non-PIC inline assembly code. This commit converts lib/x86/usermode.c and x86/emulator.c to PIC, so x86/emulator.c can compile and run in UEFI. - x86/vmware_backdoors.c: it depends on lib/x86/usermode.c and now works without modifications - x86/eventinj.c - x86/smap.c - x86/access.c - x86/umip.c Signed-off-by: Zixuan Wang --- lib/x86/usermode.c | 3 ++- x86/Makefile.common | 10 +++++----- x86/Makefile.x86_64 | 7 ++++--- x86/access.c | 9 +++++---- x86/cet.c | 8 +++++--- x86/emulator.c | 5 +++-- x86/eventinj.c | 6 ++++-- x86/smap.c | 8 ++++---- x86/umip.c | 10 +++++++--- 9 files changed, 39 insertions(+), 27 deletions(-) diff --git a/lib/x86/usermode.c b/lib/x86/usermode.c index f032523..c550545 100644 --- a/lib/x86/usermode.c +++ b/lib/x86/usermode.c @@ -58,7 +58,8 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector, "pushq %[user_stack_top]\n\t" "pushfq\n\t" "pushq %[user_cs]\n\t" - "pushq $user_mode\n\t" + "lea user_mode(%%rip), %%rdx\n\t" + "pushq %%rdx\n\t" "iretq\n" "user_mode:\n\t" diff --git a/x86/Makefile.common b/x86/Makefile.common index 4859bf3..959379c 100644 --- a/x86/Makefile.common +++ b/x86/Makefile.common @@ -81,16 +81,16 @@ tests-common = $(TEST_DIR)/vmexit.$(exe) $(TEST_DIR)/tsc.$(exe) \ $(TEST_DIR)/init.$(exe) \ $(TEST_DIR)/hyperv_synic.$(exe) $(TEST_DIR)/hyperv_stimer.$(exe) \ $(TEST_DIR)/hyperv_connections.$(exe) \ - $(TEST_DIR)/tsx-ctrl.$(exe) + $(TEST_DIR)/tsx-ctrl.$(exe) \ + $(TEST_DIR)/eventinj.$(exe) \ + $(TEST_DIR)/umip.$(exe) # The following test cases are disabled when building EFI tests because they # use absolute addresses in their inline assembly code, which cannot compile # with the '-fPIC' flag ifneq ($(TARGET_EFI),y) -tests-common += $(TEST_DIR)/eventinj.$(exe) \ - $(TEST_DIR)/smap.$(exe) \ - $(TEST_DIR)/realmode.$(exe) \ - $(TEST_DIR)/umip.$(exe) +tests-common += $(TEST_DIR)/smap.$(exe) \ + $(TEST_DIR)/realmode.$(exe) endif test_cases: $(tests-common) $(tests) diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64 index aa23b22..7e8a57a 100644 --- a/x86/Makefile.x86_64 +++ b/x86/Makefile.x86_64 @@ -30,20 +30,21 @@ tests += $(TEST_DIR)/intel-iommu.$(exe) tests += $(TEST_DIR)/rdpru.$(exe) tests += $(TEST_DIR)/pks.$(exe) tests += $(TEST_DIR)/pmu_lbr.$(exe) +tests += $(TEST_DIR)/emulator.$(exe) +tests += $(TEST_DIR)/vmware_backdoors.$(exe) # The following test cases are disabled when building EFI tests because they # use absolute addresses in their inline assembly code, which cannot compile # with the '-fPIC' flag ifneq ($(TARGET_EFI),y) tests += $(TEST_DIR)/access.$(exe) -tests += $(TEST_DIR)/emulator.$(exe) tests += $(TEST_DIR)/svm.$(exe) tests += $(TEST_DIR)/vmx.$(exe) -tests += $(TEST_DIR)/vmware_backdoors.$(exe) +endif + ifneq ($(fcf_protection_full),) tests += $(TEST_DIR)/cet.$(exe) endif -endif include $(SRCDIR)/$(TEST_DIR)/Makefile.common diff --git a/x86/access.c b/x86/access.c index 4725bbd..8d620a7 100644 --- a/x86/access.c +++ b/x86/access.c @@ -700,7 +700,7 @@ static int ac_test_do_access(ac_test_t *at) if (F(AC_ACCESS_TWICE)) { asm volatile ( - "mov $fixed2, %%rsi \n\t" + "lea fixed2(%%rip), %%rsi \n\t" "mov (%[addr]), %[reg] \n\t" "fixed2:" : [reg]"=r"(r), [fault]"=a"(fault), "=b"(e) @@ -710,7 +710,7 @@ static int ac_test_do_access(ac_test_t *at) fault = 0; } - asm volatile ("mov $fixed1, %%rsi \n\t" + asm volatile ("lea fixed1(%%rip), %%rsi \n\t" "mov %%rsp, %%rdx \n\t" "cmp $0, %[user] \n\t" "jz do_access \n\t" @@ -719,7 +719,8 @@ static int ac_test_do_access(ac_test_t *at) "pushq %[user_stack_top] \n\t" "pushfq \n\t" "pushq %[user_cs] \n\t" - "pushq $do_access \n\t" + "lea do_access(%%rip), %%r8\n\t" + "pushq %%r8\n\t" "iretq \n" "do_access: \n\t" "cmp $0, %[fetch] \n\t" @@ -744,7 +745,7 @@ static int ac_test_do_access(ac_test_t *at) [user_cs]"i"(USER_CS), [user_stack_top]"r"(user_stack + sizeof user_stack), [kernel_entry_vector]"i"(0x20) - : "rsi"); + : "rsi", "r8"); asm volatile (".section .text.pf \n\t" "page_fault: \n\t" diff --git a/x86/cet.c b/x86/cet.c index a21577a..a4b79cb 100644 --- a/x86/cet.c +++ b/x86/cet.c @@ -52,7 +52,7 @@ static u64 cet_ibt_func(void) printf("No endbr64 instruction at jmp target, this triggers #CP...\n"); asm volatile ("movq $2, %rcx\n" "dec %rcx\n" - "leaq 2f, %rax\n" + "leaq 2f(%rip), %rax\n" "jmp *%rax \n" "2:\n" "dec %rcx\n"); @@ -67,7 +67,8 @@ void test_func(void) { "pushq %[user_stack_top]\n\t" "pushfq\n\t" "pushq %[user_cs]\n\t" - "pushq $user_mode\n\t" + "lea user_mode(%%rip), %%rax\n\t" + "pushq %%rax\n\t" "iretq\n" "user_mode:\n\t" @@ -77,7 +78,8 @@ void test_func(void) { [user_ds]"i"(USER_DS), [user_cs]"i"(USER_CS), [user_stack_top]"r"(user_stack + - sizeof(user_stack))); + sizeof(user_stack)) + : "rax"); } #define SAVE_REGS() \ diff --git a/x86/emulator.c b/x86/emulator.c index 9fda1a0..4d2de24 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -262,12 +262,13 @@ static void test_pop(void *mem) asm volatile("mov %%rsp, %[tmp] \n\t" "mov %[stack_top], %%rsp \n\t" - "push $1f \n\t" + "lea 1f(%%rip), %%rax \n\t" + "push %%rax \n\t" "ret \n\t" "2: jmp 2b \n\t" "1: mov %[tmp], %%rsp" : [tmp]"=&r"(tmp) : [stack_top]"r"(stack_top) - : "memory"); + : "memory", "rax"); report(1, "ret"); stack_top[-1] = 0x778899; diff --git a/x86/eventinj.c b/x86/eventinj.c index 46593c9..0cd68e8 100644 --- a/x86/eventinj.c +++ b/x86/eventinj.c @@ -155,9 +155,11 @@ asm("do_iret:" "pushf"W" \n\t" "mov %cs, %ecx \n\t" "push"W" %"R "cx \n\t" - "push"W" $2f \n\t" + "lea"W" 2f(%"R "ip), %"R "bx \n\t" + "push"W" %"R "bx \n\t" - "cmpb $0, no_test_device\n\t" // see if need to flush + "mov no_test_device(%"R "ip), %bl \n\t" + "cmpb $0, %bl\n\t" // see if need to flush "jnz 1f\n\t" "outl %eax, $0xe4 \n\t" // flush page "1: \n\t" diff --git a/x86/smap.c b/x86/smap.c index ac2c8d5..b3ee16f 100644 --- a/x86/smap.c +++ b/x86/smap.c @@ -161,10 +161,10 @@ int main(int ac, char **av) test = -1; asm("or $(" xstr(USER_BASE) "), %"R "sp \n" "push $44 \n " - "decl test\n" + "decl test(%"R "ip)\n" "and $~(" xstr(USER_BASE) "), %"R "sp \n" "pop %"R "ax\n" - "movl %eax, test"); + "movl %eax, test(%"R "ip)"); report(pf_count == 0 && test == 44, "write to user stack with AC=1"); @@ -173,10 +173,10 @@ int main(int ac, char **av) test = -1; asm("or $(" xstr(USER_BASE) "), %"R "sp \n" "push $45 \n " - "decl test\n" + "decl test(%"R "ip)\n" "and $~(" xstr(USER_BASE) "), %"R "sp \n" "pop %"R "ax\n" - "movl %eax, test"); + "movl %eax, test(%"R "ip)"); report(pf_count == 1 && test == 45 && save == -1, "write to user stack with AC=0"); diff --git a/x86/umip.c b/x86/umip.c index c5700b3..8b4e798 100644 --- a/x86/umip.c +++ b/x86/umip.c @@ -23,7 +23,10 @@ static void gp_handler(struct ex_regs *regs) #define GP_ASM(stmt, in, clobber) \ asm volatile ( \ - "mov" W " $1f, %[expected_rip]\n\t" \ + "push" W " %%" R "ax\n\t" \ + "lea 1f(%%" R "ip), %%" R "ax\n\t" \ + "mov %%" R "ax, %[expected_rip]\n\t" \ + "pop" W " %%" R "ax\n\t" \ "movl $2f-1f, %[skip_count]\n\t" \ "1: " stmt "\n\t" \ "2: " \ @@ -130,7 +133,8 @@ static int do_ring3(void (*fn)(const char *), const char *arg) "push" W " %%" R "dx \n\t" "pushf" W "\n\t" "push" W " %[user_cs] \n\t" - "push" W " $1f \n\t" + "lea 1f(%%" R "ip), %%" R "dx \n\t" + "push" W " %%" R "dx \n\t" "iret" W "\n" "1: \n\t" "push %%" R "cx\n\t" /* save kernel SP */ @@ -144,7 +148,7 @@ static int do_ring3(void (*fn)(const char *), const char *arg) #endif "pop %%" R "cx\n\t" - "mov $1f, %%" R "dx\n\t" + "lea 1f(%%" R "ip), %%" R "dx\n\t" "int %[kernel_entry_vector]\n\t" ".section .text.entry \n\t" "kernel_entry: \n\t"