diff mbox series

nSVM: Test VMLOAD/VMSAVE intercepts

Message ID 20210304163613.42116-2-krish.sadhukhan@oracle.com (mailing list archive)
State New, archived
Headers show
Series nSVM: Test VMLOAD/VMSAVE intercepts | expand

Commit Message

Krish Sadhukhan March 4, 2021, 4:36 p.m. UTC
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(+)

Comments

Paolo Bonzini March 4, 2021, 6 p.m. UTC | #1
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 mbox series

Patch

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 }
 };