According to section "Nested Paging and VMRUN/#VMEXIT" in APM vol 2, the following guest state is illegal: "Any MBZ bit of nCR3 is set" Signed-off-by: Krish Sadhukhan <krish.sadhkhan@xxxxxxxxxx> --- x86/svm_tests.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/x86/svm_tests.c b/x86/svm_tests.c index 8ad6122..ecfb5cb 100644 --- a/x86/svm_tests.c +++ b/x86/svm_tests.c @@ -2183,7 +2183,10 @@ static void basic_guest_main(struct svm_test *test) vmcb->save.cr0 = tmp; \ break; \ case 3: \ - vmcb->save.cr3 = tmp; \ + if (strcmp(test_name, "nested ") == 0) \ + vmcb->control.nested_cr3 = tmp; \ + else \ + vmcb->save.cr3 = tmp; \ break; \ case 4: \ vmcb->save.cr4 = tmp; \ @@ -2547,6 +2550,41 @@ static void guest_rflags_test_db_handler(struct ex_regs *r) r->rflags &= ~X86_EFLAGS_TF; } +static void test_ncr3(void) +{ + u64 ncr3_saved = vmcb->control.nested_cr3; + u64 nested_ctl_saved = vmcb->control.nested_ctl; + u32 ret; + + if (!npt_supported()) { + report_skip("NPT not supported"); + return; + } + + vmcb->control.nested_ctl = 0; + SVM_TEST_CR_RESERVED_BITS(0, 63, 1, 3, ncr3_saved, + SVM_CR3_LONG_MBZ_MASK, SVM_EXIT_VMMCALL, "nested "); + + vmcb->control.nested_cr3 = ncr3_saved & ~SVM_CR3_LONG_MBZ_MASK; + ret = svm_vmrun(); + report (ret == SVM_EXIT_VMMCALL, "Test CR3 nested 63:0: %lx, wanted " + "exit 0x%x, got 0x%x", ncr3_saved & ~SVM_CR3_LONG_MBZ_MASK, + SVM_EXIT_VMMCALL, ret); + + vmcb->control.nested_ctl = 1; + SVM_TEST_CR_RESERVED_BITS(0, 63, 1, 3, ncr3_saved, + SVM_CR3_LONG_MBZ_MASK, SVM_EXIT_ERR, "nested "); + + vmcb->control.nested_cr3 = ncr3_saved & ~SVM_CR3_LONG_MBZ_MASK; + ret = svm_vmrun(); + report (ret == SVM_EXIT_VMMCALL, "Test CR3 nested 63:0: %lx, wanted " + "exit 0x%x, got 0x%x", ncr3_saved & ~SVM_CR3_LONG_MBZ_MASK, + SVM_EXIT_VMMCALL, ret); + + vmcb->control.nested_cr3 = ncr3_saved; + vmcb->control.nested_ctl = nested_ctl_saved; +} + static void svm_guest_state_test(void) { test_set_guest(basic_guest_main); @@ -2557,6 +2595,7 @@ static void svm_guest_state_test(void) test_dr(); test_msrpm_iopm_bitmap_addrs(); test_canonicalization(); + test_ncr3(); } extern void guest_rflags_test_guest(struct svm_test *test); -- 2.27.0