[kvm-unit-tests PATCH 14/14] x86: Add tests that run ac_test_run() in an L2 guest

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add tests vmx_pf_exception_test and vmx_pf_exception_test_reduced_maxphyaddr
to vmx_tests.c.

The purpose of these tests are to test the reflection logic in KVM to
ensure exceptions are being routed to were they are intended to go.  For
example, it will test that we are not accidentally reflecting exceptions
into L1 when L1 isn't expecting them.  Commit 18712c13709d ("KVM: nVMX:
Use vmx_need_pf_intercept() when deciding if L0 wants a #PF") fixed an
issue related to this which went undetected because there was no testing
in place.  This adds testing to ensure there is coverage for such
issues.

Signed-off-by: Aaron Lewis <aaronlewis@xxxxxxxxxx>
---
 x86/Makefile.common |  2 ++
 x86/unittests.cfg   | 13 ++++++++++++
 x86/vmx_tests.c     | 49 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+)

diff --git a/x86/Makefile.common b/x86/Makefile.common
index a665854..461de51 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -74,6 +74,8 @@ $(TEST_DIR)/realmode.o: bits = $(if $(call cc-option,-m16,""),16,32)
 
 $(TEST_DIR)/access_test.elf: $(TEST_DIR)/access.o
 
+$(TEST_DIR)/vmx.elf: $(TEST_DIR)/access.o
+
 $(TEST_DIR)/kvmclock_test.elf: $(TEST_DIR)/kvmclock.o
 
 $(TEST_DIR)/hyperv_synic.elf: $(TEST_DIR)/hyperv.o
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index dbeb8a2..4069e4c 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -347,6 +347,19 @@ extra_params = -cpu max,+vmx -append vmx_vmcs_shadow_test
 arch = x86_64
 groups = vmx
 
+[vmx_pf_exception_test]
+file = vmx.flat
+extra_params = -cpu max,+vmx -append vmx_pf_exception_test
+arch = x86_64
+groups = vmx nested_exception
+
+[vmx_pf_exception_test_reduced_maxphyaddr]
+file = vmx.flat
+extra_params = -cpu IvyBridge,phys-bits=36,host-phys-bits=off,+vmx -append vmx_pf_exception_test
+arch = x86_64
+groups = vmx nested_exception
+check = /sys/module/kvm_intel/parameters/allow_smaller_maxphyaddr=Y
+
 [debug]
 file = debug.flat
 arch = x86_64
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 9ee6653..8cf3543 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -20,6 +20,7 @@
 #include "alloc_page.h"
 #include "smp.h"
 #include "delay.h"
+#include "access.h"
 
 #define VPID_CAP_INVVPID_TYPES_SHIFT 40
 
@@ -10658,6 +10659,53 @@ static void atomic_switch_overflow_msrs_test(void)
 		test_skip("Test is only supported on KVM");
 }
 
+static void vmx_pf_exception_test_guest(void)
+{
+	ac_test_run(PT_LEVEL_PML4);
+}
+
+static void vmx_pf_exception_test(void)
+{
+	u64 efer;
+	struct cpuid cpuid;
+
+	test_set_guest(vmx_pf_exception_test_guest);
+
+	enter_guest();
+
+	while (vmcs_read(EXI_REASON) != VMX_VMCALL) {
+		switch (vmcs_read(EXI_REASON)) {
+		case VMX_RDMSR:
+			assert(regs.rcx == MSR_EFER);
+			efer = vmcs_read(GUEST_EFER);
+			regs.rdx = efer >> 32;
+			regs.rax = efer & 0xffffffff;
+			break;
+		case VMX_WRMSR:
+			assert(regs.rcx == MSR_EFER);
+			efer = regs.rdx << 32 | (regs.rax & 0xffffffff);
+			vmcs_write(GUEST_EFER, efer);
+			break;
+		case VMX_CPUID:
+			cpuid = (struct cpuid) {0, 0, 0, 0};
+			cpuid = raw_cpuid(regs.rax, regs.rcx);
+			regs.rax = cpuid.a;
+			regs.rbx = cpuid.b;
+			regs.rcx = cpuid.c;
+			regs.rdx = cpuid.d;
+			break;
+		default:
+			assert_msg(false,
+				"Unexpected exit to L1, exit_reason: %s (0x%lx)",
+				exit_reason_description(vmcs_read(EXI_REASON)),
+				vmcs_read(EXI_REASON));
+		}
+		skip_exit_insn();
+		enter_guest();
+	}
+
+	assert_exit_reason(VMX_VMCALL);
+}
 #define TEST(name) { #name, .v2 = name }
 
 /* name/init/guest_main/exit_handler/syscall_handler/guest_regs */
@@ -10763,5 +10811,6 @@ struct vmx_test vmx_tests[] = {
 	TEST(rdtsc_vmexit_diff_test),
 	TEST(vmx_mtf_test),
 	TEST(vmx_mtf_pdpte_test),
+	TEST(vmx_pf_exception_test),
 	{ NULL, NULL, NULL, NULL, NULL, {0} },
 };
-- 
2.34.0.rc1.387.gb447b232ab-goog




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux