[PATCH kvm-unit-tests] x86: access: fix SMEP-disabled case with TCG

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

 



TCG always allows setting CR4.SMEP, even when the CPUID bit is
disabled.  In this case, however, the test causes a triple fault
because it tries to execute a user page with CR4.SMEP=1.  The
right way to do the test is to go through set_cr4_smep.  Change
set_cr4_smep to return whether an exception happened, and use it
in ac_test_run.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 x86/access.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/x86/access.c b/x86/access.c
index 56d17a1..640ca8c 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -192,23 +192,25 @@ void set_cr0_wp(int wp)
         write_cr0(cr0);
 }
 
-void set_cr4_smep(int smep)
+unsigned set_cr4_smep(int smep)
 {
     unsigned long cr4 = read_cr4();
     unsigned long old_cr4 = cr4;
     extern u64 ptl2[];
+    unsigned r;
 
     cr4 &= ~CR4_SMEP_MASK;
     if (smep)
 	cr4 |= CR4_SMEP_MASK;
     if (old_cr4 == cr4)
-        return;
+        return 0;
 
     if (smep)
         ptl2[2] &= ~PT_USER_MASK;
-    write_cr4(cr4);
+    r = write_cr4_checking(cr4);
     if (!smep)
         ptl2[2] |= PT_USER_MASK;
+    return r;
 }
 
 void set_cr4_pke(int pke)
@@ -951,9 +953,8 @@ int ac_test_run(void)
     }
 
     if (!(cpuid_7_ebx & (1 << 7))) {
-	unsigned long cr4 = read_cr4();
 	tests++;
-	if (write_cr4_checking(cr4 | CR4_SMEP_MASK) == GP_VECTOR) {
+	if (set_cr4_smep(1) == GP_VECTOR) {
             successes++;
             invalid_mask |= AC_CPU_CR4_SMEP_MASK;
             printf("CR4.SMEP not available, disabling SMEP tests\n");
-- 
2.13.5




[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