Test that if L2 triggers a shutdown, this VM exits to L1 and doesn't crash the host. Signed-off-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx> --- x86/svm_tests.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/x86/svm_tests.c b/x86/svm_tests.c index 19b35e95..2c29c2b0 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -10,6 +10,7 @@ #include "isr.h" #include "apic.h" #include "delay.h" +#include "vmalloc.h" #define SVM_EXIT_MAX_DR_INTERCEPT 0x3f @@ -3270,6 +3271,55 @@ static void svm_intr_intercept_mix_smi(void) svm_intr_intercept_mix_run_guest(NULL, SVM_EXIT_SMI); } + +static void shutdown_intercept_test_guest(struct svm_test *test) +{ + asm volatile ("int3"); + report_fail("should not reach here\n"); + +} + +static void shutdown_intercept_test_guest2(struct svm_test *test) +{ + asm volatile ("ud2"); + report_fail("should not reach here\n"); + +} + +static void svm_shutdown_intercept_test(void) +{ + void* unmapped_address = alloc_vpage(); + + /* + * Test that shutdown vm exit doesn't crash L0 + * + * Test both native and emulated triple fault + * (due to exception merging) + */ + + + /* + * This will usually cause native SVM_EXIT_SHUTDOWN + * (KVM usually doesn't intercept #PF) + * */ + test_set_guest(shutdown_intercept_test_guest); + vmcb->save.idtr.base = (u64)unmapped_address; + vmcb->control.intercept |= (1ULL << INTERCEPT_SHUTDOWN); + svm_vmrun(); + report (vmcb->control.exit_code == SVM_EXIT_SHUTDOWN, "shutdown (BP->PF->DF->TRIPLE_FAULT) test passed"); + + /* + * This will usually cause emulated SVM_EXIT_SHUTDOWN + * (KVM usually intercepts #UD) + */ + test_set_guest(shutdown_intercept_test_guest2); + vmcb_ident(vmcb); + vmcb->save.idtr.limit = 0; + vmcb->control.intercept |= (1ULL << INTERCEPT_SHUTDOWN); + svm_vmrun(); + report (vmcb->control.exit_code == SVM_EXIT_SHUTDOWN, "shutdown (UD->DF->TRIPLE_FAULT) test passed"); +} + struct svm_test svm_tests[] = { { "null", default_supported, default_prepare, default_prepare_gif_clear, null_test, @@ -3382,6 +3432,7 @@ struct svm_test svm_tests[] = { TEST(svm_intr_intercept_mix_smi), TEST(svm_tsc_scale_test), TEST(pause_filter_test), + TEST(svm_shutdown_intercept_test), { NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; -- 2.26.3