From patchwork Fri Sep 30 23:24:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12996080 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49FB1C433FE for ; Fri, 30 Sep 2022 23:25:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232343AbiI3XZs (ORCPT ); Fri, 30 Sep 2022 19:25:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232630AbiI3XZU (ORCPT ); Fri, 30 Sep 2022 19:25:20 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CBB9A7AA8 for ; Fri, 30 Sep 2022 16:25:04 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id pf10-20020a17090b1d8a00b002037c2aad2bso6522894pjb.0 for ; Fri, 30 Sep 2022 16:25:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date; bh=mSnHxxlxtHo6KvIN5t/qvi7UQX4NADLYciTfA4XVgqE=; b=joareyNgmX5+rQs5fq6zLBGVniGVsSPpmbHyYIzOA8YlGnavPrOTEjJMqzVSXfppqU 8za85cH9rOCq/vcl9bFZXxRDJ9GJ+tt98NZSTQqkX6xoXjagd62B8lX8ssKwEKq5IPEY xOVR95AAVAGLrvoJBKzvy/IaHhYIDRxBqNPszy1pAXrlsrRcC8CS6m2j9MtAPaFT4c7z M2OQlUxaiZDUYK3uxIqphSOAqKzeKl+y1+2g4Fb2lu04fCzIdyuddK6gHuoQVraJTVPO L0F7nqpL55qi9dd33EdXES84PVypTIzhh1ffRKLvEAjCZ/m/rOXZSjPJt2ydsn6EmIwr TilQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date; bh=mSnHxxlxtHo6KvIN5t/qvi7UQX4NADLYciTfA4XVgqE=; b=eL/aFLvgzDOU1bkykL48zf+JDMgWAF1BNc6T1+w+wY7q2h+f0Ivj9LeEa2F0jlp1Dg ResxVjlazlKZkhD3yW9Q61qPxWQUB+g060ms32E8KB7l5/iZQgDJ03jH4vYUOu05k2CQ fbjCwTF4fwoXDIzwbE4rtSptUn+CnSJ3NJsFEcxNnEATzOdzankxkPtrT8LKqJdNnrSX xLGifVwBjbw1m1PLmsEur0WSrIgzQPM9rkmUsgZEjZ5ZptcyZsp5nFIURKz7ml/iVai5 gjdsz/nNTFJ91faqBe/1st3Hvh8neuWWVviD0nc5ReavZjuC9NLaZrL9sMibdjb83Dx9 6vlg== X-Gm-Message-State: ACrzQf02l9BZdSz4MDy521K0y6CzvYzpFVaVtlBazHE8KAiiOXwPIeWK KcVobTJLePdQA3U+e4NrAv8NYdcovR4= X-Google-Smtp-Source: AMsMyM6lEVRQflIcEvtVUpLQe1g2hRIuoprTJNhan+3lTIOsMPyfIv56UP+5joYOkfs1cemfqkkTq9ZEeuM= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:90b:3852:b0:202:f891:9ed5 with SMTP id nl18-20020a17090b385200b00202f8919ed5mr644594pjb.239.1664580293676; Fri, 30 Sep 2022 16:24:53 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 30 Sep 2022 23:24:48 +0000 In-Reply-To: <20220930232450.1677811-1-seanjc@google.com> Mime-Version: 1.0 References: <20220930232450.1677811-1-seanjc@google.com> X-Mailer: git-send-email 2.38.0.rc1.362.ged0d419d3c-goog Message-ID: <20220930232450.1677811-2-seanjc@google.com> Subject: [kvm-unit-tests PATCH 1/3] x86: Handle all known exceptions with ASM_TRY() From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Install the ASM_TRY() exception handler for all known exception vectors so that ASM_TRY() can be used for other exceptions, e.g. #PF. ASM_TRY() might not Just Work in all cases, but there's no good reason to limit usage to just #DE, #UD, and #GP. Signed-off-by: Sean Christopherson --- lib/x86/desc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/x86/desc.c b/lib/x86/desc.c index a20be92..b293ae4 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -301,12 +301,12 @@ void setup_idt(void) idt_initialized = true; for (i = 0; i < 32; i++) { - if (idt_handlers[i]) - set_idt_entry(i, idt_handlers[i], 0); + if (!idt_handlers[i]) + continue; + + set_idt_entry(i, idt_handlers[i], 0); + handle_exception(i, check_exception_table); } - handle_exception(0, check_exception_table); - handle_exception(6, check_exception_table); - handle_exception(13, check_exception_table); } void load_idt(void) From patchwork Fri Sep 30 23:24:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12996082 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85B8EC433FE for ; Fri, 30 Sep 2022 23:25:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231779AbiI3XZu (ORCPT ); Fri, 30 Sep 2022 19:25:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232631AbiI3XZV (ORCPT ); Fri, 30 Sep 2022 19:25:21 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D6D1B5155 for ; Fri, 30 Sep 2022 16:25:06 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id e187-20020a6369c4000000b0041c8dfb8447so3630247pgc.23 for ; Fri, 30 Sep 2022 16:25:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date; bh=fDi8wRV5SYMy1Kx1OwJz2AhmwqAhK5Jw4Z8aN6lk0xw=; b=DXOb1tqXD1MXLtiY7E0MQLySkHHMBY7V3Zjvrs5hSrPSVmF815V9ThN0uPA5+/PQOi nCqsohNxn/4CONToKnQQj4u1AaJhaWhhTtONmWozpG09vsgtBZ3ioTKFnXTOISmWEWmp g04hAw+1T+Fih7homeaRtbYC0WnoPUFa6u6GJzzJ9t8BP6PLCvrlbLBwGIYJiXOyp+m2 bJ4CBz928oldwDpP7p6Zor8I26XxcOo6UCa6AQ99oW62UsQloNkj021zVKuye909LMif u0c4JkyduLA0W2Oz6zlwqWF4D5tp9Sz8kQFy7GhQ3r7imth4ptg3JEC41xSDmoQ85UQC x0Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date; bh=fDi8wRV5SYMy1Kx1OwJz2AhmwqAhK5Jw4Z8aN6lk0xw=; b=76fiorOKcMCBno5BmpClYPfA7f6xT7TA8sZDPP3x3DNTJHbfsKXYHibM9q78j1u0/j elR1zHc6zjJgFDDbzsQchWNUnVEDrYYt1z+o3PJpSzMBrm/Qa5FdO14b4R/jg64Rhb4v qWhuQ9Md4pWFZJvi9bePbVdRFlzHENldSrhbX78/IU2QFz8kV053Ju+s+qnXWhw2UFsY Xf81QFHqwwzN5WLuQJrSKHRCwWXikBbbPCkKziTmq6RnQYDXrmER4wiJ1K1y62cd42q8 ZdYy8pkFvyLpDIp9kEqLXTMsv9K78myhycESTr5H3PqZYCywmYrEua53ipGmEiooO4+x vIpg== X-Gm-Message-State: ACrzQf2Gvr3QUCUiTO6vMrAZIK9UI+2EWtXid8BZt5Rx/LBSTuA7cqyJ xQCHTLKLYOumpM/ayXYUDEaqEt8PJiA= X-Google-Smtp-Source: AMsMyM5UM5FlGsfK/ElTxcIVbDjEzTKejYM5HR0E3cnlamT80xwO7FYN41le1luPq6dziW2d1Gq4XNjihOM= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a63:5fc4:0:b0:43d:c6cc:ef59 with SMTP id t187-20020a635fc4000000b0043dc6ccef59mr9369015pgb.585.1664580295217; Fri, 30 Sep 2022 16:24:55 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 30 Sep 2022 23:24:49 +0000 In-Reply-To: <20220930232450.1677811-1-seanjc@google.com> Mime-Version: 1.0 References: <20220930232450.1677811-1-seanjc@google.com> X-Mailer: git-send-email 2.38.0.rc1.362.ged0d419d3c-goog Message-ID: <20220930232450.1677811-3-seanjc@google.com> Subject: [kvm-unit-tests PATCH 2/3] nVMX: Use ASM_TRY() for VMREAD and VMWRITE page fault tests From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Use ASM_TRY() in the VMREAD and VMWRITE page fault tests to fix a bug where gcc-12 completely optimizes out handler_called. Because the flag isn't tagged volatile and the compiler is unaware that an exception may occur, gcc-12 thinks the value can only ever be 0. Note, exception fixup effectively performs an exact RIP check, and using LAHF to save RFLAGS drops the fixed RFLAGS bit. Opportunistically drop the 'noinline' as removing the global label makes the functions safe to inline/duplicate. Signed-off-by: Sean Christopherson --- x86/vmx.c | 135 ++++++++++++++++++++---------------------------------- 1 file changed, 49 insertions(+), 86 deletions(-) diff --git a/x86/vmx.c b/x86/vmx.c index a13f2c9..0ae134d 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -387,25 +387,7 @@ static void test_vmwrite_vmread(void) free_page(vmcs); } -ulong finish_fault; -u8 sentinel; -bool handler_called; - -static void pf_handler(struct ex_regs *regs) -{ - /* - * check that RIP was not improperly advanced and that the - * flags value was preserved. - */ - report(regs->rip < finish_fault, "RIP has not been advanced!"); - report(((u8)regs->rflags == ((sentinel | 2) & 0xd7)), - "The low byte of RFLAGS was preserved!"); - regs->rip = finish_fault; - handler_called = true; - -} - -static void prep_flags_test_env(void **vpage, struct vmcs **vmcs, handler *old) +static void prep_flags_test_env(void **vpage, struct vmcs **vmcs) { /* * get an unbacked address that will cause a #PF @@ -421,107 +403,88 @@ static void prep_flags_test_env(void **vpage, struct vmcs **vmcs, handler *old) (*vmcs)->hdr.revision_id = basic.revision; assert(!vmcs_clear(*vmcs)); assert(!make_vmcs_current(*vmcs)); - - *old = handle_exception(PF_VECTOR, &pf_handler); } -static noinline void test_read_sentinel(void) +static void test_read_sentinel(u8 sentinel) { - void *vpage; + unsigned long flags = sentinel; + unsigned int vector; struct vmcs *vmcs; - handler old; + void *vpage; - prep_flags_test_env(&vpage, &vmcs, &old); + prep_flags_test_env(&vpage, &vmcs); /* - * set the proper label + * Execute VMREAD with a not-PRESENT memory operand, and verify a #PF + * occurred and RFLAGS were not modified. */ - extern char finish_read_fault; + asm volatile ("sahf\n\t" + ASM_TRY("1f") + "vmread %[enc], %[val]\n\t" + "1: lahf" + : [val] "=m" (*(u64 *)vpage), + [flags] "+a" (flags) + : [enc] "r" ((u64)GUEST_SEL_SS) + : "cc"); - finish_fault = (ulong)&finish_read_fault; + vector = exception_vector(); + report(vector == PF_VECTOR, + "Expected #PF on VMREAD, got exception 0x%x", vector); - /* - * execute the vmread instruction that will cause a #PF - */ - handler_called = false; - asm volatile ("movb %[byte], %%ah\n\t" - "sahf\n\t" - "vmread %[enc], %[val]; finish_read_fault:" - : [val] "=m" (*(u64 *)vpage) - : [byte] "Krm" (sentinel), - [enc] "r" ((u64)GUEST_SEL_SS) - : "cc", "ah"); - report(handler_called, "The #PF handler was invoked"); - - /* - * restore the old #PF handler - */ - handle_exception(PF_VECTOR, old); + report((u8)flags == sentinel, + "Expected RFLAGS 0x%x, got 0x%x", sentinel, (u8)flags); } static void test_vmread_flags_touch(void) { /* - * set up the sentinel value in the flags register. we - * choose these two values because they candy-stripe - * the 5 flags that sahf sets. + * Test with two values to candy-stripe the 5 flags stored/loaded by + * SAHF/LAHF. */ - sentinel = 0x91; - test_read_sentinel(); - - sentinel = 0x45; - test_read_sentinel(); + test_read_sentinel(0x91); + test_read_sentinel(0x45); } -static noinline void test_write_sentinel(void) +static void test_write_sentinel(u8 sentinel) { - void *vpage; + unsigned long flags = sentinel; + unsigned int vector; struct vmcs *vmcs; - handler old; + void *vpage; - prep_flags_test_env(&vpage, &vmcs, &old); + prep_flags_test_env(&vpage, &vmcs); /* - * set the proper label + * Execute VMWRITE with a not-PRESENT memory operand, and verify a #PF + * occurred and RFLAGS were not modified. */ - extern char finish_write_fault; + asm volatile ("sahf\n\t" + ASM_TRY("1f") + "vmwrite %[val], %[enc]\n\t" + "1: lahf" + : [val] "=m" (*(u64 *)vpage), + [flags] "+a" (flags) + : [enc] "r" ((u64)GUEST_SEL_SS) + : "cc"); - finish_fault = (ulong)&finish_write_fault; + vector = exception_vector(); + report(vector == PF_VECTOR, + "Expected #PF on VMWRITE, got exception '0x%x'\n", vector); - /* - * execute the vmwrite instruction that will cause a #PF - */ - handler_called = false; - asm volatile ("movb %[byte], %%ah\n\t" - "sahf\n\t" - "vmwrite %[val], %[enc]; finish_write_fault:" - : [val] "=m" (*(u64 *)vpage) - : [byte] "Krm" (sentinel), - [enc] "r" ((u64)GUEST_SEL_SS) - : "cc", "ah"); - report(handler_called, "The #PF handler was invoked"); - - /* - * restore the old #PF handler - */ - handle_exception(PF_VECTOR, old); + report((u8)flags == sentinel, + "Expected RFLAGS 0x%x, got 0x%x", sentinel, (u8)flags); } static void test_vmwrite_flags_touch(void) { /* - * set up the sentinel value in the flags register. we - * choose these two values because they candy-stripe - * the 5 flags that sahf sets. + * Test with two values to candy-stripe the 5 flags stored/loaded by + * SAHF/LAHF. */ - sentinel = 0x91; - test_write_sentinel(); - - sentinel = 0x45; - test_write_sentinel(); + test_write_sentinel(0x91); + test_write_sentinel(0x45); } - static void test_vmcs_high(void) { struct vmcs *vmcs = alloc_page(); From patchwork Fri Sep 30 23:24:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12996083 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9BEEC433F5 for ; Fri, 30 Sep 2022 23:25:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232496AbiI3XZx (ORCPT ); Fri, 30 Sep 2022 19:25:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232655AbiI3XZV (ORCPT ); Fri, 30 Sep 2022 19:25:21 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81660C80F1 for ; Fri, 30 Sep 2022 16:25:09 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id w14-20020a170902e88e00b00177ab7a12f6so4068274plg.16 for ; Fri, 30 Sep 2022 16:25:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date; bh=nL/lfFme3jtjL6Ze3CyERsb/LSTZ5YkGYrnD4NBE2Hw=; b=V/SjIoKmXFbrqT/binJvKHwdo3qdjqQCerJbBH/12Uc0FFc89bANMUmDqoGbfTRK5U L7yOtqX1cogO1+gHiLwAe/CBdRYReBpcOxpTbzQEGWoUveubNHmHsXNGIbVA8ox2webe n8zLcyeySOTHUeHaT928bcvRQncEqXHPN3tBuVEQZRCGfzxX9bBZe0nRlnNw6AYQkHK7 dlpXp8cwBBsGQ5E8zi40OQUc3N9y2LQRPSmCJ2Y7h9jXK0nQ6jiTxtRYmwnxu7GFieyi n/0aYKRGTUD48PkYQQyXYdJU+jGfX6RO2yAgXvitjdNa6ooUVRfv7foO1GMv/sUmyK63 J94A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date; bh=nL/lfFme3jtjL6Ze3CyERsb/LSTZ5YkGYrnD4NBE2Hw=; b=BIa6xoQEDaKvOGnxVq2RuckOv6laBBUiL4djD+DcC8LZq38eX7TT0/PpwyN7917XtB HkXV1uPzEmtSOCmBrfNa7ITiyiVS+zFgDIJA/lvdD00dbDcrMV7azI3lybAOU6sIE4sI 0VaAiK4EQ4oNfTETXHGaeRdq/o17r2Q2sDJjXcayc78UNwBImALunszKpWIjpMH0t+Xa PQajAVj8ZY/2P6mG+mZ7HlsTH77ZWBh2WsLAsuD8kTYO6RyAWCIWlfjIymlDpLnPwcQj F8a1WlJE+M7eaGdtmMQblfasDRMbiS6Ptur9pgYojb94DKJrQSOKdfqdXFN4FSQCpkMh h+9A== X-Gm-Message-State: ACrzQf2TRxeEDmKA49UAoUf502woU3GuTLud+CH7WcN6/kvS1vC139WU dqUjdg+CHyneIEQyoB76n5w1s0oNb8g= X-Google-Smtp-Source: AMsMyM7O3dnQbXaA7lnqaczL9ag44xopYssk6pKMbWEK5nOMoCVeThtSOfQ91nWw/nDBPo4RNcxEneddvBU= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:902:b085:b0:178:3af4:31b2 with SMTP id p5-20020a170902b08500b001783af431b2mr11378613plr.122.1664580296930; Fri, 30 Sep 2022 16:24:56 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 30 Sep 2022 23:24:50 +0000 In-Reply-To: <20220930232450.1677811-1-seanjc@google.com> Mime-Version: 1.0 References: <20220930232450.1677811-1-seanjc@google.com> X-Mailer: git-send-email 2.38.0.rc1.362.ged0d419d3c-goog Message-ID: <20220930232450.1677811-4-seanjc@google.com> Subject: [kvm-unit-tests PATCH 3/3] nVMX: Dedup the bulk of the VMREAD/VMWRITE #PF tests From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Dedup most of the VMREAD/VMWRITE #PF/flags tests, they are identical except for literally VMREAD vs. VMRITE. Don't bother adding a macro to emit VMREAD vs. VMWRITE, the macro required isn't any better than copy and paste. Signed-off-by: Sean Christopherson --- x86/vmx.c | 119 ++++++++++++++++++++---------------------------------- 1 file changed, 43 insertions(+), 76 deletions(-) diff --git a/x86/vmx.c b/x86/vmx.c index 0ae134d..e28507c 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -387,102 +387,69 @@ static void test_vmwrite_vmread(void) free_page(vmcs); } -static void prep_flags_test_env(void **vpage, struct vmcs **vmcs) -{ - /* - * get an unbacked address that will cause a #PF - */ - *vpage = alloc_vpage(); - - /* - * set up VMCS so we have something to read from - */ - *vmcs = alloc_page(); - - memset(*vmcs, 0, PAGE_SIZE); - (*vmcs)->hdr.revision_id = basic.revision; - assert(!vmcs_clear(*vmcs)); - assert(!make_vmcs_current(*vmcs)); -} - -static void test_read_sentinel(u8 sentinel) +static void __test_vmread_vmwrite_pf(bool vmread, u64 *val, u8 sentinel) { unsigned long flags = sentinel; unsigned int vector; - struct vmcs *vmcs; - void *vpage; - - prep_flags_test_env(&vpage, &vmcs); /* - * Execute VMREAD with a not-PRESENT memory operand, and verify a #PF - * occurred and RFLAGS were not modified. + * Execute VMREAD/VMWRITE with a not-PRESENT memory operand, and verify + * a #PF occurred and RFLAGS were not modified. */ - asm volatile ("sahf\n\t" - ASM_TRY("1f") - "vmread %[enc], %[val]\n\t" - "1: lahf" - : [val] "=m" (*(u64 *)vpage), - [flags] "+a" (flags) - : [enc] "r" ((u64)GUEST_SEL_SS) - : "cc"); + if (vmread) + asm volatile ("sahf\n\t" + ASM_TRY("1f") + "vmread %[enc], %[val]\n\t" + "1: lahf" + : [val] "=m" (*val), + [flags] "+a" (flags) + : [enc] "r" ((u64)GUEST_SEL_SS) + : "cc"); + else + asm volatile ("sahf\n\t" + ASM_TRY("1f") + "vmwrite %[val], %[enc]\n\t" + "1: lahf" + : [val] "=m" (*val), + [flags] "+a" (flags) + : [enc] "r" ((u64)GUEST_SEL_SS) + : "cc"); vector = exception_vector(); report(vector == PF_VECTOR, - "Expected #PF on VMREAD, got exception 0x%x", vector); + "Expected #PF on %s, got exception '0x%x'\n", + vmread ? "VMREAD" : "VMWRITE", vector); report((u8)flags == sentinel, "Expected RFLAGS 0x%x, got 0x%x", sentinel, (u8)flags); } +static void test_vmread_vmwrite_pf(bool vmread) +{ + struct vmcs *vmcs = alloc_page(); + void *vpage = alloc_vpage(); + + memset(vmcs, 0, PAGE_SIZE); + vmcs->hdr.revision_id = basic.revision; + assert(!vmcs_clear(vmcs)); + assert(!make_vmcs_current(vmcs)); + + /* + * Test with two values to candy-stripe the 5 flags stored/loaded by + * SAHF/LAHF. + */ + __test_vmread_vmwrite_pf(vmread, vpage, 0x91); + __test_vmread_vmwrite_pf(vmread, vpage, 0x45); +} + static void test_vmread_flags_touch(void) { - /* - * Test with two values to candy-stripe the 5 flags stored/loaded by - * SAHF/LAHF. - */ - test_read_sentinel(0x91); - test_read_sentinel(0x45); -} - -static void test_write_sentinel(u8 sentinel) -{ - unsigned long flags = sentinel; - unsigned int vector; - struct vmcs *vmcs; - void *vpage; - - prep_flags_test_env(&vpage, &vmcs); - - /* - * Execute VMWRITE with a not-PRESENT memory operand, and verify a #PF - * occurred and RFLAGS were not modified. - */ - asm volatile ("sahf\n\t" - ASM_TRY("1f") - "vmwrite %[val], %[enc]\n\t" - "1: lahf" - : [val] "=m" (*(u64 *)vpage), - [flags] "+a" (flags) - : [enc] "r" ((u64)GUEST_SEL_SS) - : "cc"); - - vector = exception_vector(); - report(vector == PF_VECTOR, - "Expected #PF on VMWRITE, got exception '0x%x'\n", vector); - - report((u8)flags == sentinel, - "Expected RFLAGS 0x%x, got 0x%x", sentinel, (u8)flags); + test_vmread_vmwrite_pf(true); } static void test_vmwrite_flags_touch(void) { - /* - * Test with two values to candy-stripe the 5 flags stored/loaded by - * SAHF/LAHF. - */ - test_write_sentinel(0x91); - test_write_sentinel(0x45); + test_vmread_vmwrite_pf(false); } static void test_vmcs_high(void)