If VMLOAD/VMSAVE intercepts are disabled, no respective #VMEXIT to host happens. Enabling VMLOAD/VMSAVE intercept will cause respective #VMEXIT to host. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> --- x86/svm_tests.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/x86/svm_tests.c b/x86/svm_tests.c index 29a0b59..7f4e63e 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -2382,6 +2382,69 @@ static void svm_vmrun_errata_test(void) } } +static void vmload_vmsave_guest_main(struct svm_test *test) +{ + u64 vmcb_phys = virt_to_phys(vmcb); + + asm volatile ("vmload %0" : : "a"(vmcb_phys)); + asm volatile ("vmsave %0" : : "a"(vmcb_phys)); +} + +static void svm_vmload_vmsave(void) +{ + u32 intercept_saved = vmcb->control.intercept; + + test_set_guest(vmload_vmsave_guest_main); + + /* + * Disabling intercept for VMLOAD and VMSAVE doesn't cause + * respective #VMEXIT to host + */ + vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMLOAD); + vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMSAVE); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test " + "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT"); + + /* + * Enabling intercept for VMLOAD and VMSAVE causes respective + * #VMEXIT to host + */ + vmcb->control.intercept |= (1ULL << INTERCEPT_VMLOAD); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMLOAD, "Test " + "VMLOAD/VMSAVE intercept: Expected VMLOAD #VMEXIT"); + vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMLOAD); + vmcb->control.intercept |= (1ULL << INTERCEPT_VMSAVE); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMSAVE, "Test " + "VMLOAD/VMSAVE intercept: Expected VMSAVE #VMEXIT"); + vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMSAVE); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test " + "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT"); + + vmcb->control.intercept |= (1ULL << INTERCEPT_VMLOAD); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMLOAD, "Test " + "VMLOAD/VMSAVE intercept: Expected VMLOAD #VMEXIT"); + vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMLOAD); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test " + "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT"); + + vmcb->control.intercept |= (1ULL << INTERCEPT_VMSAVE); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMSAVE, "Test " + "VMLOAD/VMSAVE intercept: Expected VMSAVE #VMEXIT"); + vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMSAVE); + svm_vmrun(); + report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test " + "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT"); + + vmcb->control.intercept = intercept_saved; +} + struct svm_test svm_tests[] = { { "null", default_supported, default_prepare, default_prepare_gif_clear, null_test, @@ -2495,5 +2558,6 @@ struct svm_test svm_tests[] = { TEST(svm_cr4_osxsave_test), TEST(svm_guest_state_test), TEST(svm_vmrun_errata_test), + TEST(svm_vmload_vmsave), { NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; -- 2.27.0