]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
vvmx: Test vmxon in VMX root w/ CPL = 0 and w/ current VMCS
authorHaozhong Zhang <haozhong.zhang@intel.com>
Fri, 16 Dec 2016 13:43:47 +0000 (21:43 +0800)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 30 Jun 2017 09:21:43 +0000 (10:21 +0100)
VMfailvalid() 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>
tests/vvmx/test.h
tests/vvmx/util.c
tests/vvmx/vmxon.c

index ef8239a16ac11384ad8bfb6f9f96834b784f7fb7..0e32ce57598fb4fbbd950785e583c4ad0f4ae54c 100644 (file)
@@ -41,6 +41,7 @@ static inline void clear_vmcs(void *_vmcs, uint32_t rev)
 
 /* VMX instruction stubs, wrapped to return exinfo_t information. */
 exinfo_t stub_vmxon(uint64_t paddr);
+exinfo_t stub_vmptrld(uint64_t paddr);
 exinfo_t stub_vmxon_user(uint64_t paddr);
 
 /* Test routines. */
index c86ed432ca2eaf3d838318bb0cc3daa52bc05352..6f9a0db9f676515d47d0eecc620eae962cc07ab7 100644 (file)
@@ -100,6 +100,30 @@ exinfo_t stub_vmxon(uint64_t paddr)
         return ex;
 }
 
+exinfo_t stub_vmptrld(uint64_t paddr)
+{
+    exinfo_t ex = 0;
+    bool fail_valid = false, fail_invalid = false;
+
+    asm volatile ("1: vmptrld %[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;
+}
+
 exinfo_t __user_text stub_vmxon_user(uint64_t paddr)
 {
     exinfo_t ex = 0;
index 5d655ea7190fdda96523b4bc24da7b141dc94655..a72d2e8643beef5afba88a0408a12b566336113f 100644 (file)
@@ -6,6 +6,9 @@ static uint8_t vmxon_region_unused[PAGE_SIZE] __page_aligned_bss;
 /* vmxon region which gets latched in hardware. */
 static uint8_t vmxon_region_real[PAGE_SIZE] __page_aligned_bss;
 
+/* Loaded VMCS, to recover VM Instruction Errors. */
+static uint8_t vmcs[PAGE_SIZE] __page_aligned_bss;
+
 /**
  * vmxon with CR4.VMXE cleared
  *
@@ -139,9 +142,23 @@ static void test_vmxon_novmcs_in_root_user(void)
     check(__func__, ex, EXINFO_SYM(GP, 0));
 }
 
+/**
+ * vmxon in VMX root w/ CPL = 0 and w/ current VMCS
+ *
+ * Expect: VMfailvalid()
+ */
+static void test_vmxon_in_root_cpl0(void)
+{
+    clear_vmcs(vmxon_region_unused, vmcs_revid);
+    exinfo_t ex = stub_vmxon(_u(vmxon_region_unused));
+
+    check(__func__, ex, VMERR_VALID(VMERR_VMXON_IN_ROOT));
+}
+
 void test_vmxon(void)
 {
     unsigned long cr4 = read_cr4();
+    exinfo_t ex;
 
     if ( cr4 & X86_CR4_VMXE )
         write_cr4(cr4 &= ~X86_CR4_VMXE);
@@ -164,6 +181,14 @@ void test_vmxon(void)
 
     test_vmxon_novmcs_in_root_cpl0();
     test_vmxon_novmcs_in_root_user();
+
+    /* Load a real VMCS to recover VM Instruction Errors. */
+    clear_vmcs(vmcs, vmcs_revid);
+    ex = stub_vmptrld(_u(vmcs));
+    if ( ex )
+        return xtf_failure("Fail: unexpected vmptrld failure %08x\n", ex);
+
+    test_vmxon_in_root_cpl0();
 }
 
 /*