From: "Radim Krčmář" <rkrcmar@redhat.com>
To: kvm@vger.kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>
Subject: [kvm-unit-tests PATCH] x86: vmx: test invalid vmcs
Date: Wed, 21 Dec 2016 21:26:04 +0100 [thread overview]
Message-ID: <20161221202604.24248-1-rkrcmar@redhat.com> (raw)
This patch adds a generator for simple VMCS tests, generates few tests
for recent changes, and also pulls in some header file dependencies.
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
x86/vmx.h | 39 +++++++++++++++++++++++++++++++++++++++
x86/vmx_tests.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/x86/vmx.h b/x86/vmx.h
index a2bacd348161..4829f9135a02 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -44,6 +44,45 @@ struct vmentry_failure {
unsigned long flags;
};
+/*
+ * Exit Qualifications for entry failure during or after loading guest state
+ */
+#define ENTRY_FAIL_DEFAULT 0
+#define ENTRY_FAIL_PDPTE 2
+#define ENTRY_FAIL_NMI 3
+#define ENTRY_FAIL_VMCS_LINK_PTR 4
+
+/*
+ * VM-instruction error numbers
+ */
+enum vm_instruction_error_number {
+ VMXERR_VMCALL_IN_VMX_ROOT_OPERATION = 1,
+ VMXERR_VMCLEAR_INVALID_ADDRESS = 2,
+ VMXERR_VMCLEAR_VMXON_POINTER = 3,
+ VMXERR_VMLAUNCH_NONCLEAR_VMCS = 4,
+ VMXERR_VMRESUME_NONLAUNCHED_VMCS = 5,
+ VMXERR_VMRESUME_AFTER_VMXOFF = 6,
+ VMXERR_ENTRY_INVALID_CONTROL_FIELD = 7,
+ VMXERR_ENTRY_INVALID_HOST_STATE_FIELD = 8,
+ VMXERR_VMPTRLD_INVALID_ADDRESS = 9,
+ VMXERR_VMPTRLD_VMXON_POINTER = 10,
+ VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID = 11,
+ VMXERR_UNSUPPORTED_VMCS_COMPONENT = 12,
+ VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT = 13,
+ VMXERR_VMXON_IN_VMX_ROOT_OPERATION = 15,
+ VMXERR_ENTRY_INVALID_EXECUTIVE_VMCS_POINTER = 16,
+ VMXERR_ENTRY_NONLAUNCHED_EXECUTIVE_VMCS = 17,
+ VMXERR_ENTRY_EXECUTIVE_VMCS_POINTER_NOT_VMXON_POINTER = 18,
+ VMXERR_VMCALL_NONCLEAR_VMCS = 19,
+ VMXERR_VMCALL_INVALID_VM_EXIT_CONTROL_FIELDS = 20,
+ VMXERR_VMCALL_INCORRECT_MSEG_REVISION_ID = 22,
+ VMXERR_VMXOFF_UNDER_DUAL_MONITOR_TREATMENT_OF_SMIS_AND_SMM = 23,
+ VMXERR_VMCALL_INVALID_SMM_MONITOR_FEATURES = 24,
+ VMXERR_ENTRY_INVALID_VM_EXECUTION_CONTROL_FIELDS_IN_EXECUTIVE_VMCS = 25,
+ VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS = 26,
+ VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID = 28,
+};
+
struct vmx_test {
const char *name;
int (*init)(struct vmcs *vmcs);
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 5fd95706c418..a1400b937254 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -1816,6 +1816,42 @@ int into_exit_handler()
return VMX_TEST_VMEXIT;
}
+#define __create_invalid_vmcs_test(name, value, test) \
+ static int invalid_##name##_init() \
+ { \
+ vmcs_write(name, value); \
+ return VMX_TEST_START; \
+ } \
+ static int invalid_##name##_entry_failure(struct vmentry_failure *failure) \
+ { \
+ report("VM entry failure on invalid "#name, test); \
+ return VMX_TEST_VMEXIT; \
+ }
+
+#define create_invalid_host_vmcs_test(name, value, error) \
+ __create_invalid_vmcs_test(name, value, failure->early && \
+ vmcs_read(VMX_INST_ERROR) == error)
+
+#define create_invalid_guest_vmcs_test(name, value, reason, qualification) \
+ __create_invalid_vmcs_test(name, value, !failure->early && \
+ vmcs_read(EXI_REASON) == (reason | VMX_ENTRY_FAILURE) && \
+ vmcs_read(EXI_QUALIFICATION) == qualification)
+
+#define test_invalid_vmcs(name) \
+ { "invalid "#name, invalid_##name##_init, NULL, NULL, NULL, {0}, \
+ invalid_##name##_entry_failure }
+
+#define C create_invalid_host_vmcs_test
+C(HOST_EFER, -1ull, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD)
+#undef C
+
+#define C create_invalid_guest_vmcs_test
+C(VMCS_LINK_PTR, 1, VMX_FAIL_STATE, ENTRY_FAIL_VMCS_LINK_PTR)
+C(GUEST_CR0, -1ull, VMX_FAIL_STATE, ENTRY_FAIL_DEFAULT)
+C(GUEST_CR4, -1ull, VMX_FAIL_STATE, ENTRY_FAIL_DEFAULT)
+C(GUEST_EFER, -1ull, VMX_FAIL_STATE, ENTRY_FAIL_DEFAULT)
+#undef C
+
/* name/init/guest_main/exit_handler/syscall_handler/guest_regs */
struct vmx_test vmx_tests[] = {
{ "null", NULL, basic_guest_main, basic_exit_handler, NULL, {0} },
@@ -1845,5 +1881,10 @@ struct vmx_test vmx_tests[] = {
disable_rdtscp_exit_handler, NULL, {0} },
{ "int3", int3_init, int3_guest_main, int3_exit_handler, NULL, {0} },
{ "into", into_init, into_guest_main, into_exit_handler, NULL, {0} },
+ test_invalid_vmcs(VMCS_LINK_PTR),
+ test_invalid_vmcs(GUEST_CR0),
+ test_invalid_vmcs(GUEST_CR4),
+ test_invalid_vmcs(GUEST_EFER),
+ test_invalid_vmcs(HOST_EFER),
{ NULL, NULL, NULL, NULL, NULL, {0} },
};
--
2.11.0
next reply other threads:[~2016-12-21 20:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-21 20:26 Radim Krčmář [this message]
2016-12-22 10:00 ` [kvm-unit-tests PATCH] x86: vmx: test invalid vmcs Paolo Bonzini
2016-12-22 18:50 ` Radim Krčmář
2016-12-27 11:17 ` Andrew Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161221202604.24248-1-rkrcmar@redhat.com \
--to=rkrcmar@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox