]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
vvmx: Test vmxon with CR4.VMXE cleared
authorHaozhong Zhang <haozhong.zhang@intel.com>
Fri, 16 Dec 2016 13:43:38 +0000 (21:43 +0800)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 30 Jun 2017 09:21:42 +0000 (10:21 +0100)
Fault #UD is expected in this test.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
Rebase and cleanup.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/include/arch/x86-vmx.h
include/xtf/lib.h
tests/vvmx/Makefile
tests/vvmx/main.c
tests/vvmx/test.h
tests/vvmx/util.c
tests/vvmx/vmxon.c [new file with mode: 0644]

index 6edefbfb4b8e783bd3a6b60166eb63a3143bd74f..da8f8fdcfca7817997eae3fe33e5148ed816ee93 100644 (file)
 /* 27 not specified. */
 #define VMERR_BAD_INV_OPERAND                       28
 
+
+/* VMCS field encodings. */
+#define VMCS_VM_INSN_ERR                        0x4400
+
 #endif /* XTF_X86_X86_VMX_H */
 
 /*
index 3c3022ef3c90cfac0f3c3ce02818d7e45d422723..a392fb48a9dee1d42c147d2a8ab010d854308b5b 100644 (file)
@@ -49,6 +49,12 @@ void __noreturn panic(const char *fmt, ...) __printf(1, 2);
 
 #define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1))
 
+#ifdef __GCC_ASM_FLAG_OUTPUTS__
+# define ASM_FLAG_OUT(yes, no) yes
+#else
+# define ASM_FLAG_OUT(yes, no) no
+#endif
+
 void heapsort(void *base, size_t nmemb, size_t size,
               int (*compar)(const void *, const void *),
               void (*swap)(void *, void *));
index 8fe575fab1394b248f52fb72f84ea9bc8fc9d227..2fc67c1779003bffe0c02a17e0a8c9dd1c0aa0e1 100644 (file)
@@ -6,6 +6,6 @@ TEST-ENVS := $(HVM_ENVIRONMENTS)
 
 TEST-EXTRA-CFG := extra.cfg.in
 
-obj-perenv += main.o msr.o util.o
+obj-perenv += main.o msr.o util.o vmxon.o
 
 include $(ROOT)/build/gen.mk
index 6c02cfc09f430169662e44890b8450968c5e8295..5c635d0e130a67ecc9cacf5f37793b049b636ccc 100644 (file)
@@ -21,6 +21,7 @@ void test_main(void)
         xtf_warning("Warning: VT-x found on non-Intel processor\n");
 
     test_msr_vmx();
+    test_vmxon();
 
     xtf_success(NULL);
 }
index e5a1f831b755ea2c6eebf06f00c22ca81a69b340..ec0b67ed098bb40950e1771acd8058a2dd55c117 100644 (file)
  */
 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);
+
 /* Test routines. */
 void test_msr_vmx(void);
+void test_vmxon(void);
 
 #endif /* VVMX_TEST_H */
index 2a085c213719d9c2cf3db5c9e26062d4375b4a48..b68384df1c4781742a867b94bb2d56b65d34214f 100644 (file)
@@ -52,6 +52,45 @@ void check(const char *func, exinfo_t got, exinfo_t exp)
                 func, exp, expstr, got, gotstr);
 }
 
+/*
+ * Read the VM Instruction Error code from the VMCS.  It is the callers
+ * responsibility to ensure that the VMCS is valid in context.
+ */
+static exinfo_t get_vmx_insn_err(void)
+{
+    unsigned long err;
+
+    asm ("vmread %[field], %[value]"
+         : [value] "=rm" (err)
+         : [field] "r" (VMCS_VM_INSN_ERR + 0ul));
+
+    return VMERR_VALID(err);
+}
+
+exinfo_t stub_vmxon(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
diff --git a/tests/vvmx/vmxon.c b/tests/vvmx/vmxon.c
new file mode 100644 (file)
index 0000000..1122ed5
--- /dev/null
@@ -0,0 +1,33 @@
+#include "test.h"
+
+/**
+ * vmxon with CR4.VMXE cleared
+ *
+ * Expect: @#UD
+ */
+static void test_vmxon_novmxe(void)
+{
+    check(__func__, stub_vmxon(0), EXINFO_SYM(UD, 0));
+}
+
+void test_vmxon(void)
+{
+    unsigned long cr4 = read_cr4();
+
+    if ( cr4 & X86_CR4_VMXE )
+        write_cr4(cr4 &= ~X86_CR4_VMXE);
+
+    printk("Test: vmxon\n");
+
+    test_vmxon_novmxe();
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */