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@xxxxxxxxxx> --- x86/vmx_tests.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) 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; -- 2.34.1.173.g76aa8bc2d0-goog