[kvm-unit-tests PATCH 2/2] x86: svm: Add test for L2 change of CR4.OSXSAVE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If L1 allows L2 to modify CR4.OSXSAVE, then L0 kvm recalculates the
guest's CPUID.01H:ECX.OSXSAVE bit when the L2 guest changes
CR4.OSXSAVE via MOV-to-CR4. Verify that kvm also recalculates this
CPUID bit when loading L1's CR4 from the save.cr4 field of the
hsave area.

Signed-off-by: Jim Mattson <jmattson@xxxxxxxxxx>
Reviewed-by: Ricardo Koller <ricarkol@xxxxxxxxxx>
Reviewed-by: Peter Shier <pshier@xxxxxxxxxx>
---
 x86/svm_tests.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/x86/svm_tests.c b/x86/svm_tests.c
index 3b0424a..e2455c8 100644
--- a/x86/svm_tests.c
+++ b/x86/svm_tests.c
@@ -1917,6 +1917,40 @@ static bool reg_corruption_check(struct svm_test *test)
  * v2 tests
  */
 
+/*
+ * Ensure that kvm recalculates the L1 guest's CPUID.01H:ECX.OSXSAVE
+ * after VM-exit from an L2 guest that sets CR4.OSXSAVE to a different
+ * value than in L1.
+ */
+
+static void svm_cr4_osxsave_test_guest(struct svm_test *test)
+{
+	write_cr4(read_cr4() & ~X86_CR4_OSXSAVE);
+}
+
+static void svm_cr4_osxsave_test(void)
+{
+	if (!this_cpu_has(X86_FEATURE_XSAVE)) {
+		report_skip("XSAVE not detected");
+		return;
+	}
+
+	if (!(read_cr4() & X86_CR4_OSXSAVE)) {
+		unsigned long cr4 = read_cr4() | X86_CR4_OSXSAVE;
+
+		write_cr4(cr4);
+		vmcb->save.cr4 = cr4;
+	}
+
+	report(cpuid_osxsave(), "CPUID.01H:ECX.XSAVE set before VMRUN");
+
+	test_set_guest(svm_cr4_osxsave_test_guest);
+	report(svm_vmrun() == SVM_EXIT_VMMCALL,
+	       "svm_cr4_osxsave_test_guest finished with VMMCALL");
+
+	report(cpuid_osxsave(), "CPUID.01H:ECX.XSAVE set after VMRUN");
+}
+
 static void basic_guest_main(struct svm_test *test)
 {
 }
@@ -2301,6 +2335,7 @@ struct svm_test svm_tests[] = {
     { "reg_corruption", default_supported, reg_corruption_prepare,
       default_prepare_gif_clear, reg_corruption_test,
       reg_corruption_finished, reg_corruption_check },
+    TEST(svm_cr4_osxsave_test),
     TEST(svm_guest_state_test),
     { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
-- 
2.29.1.341.ge80a0c044ae-goog




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux