@@ -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);
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@oracle.com> --- x86/svm_tests.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-)