All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, Sean Christopherson <seanjc@google.com>
Subject: [kvm-unit-tests PATCH 12/14] x86: msr: Verify 64-bit only MSRs fault on 32-bit hosts
Date: Wed, 21 Apr 2021 20:05:02 -0700	[thread overview]
Message-ID: <20210422030504.3488253-13-seanjc@google.com> (raw)
In-Reply-To: <20210422030504.3488253-1-seanjc@google.com>

Assert that 64-bit only MSRs take a #GP when read or written on 32-bit
hosts, as opposed to simply skipping the MSRs on 32-bit builds.  Force
"cpu -host" so that CPUID can be used to check for 64-bit support.

Technically, the unit test could/should be even more aggressive and
require KVM to inject faults if the vCPU model doesn't support 64-bit
mode.  But, there are no plans to go to that level of emulation in KVM,
and practically speaking there isn't much benefit as allowing a 32-bit
vCPU to access the MSRs on a 64-bit host is a benign virtualization hole.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 lib/x86/processor.h | 22 +++++++++++++++++
 x86/msr.c           | 57 ++++++++++++++++++++++++++++++++-------------
 x86/unittests.cfg   |  6 +++--
 3 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index dda57a1..dfe96d0 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -2,6 +2,7 @@
 #define LIBCFLAT_PROCESSOR_H
 
 #include "libcflat.h"
+#include "desc.h"
 #include "msr.h"
 #include <stdint.h>
 
@@ -163,6 +164,7 @@ static inline u8 cpuid_maxphyaddr(void)
 #define	X86_FEATURE_ARCH_CAPABILITIES	(CPUID(0x7, 0, EDX, 29))
 #define	X86_FEATURE_PKS			(CPUID(0x7, 0, ECX, 31))
 #define	X86_FEATURE_NX			(CPUID(0x80000001, 0, EDX, 20))
+#define	X86_FEATURE_LM			(CPUID(0x80000001, 0, EDX, 29))
 #define	X86_FEATURE_RDPRU		(CPUID(0x80000008, 0, EBX, 4))
 
 /*
@@ -320,6 +322,26 @@ static inline void wrmsr(u32 index, u64 val)
     asm volatile ("wrmsr" : : "a"(a), "d"(d), "c"(index) : "memory");
 }
 
+static inline int rdmsr_checking(u32 index)
+{
+	asm volatile (ASM_TRY("1f")
+		      "rdmsr\n\t"
+		      "1:"
+		      : : "c"(index) : "memory", "eax", "edx");
+	return exception_vector();
+}
+
+static inline int wrmsr_checking(u32 index, u64 val)
+{
+        u32 a = val, d = val >> 32;
+
+	asm volatile (ASM_TRY("1f")
+		      "wrmsr\n\t"
+		      "1:"
+		      : : "a"(a), "d"(d), "c"(index) : "memory");
+	return exception_vector();
+}
+
 static inline uint64_t rdpmc(uint32_t index)
 {
     uint32_t a, d;
diff --git a/x86/msr.c b/x86/msr.c
index 4642451..e7ebe8b 100644
--- a/x86/msr.c
+++ b/x86/msr.c
@@ -6,6 +6,7 @@
 
 struct msr_info {
 	int index;
+	bool is_64bit_only;
 	const char *name;
 	unsigned long long value;
 };
@@ -14,26 +15,26 @@ struct msr_info {
 #define addr_64 0x0000123456789abcULL
 #define addr_ul (unsigned long)addr_64
 
-#define MSR_TEST(msr, val)	\
-	{ .index = msr, .name = #msr, .value = val }
+#define MSR_TEST(msr, val, only64)	\
+	{ .index = msr, .name = #msr, .value = val, .is_64bit_only = only64 }
 
 struct msr_info msr_info[] =
 {
-	MSR_TEST(MSR_IA32_SYSENTER_CS, 0x1234),
-	MSR_TEST(MSR_IA32_SYSENTER_ESP, addr_ul),
-	MSR_TEST(MSR_IA32_SYSENTER_EIP, addr_ul),
+	MSR_TEST(MSR_IA32_SYSENTER_CS, 0x1234, false),
+	MSR_TEST(MSR_IA32_SYSENTER_ESP, addr_ul, false),
+	MSR_TEST(MSR_IA32_SYSENTER_EIP, addr_ul, false),
 	// reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63
-	MSR_TEST(MSR_IA32_MISC_ENABLE, 0x400c51889),
-	MSR_TEST(MSR_IA32_CR_PAT, 0x07070707),
+	MSR_TEST(MSR_IA32_MISC_ENABLE, 0x400c51889, false),
+	MSR_TEST(MSR_IA32_CR_PAT, 0x07070707, false),
+	MSR_TEST(MSR_FS_BASE, addr_64, true),
+	MSR_TEST(MSR_GS_BASE, addr_64, true),
+	MSR_TEST(MSR_KERNEL_GS_BASE, addr_64, true),
 #ifdef __x86_64__
-	MSR_TEST(MSR_FS_BASE, addr_64),
-	MSR_TEST(MSR_GS_BASE, addr_64),
-	MSR_TEST(MSR_KERNEL_GS_BASE, addr_64),
-	MSR_TEST(MSR_EFER, 0xD00),
-	MSR_TEST(MSR_LSTAR, addr_64),
-	MSR_TEST(MSR_CSTAR, addr_64),
-	MSR_TEST(MSR_SYSCALL_MASK, 0xffffffff),
+	MSR_TEST(MSR_EFER, 0xD00, false),
 #endif
+	MSR_TEST(MSR_LSTAR, addr_64, true),
+	MSR_TEST(MSR_CSTAR, addr_64, true),
+	MSR_TEST(MSR_SYSCALL_MASK, 0xffffffff, true),
 //	MSR_IA32_DEBUGCTLMSR needs svm feature LBRV
 //	MSR_VM_HSAVE_PA only AMD host
 };
@@ -54,12 +55,36 @@ static void test_msr_rw(struct msr_info *msr, unsigned long long val)
 	report(val == r, "%s", msr->name);
 }
 
+static void test_wrmsr_fault(struct msr_info *msr, unsigned long long val)
+{
+	unsigned char vector = wrmsr_checking(msr->index, val);
+
+	report(vector == GP_VECTOR,
+	       "Expected #GP on WRSMR(%s, 0x%llx), got vector %d",
+	       msr->name, val, vector);
+}
+
+static void test_rdmsr_fault(struct msr_info *msr)
+{
+	unsigned char vector = rdmsr_checking(msr->index);
+
+	report(vector == GP_VECTOR,
+	       "Expected #GP on RDSMR(%s), got vector %d", msr->name, vector);
+}
+
 int main(int ac, char **av)
 {
+	bool is_64bit_host = this_cpu_has(X86_FEATURE_LM);
 	int i;
 
-	for (i = 0 ; i < ARRAY_SIZE(msr_info); i++)
-		test_msr_rw(&msr_info[i], msr_info[i].value);
+	for (i = 0 ; i < ARRAY_SIZE(msr_info); i++) {
+		if (is_64bit_host || !msr_info[i].is_64bit_only) {
+			test_msr_rw(&msr_info[i], msr_info[i].value);
+		} else {
+			test_wrmsr_fault(&msr_info[i], msr_info[i].value);
+			test_rdmsr_fault(&msr_info[i]);
+		}
+	}
 
 	return report_summary();
 }
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index c2608bc..29cfe51 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -168,9 +168,11 @@ arch = x86_64
 
 [msr]
 # Use GenuineIntel to ensure SYSENTER MSRs are fully preserved, and to test
-# SVM emulation of Intel CPU behavior.
+# SVM emulation of Intel CPU behavior.  Use the host CPU model so that 64-bit
+# support follows the host kernel.  Running a 32-bit guest on a 64-bit host
+# will fail due to shortcomings in KVM.
 file = msr.flat
-extra_params = -cpu qemu64,vendor=GenuineIntel
+extra_params = -cpu host,vendor=GenuineIntel
 
 [pmu]
 file = pmu.flat
-- 
2.31.1.498.g6c1eba8ee3d-goog


  parent reply	other threads:[~2021-04-22  3:05 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-22  3:04 [kvm-unit-tests PATCH 00/14] x86: MSR_GS_BASE and friends Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 01/14] x86/cstart: Don't use MSR_GS_BASE in 32-bit boot code Sean Christopherson
2021-04-22  9:44   ` Paolo Bonzini
2021-04-22 10:02   ` Paolo Bonzini
2021-04-22 17:57     ` Sean Christopherson
2021-04-23  6:57       ` Paolo Bonzini
2021-04-22  3:04 ` [kvm-unit-tests PATCH 02/14] x86: msr: Exclude GS/FS_BASE MSRs from 32-bit builds Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 03/14] x86: msr: Advertise GenuineIntel as vendor to play nice with SYSENTER Sean Christopherson
2021-04-22 10:11   ` Paolo Bonzini
2021-04-22  3:04 ` [kvm-unit-tests PATCH 04/14] x86: msr: Restore original MSR value after writing arbitrary test value Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 05/14] x86: Force the compiler to retrieve exception info from per-cpu area Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 06/14] x86: msr: Replace spaces with tabs in all of msr.c Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 07/14] x86: msr: Use ARRAY_SIZE() instead of open coded equivalent Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 08/14] x86: msr: Use the #defined MSR indices in favor of open coding the values Sean Christopherson
2021-04-22  3:04 ` [kvm-unit-tests PATCH 09/14] x86: msr: Drop the explicit expected value Sean Christopherson
2021-04-22  3:05 ` [kvm-unit-tests PATCH 10/14] x86: msr: Add builder macros to define MSR entries Sean Christopherson
2021-04-22  3:05 ` [kvm-unit-tests PATCH 11/14] x86: msr: Pass msr_info instead of doing a lookup at runtime Sean Christopherson
2021-04-22  3:05 ` Sean Christopherson [this message]
2021-04-22 10:32   ` [kvm-unit-tests PATCH 12/14] x86: msr: Verify 64-bit only MSRs fault on 32-bit hosts Paolo Bonzini
2021-04-22  3:05 ` [kvm-unit-tests PATCH 13/14] x86: msr: Test that always-canonical MSRs #GP on non-canonical value Sean Christopherson
2021-04-22  3:05 ` [kvm-unit-tests PATCH 14/14] x86: msr: Verify that EFER.SCE can be written on 32-bit vCPUs Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210422030504.3488253-13-seanjc@google.com \
    --to=seanjc@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.