]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
vvmx: Test vmxon in CPL=3 inside and outside of VMX operation
authorHaozhong Zhang <haozhong.zhang@intel.com>
Fri, 16 Dec 2016 13:43:39 +0000 (21:43 +0800)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 30 Jun 2017 09:21:43 +0000 (10:21 +0100)
Faults #UD and #GP(0) are expected in this test.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
Introduce a second test, checking both #UD and #GP(0)

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
tests/vvmx/test.h
tests/vvmx/util.c
tests/vvmx/vmxon.c

index ec0b67ed098bb40950e1771acd8058a2dd55c117..472d79623dffacb8a313c53912e56322fa7308d9 100644 (file)
@@ -25,6 +25,7 @@ void check(const char *func, exinfo_t got, exinfo_t exp);
 
 /* VMX instruction stubs, wrapped to return exinfo_t information. */
 exinfo_t stub_vmxon(uint64_t paddr);
+exinfo_t stub_vmxon_user(uint64_t paddr);
 
 /* Test routines. */
 void test_msr_vmx(void);
index b68384df1c4781742a867b94bb2d56b65d34214f..4290a998d6890579c9aa62bb09f9c34abc5b07fe 100644 (file)
@@ -91,6 +91,30 @@ exinfo_t stub_vmxon(uint64_t paddr)
         return ex;
 }
 
+exinfo_t __user_text stub_vmxon_user(uint64_t paddr)
+{
+    exinfo_t ex = 0;
+    bool fail_valid = false, fail_invalid = false;
+
+    asm volatile ("1: vmxon %[paddr];"
+                  ASM_FLAG_OUT(, "setc %[fail_invalid];")
+                  ASM_FLAG_OUT(, "setz %[fail_valid];")
+                  "2:"
+                  _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+                  : "+D" (ex),
+                    ASM_FLAG_OUT("=@ccc", [fail_invalid] "+rm") (fail_invalid),
+                    ASM_FLAG_OUT("=@ccz", [fail_valid]   "+rm") (fail_valid)
+                  : [paddr] "m" (paddr),
+                    "X" (ex_record_fault_edi));
+
+    if ( fail_invalid )
+        return VMERR_INVALID;
+    else if ( fail_valid )
+        return get_vmx_insn_err();
+    else
+        return ex;
+}
+
 /*
  * Local variables:
  * mode: C
index 1122ed56a5111414e0cc25179018ce0ca743be6b..aa65aa2dcb5f8237a75211a6ed969af086052ce4 100644 (file)
@@ -1,5 +1,8 @@
 #include "test.h"
 
+/* vmxon region which shouldn't be latched in the hardware vmxon pointer. */
+static uint8_t vmxon_region_unused[PAGE_SIZE] __page_aligned_bss;
+
 /**
  * vmxon with CR4.VMXE cleared
  *
@@ -10,6 +13,40 @@ static void test_vmxon_novmxe(void)
     check(__func__, stub_vmxon(0), EXINFO_SYM(UD, 0));
 }
 
+/*
+ * Wrapper around stub_vmxon_user(), This stub should always fault for control
+ * or permission reasons, but pointing at a supervisor frame is useful to
+ * check that Xen doesn't dereference the instructions parameter.
+ */
+static unsigned long __user_text vmxon_in_user(void)
+{
+    return stub_vmxon_user(_u(vmxon_region_unused));
+}
+
+/**
+ * vmxon in CPL=3 outside of VMX operation
+ *
+ * Expect: @#GP(0)
+ */
+static void test_vmxon_novmxe_in_user(void)
+{
+    exinfo_t ex = exec_user(vmxon_in_user);
+
+    check(__func__, ex, EXINFO_SYM(UD, 0));
+}
+
+/**
+ * vmxon in CPL=3 in VMX operation
+ *
+ * Expect: @#UD
+ */
+static void test_vmxon_in_user(void)
+{
+    exinfo_t ex = exec_user(vmxon_in_user);
+
+    check(__func__, ex, EXINFO_SYM(GP, 0));
+}
+
 void test_vmxon(void)
 {
     unsigned long cr4 = read_cr4();
@@ -20,6 +57,11 @@ void test_vmxon(void)
     printk("Test: vmxon\n");
 
     test_vmxon_novmxe();
+    test_vmxon_novmxe_in_user();
+
+    write_cr4(cr4 |= X86_CR4_VMXE);
+
+    test_vmxon_in_user();
 }
 
 /*