Message ID | 20210304163613.42116-2-krish.sadhukhan@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | nSVM: Test VMLOAD/VMSAVE intercepts | expand |
On 04/03/21 17:36, Krish Sadhukhan wrote: > 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@oracle.com> > --- > 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 } > }; > Queued, thanks. Paolo
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 } };
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@oracle.com> --- x86/svm_tests.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)