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@xxxxxxxxxxx> --- x86/vmx.c | 4 ++-- x86/vmx.h | 3 ++- x86/vmx_tests.c | 52 ++++++++++++++++++++++++++-------------------------- 3 files changed, 30 insertions(+), 29 deletions(-) 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) -- 1.8.1.1.298.ge7eed54 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html