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>
/* 27 not specified. */
#define VMERR_BAD_INV_OPERAND 28
+
+/* VMCS field encodings. */
+#define VMCS_VM_INSN_ERR 0x4400
+
#endif /* XTF_X86_X86_VMX_H */
/*
#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 *));
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
xtf_warning("Warning: VT-x found on non-Intel processor\n");
test_msr_vmx();
+ test_vmxon();
xtf_success(NULL);
}
*/
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 */
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
--- /dev/null
+#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:
+ */