diff mbox

[kvm-unit-tests,10/32] x86: vmcs lifecycle test

Message ID 20170421005004.137260-11-dmatlack@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Matlack April 21, 2017, 12:49 a.m. UTC
This test VMCLEARs and VMPTRLDs two VMCS's to put each VMCS into different
states of active/not-active and current/not-current and then verifies
that VMREAD/VMWRITE to the current VMCS work correctly.

Signed-off-by: David Matlack <dmatlack@google.com>
---
 x86/unittests.cfg |  6 ++++++
 x86/vmx.c         | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)
diff mbox

Patch

diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 7973f2f62d26..0f2c94fb548d 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -236,6 +236,12 @@  extra_params = -cpu host,+vmx -append test_vmwrite_vmread
 arch = x86_64
 groups = vmx
 
+[vmx_test_vmcs_lifecycle]
+file = vmx.flat
+extra_params = -cpu host,+vmx -append test_vmcs_lifecycle
+arch = x86_64
+groups = vmx
+
 [vmx_test_vmx_caps]
 file = vmx.flat
 extra_params = -cpu host,+vmx -append test_vmx_caps
diff --git a/x86/vmx.c b/x86/vmx.c
index 47404fbbd782..7daa1d110c82 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -300,6 +300,64 @@  void test_vmwrite_vmread(void)
 	free_page(vmcs);
 }
 
+void test_vmcs_lifecycle(void)
+{
+	struct vmcs *vmcs[2] = {};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vmcs); i++) {
+		vmcs[i] = alloc_page();
+		memset(vmcs[i], 0, PAGE_SIZE);
+		vmcs[i]->revision_id = basic.revision;
+	}
+
+#define VMPTRLD(_i) do { \
+	assert(_i < ARRAY_SIZE(vmcs)); \
+	assert(!make_vmcs_current(vmcs[_i])); \
+	printf("VMPTRLD VMCS%d\n", (_i)); \
+} while (0)
+
+#define VMCLEAR(_i) do { \
+	assert(_i < ARRAY_SIZE(vmcs)); \
+	assert(!vmcs_clear(vmcs[_i])); \
+	printf("VMCLEAR VMCS%d\n", (_i)); \
+} while (0)
+
+	VMCLEAR(0);
+	VMPTRLD(0);
+	set_all_vmcs_fields(0);
+	report("current:VMCS0 active:[VMCS0]", check_all_vmcs_fields(0));
+
+	VMCLEAR(0);
+	VMPTRLD(0);
+	report("current:VMCS0 active:[VMCS0]", check_all_vmcs_fields(0));
+
+	VMCLEAR(1);
+	report("current:VMCS0 active:[VMCS0]", check_all_vmcs_fields(0));
+
+	VMPTRLD(1);
+	set_all_vmcs_fields(1);
+	report("current:VMCS1 active:[VMCS0,VCMS1]", check_all_vmcs_fields(1));
+
+	VMPTRLD(0);
+	report("current:VMCS0 active:[VMCS0,VCMS1]", check_all_vmcs_fields(0));
+	VMPTRLD(1);
+	report("current:VMCS1 active:[VMCS0,VCMS1]", check_all_vmcs_fields(1));
+	VMPTRLD(1);
+	report("current:VMCS1 active:[VMCS0,VCMS1]", check_all_vmcs_fields(1));
+
+	VMCLEAR(0);
+	report("current:VMCS1 active:[VCMS1]", check_all_vmcs_fields(1));
+
+	for (i = 0; i < ARRAY_SIZE(vmcs); i++) {
+		VMCLEAR(i);
+		free_page(vmcs[i]);
+	}
+
+#undef VMPTRLD
+#undef VMCLEAR
+}
+
 void vmx_set_test_stage(u32 s)
 {
 	barrier();
@@ -1472,6 +1530,8 @@  int main(int argc, const char *argv[])
 		test_vmptrst();
 	if (test_wanted("test_vmwrite_vmread", argv, argc))
 		test_vmwrite_vmread();
+	if (test_wanted("test_vmcs_lifecycle", argv, argc))
+		test_vmcs_lifecycle();
 
 	init_vmcs(&vmcs_root);
 	if (vmx_run()) {