diff mbox

[09/15] VMX: Let init handler decide about test start

Message ID 882f1f1c8901989851da4a6538630a04a6c218a0.1387187847.git.jan.kiszka@siemens.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka Dec. 16, 2013, 9:57 a.m. UTC
If some feature is not existing and, thus, a test case is not able to
run, already report this back from the init handler.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 x86/vmx.c       |  4 ++--
 x86/vmx.h       |  3 ++-
 x86/vmx_tests.c | 52 ++++++++++++++++++++++++++--------------------------
 3 files changed, 30 insertions(+), 29 deletions(-)
diff mbox

Patch

diff --git a/x86/vmx.c b/x86/vmx.c
index 4c463fd..2928e70 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -731,8 +731,8 @@  static int test_run(struct vmx_test *test)
 	init_vmcs(&(test->vmcs));
 	/* Directly call test->init is ok here, init_vmcs has done
 	   vmcs init, vmclear and vmptrld*/
-	if (test->init)
-		test->init(test->vmcs);
+	if (test->init && test->init(test->vmcs) != VMX_TEST_START)
+		return 0;
 	test->exits = 0;
 	current = test;
 	regs = test->guest_regs;
diff --git a/x86/vmx.h b/x86/vmx.h
index 59d627a..9d3b942 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -32,7 +32,7 @@  struct regs {
 
 struct vmx_test {
 	const char *name;
-	void (*init)(struct vmcs *vmcs);
+	int (*init)(struct vmcs *vmcs);
 	void (*guest_main)();
 	int (*exit_handler)();
 	void (*syscall_handler)(u64 syscall_no);
@@ -434,6 +434,7 @@  enum Ctrl1 {
 #define VMX_IO_PORT_MASK		0xFFFF0000
 #define VMX_IO_PORT_SHIFT		16
 
+#define VMX_TEST_START			0
 #define VMX_TEST_VMEXIT			1
 #define VMX_TEST_EXIT			2
 #define VMX_TEST_RESUME			3
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index d330d5c..ae6087c 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -16,7 +16,6 @@  volatile u32 stage;
 void *io_bitmap_a, *io_bitmap_b;
 u16 ioport;
 
-bool init_fail;
 unsigned long *pml4;
 u64 eptp;
 void *data_page1, *data_page2;
@@ -119,28 +118,26 @@  u32 preempt_scale;
 volatile unsigned long long tsc_val;
 volatile u32 preempt_val;
 
-void preemption_timer_init()
+int preemption_timer_init()
 {
-	u32 ctrl_pin;
-
-	ctrl_pin = vmcs_read(PIN_CONTROLS) | PIN_PREEMPT;
-	ctrl_pin &= ctrl_pin_rev.clr;
-	vmcs_write(PIN_CONTROLS, ctrl_pin);
+	if (!(ctrl_pin_rev.clr & PIN_PREEMPT)) {
+		printf("\tPreemption timer is not supported\n");
+		return VMX_TEST_EXIT;
+	}
+	vmcs_write(PIN_CONTROLS, vmcs_read(PIN_CONTROLS) | PIN_PREEMPT);
 	preempt_val = 10000000;
 	vmcs_write(PREEMPT_TIMER_VALUE, preempt_val);
 	preempt_scale = rdmsr(MSR_IA32_VMX_MISC) & 0x1F;
 
 	if (!(ctrl_exit_rev.clr & EXI_SAVE_PREEMPT))
 		printf("\tSave preemption value is not supported\n");
+
+	return VMX_TEST_START;
 }
 
 void preemption_timer_main()
 {
 	tsc_val = rdtsc();
-	if (!(ctrl_pin_rev.clr & PIN_PREEMPT)) {
-		printf("\tPreemption timer is not supported\n");
-		return;
-	}
 	if (ctrl_exit_rev.clr & EXI_SAVE_PREEMPT) {
 		set_stage(0);
 		vmcall();
@@ -223,7 +220,7 @@  void msr_bmp_init()
 	vmcs_write(MSR_BITMAP, (u64)msr_bitmap);
 }
 
-static void test_ctrl_pat_init()
+static int test_ctrl_pat_init()
 {
 	u64 ctrl_ent;
 	u64 ctrl_exi;
@@ -236,6 +233,7 @@  static void test_ctrl_pat_init()
 	ia32_pat = rdmsr(MSR_IA32_CR_PAT);
 	vmcs_write(GUEST_PAT, 0x0);
 	vmcs_write(HOST_PAT, ia32_pat);
+	return VMX_TEST_START;
 }
 
 static void test_ctrl_pat_main()
@@ -301,7 +299,7 @@  static int test_ctrl_pat_exit_handler()
 	return VMX_TEST_VMEXIT;
 }
 
-static void test_ctrl_efer_init()
+static int test_ctrl_efer_init()
 {
 	u64 ctrl_ent;
 	u64 ctrl_exi;
@@ -314,6 +312,7 @@  static void test_ctrl_efer_init()
 	ia32_efer = rdmsr(MSR_EFER);
 	vmcs_write(GUEST_EFER, ia32_efer ^ EFER_NX);
 	vmcs_write(HOST_EFER, ia32_efer ^ EFER_NX);
+	return VMX_TEST_START;
 }
 
 static void test_ctrl_efer_main()
@@ -589,7 +588,7 @@  static int cr_shadowing_exit_handler()
 	return VMX_TEST_VMEXIT;
 }
 
-static void iobmp_init()
+static int iobmp_init()
 {
 	u32 ctrl_cpu0;
 
@@ -603,6 +602,7 @@  static void iobmp_init()
 	vmcs_write(CPU_EXEC_CTRL0, ctrl_cpu0);
 	vmcs_write(IO_BITMAP_A, (u64)io_bitmap_a);
 	vmcs_write(IO_BITMAP_B, (u64)io_bitmap_b);
+	return VMX_TEST_START;
 }
 
 static void iobmp_main()
@@ -814,7 +814,7 @@  static struct insn_table insn_table[] = {
 	{NULL},
 };
 
-static void insn_intercept_init()
+static int insn_intercept_init()
 {
 	u32 ctrl_cpu[2];
 
@@ -827,6 +827,7 @@  static void insn_intercept_init()
 	ctrl_cpu[1] |= CPU_WBINVD | CPU_RDRAND;
 	ctrl_cpu[1] &= ctrl_cpu_rev[1].clr;
 	vmcs_write(CPU_EXEC_CTRL1, ctrl_cpu[1]);
+	return VMX_TEST_START;
 }
 
 static void insn_intercept_main()
@@ -926,12 +927,17 @@  static int setup_ept()
 	return 0;
 }
 
-static void ept_init()
+static int ept_init()
 {
 	unsigned long base_addr1, base_addr2;
 	u32 ctrl_cpu[2];
 
-	init_fail = false;
+	if (!(ctrl_cpu_rev[0].clr & CPU_SECONDARY) ||
+	    !(ctrl_cpu_rev[1].clr & CPU_EPT)) {
+		printf("\tEPT is not supported");
+		return VMX_TEST_EXIT;
+	}
+
 	ctrl_cpu[0] = vmcs_read(CPU_EXEC_CTRL0);
 	ctrl_cpu[1] = vmcs_read(CPU_EXEC_CTRL1);
 	ctrl_cpu[0] = (ctrl_cpu[0] | CPU_SECONDARY)
@@ -941,7 +947,7 @@  static void ept_init()
 	vmcs_write(CPU_EXEC_CTRL0, ctrl_cpu[0]);
 	vmcs_write(CPU_EXEC_CTRL1, ctrl_cpu[1]);
 	if (setup_ept())
-		init_fail = true;
+		return VMX_TEST_EXIT;
 	data_page1 = alloc_page();
 	data_page2 = alloc_page();
 	memset(data_page1, 0x0, PAGE_SIZE);
@@ -954,20 +960,14 @@  static void ept_init()
 			    EPT_WA | EPT_RA | EPT_EA) ||
 	    setup_ept_range(pml4, base_addr2, base_addr2 + PAGE_SIZE_2M, 0, 0,
 			    EPT_WA | EPT_RA | EPT_EA))
-		init_fail = true;
+		return VMX_TEST_EXIT;
 	install_ept(pml4, (unsigned long)data_page1, (unsigned long)data_page2,
 			EPT_RA | EPT_WA | EPT_EA);
+	return VMX_TEST_START;
 }
 
 static void ept_main()
 {
-	if (init_fail)
-		return;
-	if (!(ctrl_cpu_rev[0].clr & CPU_SECONDARY) ||
-	    !(ctrl_cpu_rev[1].clr & CPU_EPT)) {
-		printf("\tEPT is not supported");
-		return;
-	}
 	set_stage(0);
 	if (*((u32 *)data_page2) != MAGIC_VAL_1 ||
 			*((u32 *)data_page1) != MAGIC_VAL_1)