@@ -2499,6 +2499,37 @@ static void test_msrpm_iopm_bitmap_addrs(void)
vmcb->control.intercept = saved_intercept;
}
+#define TEST_CANONICAL(seg_base, msg, is_canonicalized) { \
+ u64 saved_addr = seg_base; \
+ int ret; \
+ \
+ seg_base = NONCANONICAL; \
+ ret = svm_vmrun(); \
+ report(ret == SVM_EXIT_VMMCALL && \
+ is_canonical(seg_base) == is_canonicalized, "%s.base: on " \
+ "VMRUN %llx, on VMEXIT: %lx", msg, NONCANONICAL, seg_base); \
+ seg_base = saved_addr; \
+}
+
+/*
+ * VMRUN canonicalizes (i.e., sign-extend to bit 63) all base addresses
+ • in the segment registers that have been loaded.
+ */
+static void test_vmrun_canonicalization(void)
+{
+
+ TEST_CANONICAL(vmcb->save.es.base, "ES", false);
+ TEST_CANONICAL(vmcb->save.cs.base, "CS", false);
+ TEST_CANONICAL(vmcb->save.ss.base, "SS", false);
+ TEST_CANONICAL(vmcb->save.ds.base, "DS", false);
+ TEST_CANONICAL(vmcb->save.fs.base, "FS", true);
+ TEST_CANONICAL(vmcb->save.gs.base, "GS", true);
+ TEST_CANONICAL(vmcb->save.gdtr.base, "GDTR", false);
+ TEST_CANONICAL(vmcb->save.ldtr.base, "LDTR", true);
+ TEST_CANONICAL(vmcb->save.idtr.base, "IDTR", false);
+ TEST_CANONICAL(vmcb->save.tr.base, "TR", true);
+}
+
static void svm_guest_state_test(void)
{
test_set_guest(basic_guest_main);
@@ -2508,6 +2539,7 @@ static void svm_guest_state_test(void)
test_cr4();
test_dr();
test_msrpm_iopm_bitmap_addrs();
+ test_vmrun_canonicalization();
}
According to section "Canonicalization and Consistency Checks" in APM vol 2, VMRUN canonicalizes (i.e., sign-extend to bit 63) all base addresses in the segment registers that have been loaded. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com> --- x86/svm_tests.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)