diff mbox series

[kvm-unit-tests,3/3] x86: Add a regression test for L1 LDTR persistence bug

Message ID 20211008212447.2055660-4-jmattson@google.com (mailing list archive)
State New, archived
Headers show
Series Regression test for L1 LDTR persistence bug | expand

Commit Message

Jim Mattson Oct. 8, 2021, 9:24 p.m. UTC
Add a regression test for Linux commit afc8de0118be ("KVM: nVMX: Set
LDTR to its architecturally defined value on nested VM-Exit"). L1's
LDTR should be 0 after an emulated VM-exit from L2.

Signed-off-by: Jim Mattson <jmattson@google.com>
---
 x86/vmx_tests.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
diff mbox series

Patch

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 4f712ebccc08..9aafaa786ab6 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -8369,6 +8369,44 @@  static void vmentry_movss_shadow_test(void)
 	vmcs_write(GUEST_RFLAGS, X86_EFLAGS_FIXED);
 }
 
+static void vmx_ldtr_test_guest(void)
+{
+	u16 ldtr = sldt();
+
+	report(ldtr == NP_SEL, "L2 LDTR selector is %x (actual %x)",
+	       NP_SEL, ldtr);
+}
+
+/*
+ * Ensure that the L1 LDTR is set to 0 on VM-exit.
+ */
+static void vmx_ldtr_test(void)
+{
+	const u8 ldt_ar = 0x82; /* Present LDT */
+	u16 sel = FIRST_SPARE_SEL;
+
+	/* Set up a non-zero L1 LDTR prior to VM-entry. */
+	set_gdt_entry(sel, 0, 0, ldt_ar, 0);
+	lldt(sel);
+
+	test_set_guest(vmx_ldtr_test_guest);
+	/*
+	 * Set up a different LDTR for L2. The actual GDT contents are
+	 * irrelevant, since we stuff the hidden descriptor state
+	 * straight into the VMCS rather than reading it from the GDT.
+	 */
+	vmcs_write(GUEST_SEL_LDTR, NP_SEL);
+	vmcs_write(GUEST_AR_LDTR, ldt_ar);
+	enter_guest();
+
+	/*
+	 * VM-exit should clear LDTR (and make it unusable, but we
+	 * won't verify that here).
+	 */
+	sel = sldt();
+	report(!sel, "L1 LDTR selector is 0 (actual %x)", sel);
+}
+
 static void vmx_single_vmcall_guest(void)
 {
 	vmcall();
@@ -10730,6 +10768,7 @@  struct vmx_test vmx_tests[] = {
 	/* VMCS Shadowing tests */
 	TEST(vmx_vmcs_shadow_test),
 	/* Regression tests */
+	TEST(vmx_ldtr_test),
 	TEST(vmx_cr_load_test),
 	TEST(vmx_cr4_osxsave_test),
 	TEST(vmx_nm_test),