diff mbox series

[kvm-unit-tests,v2,4/4] x86: Add test coverage for nested_vmx_reflect_vmexit() testing

Message ID 20211214011823.3277011-5-aaronlewis@google.com (mailing list archive)
State New, archived
Headers show
Series Add additional testing for routing L2 exceptions | expand

Commit Message

Aaron Lewis Dec. 14, 2021, 1:18 a.m. UTC
Add test cases to ensure exceptions that occur in L2 are forwarded to
the correct place.  Add testing for exceptions: #GP, #UD, #DE, #DB, #BP,
and #AC.

Signed-off-by: Aaron Lewis <aaronlewis@google.com>
---
 x86/vmx_tests.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
diff mbox series

Patch

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 018db2f..f795330 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -21,6 +21,7 @@ 
 #include "smp.h"
 #include "delay.h"
 #include "access.h"
+#include "x86/usermode.h"
 
 #define VPID_CAP_INVVPID_TYPES_SHIFT 40
 
@@ -10701,6 +10702,72 @@  static void vmx_pf_vpid_test(void)
 	__vmx_pf_vpid_test(invalidate_tlb_new_vpid, 1);
 }
 
+static void vmx_l2_gp_test(void)
+{
+	*(volatile u64 *)NONCANONICAL = 0;
+}
+
+static void vmx_l2_ud_test(void)
+{
+	asm volatile ("ud2");
+}
+
+static void vmx_l2_de_test(void)
+{
+	asm volatile (
+		"xor %%eax, %%eax\n\t"
+		"xor %%ebx, %%ebx\n\t"
+		"xor %%edx, %%edx\n\t"
+		"idiv %%ebx\n\t"
+		::: "eax", "ebx", "edx");
+}
+
+static void vmx_l2_bp_test(void)
+{
+	asm volatile ("int3");
+}
+
+static void vmx_db_init(void)
+{
+	enable_tf();
+}
+
+static void vmx_db_uninit(void)
+{
+	disable_tf();
+}
+
+static void vmx_l2_db_test(void)
+{
+}
+
+static uint64_t usermode_callback(void)
+{
+	/* Trigger an #AC by writing 8 bytes to a 4-byte aligned address. */
+	asm volatile(
+		"sub $0x10, %rsp\n\t"
+		"movq $0, 0x4(%rsp)\n\t"
+		"add $0x10, %rsp\n\t");
+
+	return 0;
+}
+
+static void vmx_l2_ac_test(void)
+{
+	u64 old_cr0  = read_cr0();
+	u64 old_rflags = read_rflags();
+	bool raised_vector = false;
+
+	write_cr0(old_cr0 | X86_CR0_AM);
+	write_rflags(old_rflags | X86_EFLAGS_AC);
+
+	run_in_user(usermode_callback, AC_VECTOR, 0, 0, 0, 0, &raised_vector);
+	report(raised_vector, "#AC vector raised from usermode in L2");
+
+	write_cr0(old_cr0);
+	write_rflags(old_rflags);
+}
+
 struct vmx_exception_test {
 	u8 vector;
 	void (*guest_code)(void);
@@ -10709,6 +10776,12 @@  struct vmx_exception_test {
 };
 
 struct vmx_exception_test vmx_exception_tests[] = {
+	{ GP_VECTOR, vmx_l2_gp_test },
+	{ UD_VECTOR, vmx_l2_ud_test },
+	{ DE_VECTOR, vmx_l2_de_test },
+	{ DB_VECTOR, vmx_l2_db_test, vmx_db_init, vmx_db_uninit },
+	{ BP_VECTOR, vmx_l2_bp_test },
+	{ AC_VECTOR, vmx_l2_ac_test },
 };
 
 static u8 vmx_exception_test_vector;