From patchwork Mon Dec 16 09:57:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 3352791 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 32035C0D4A for ; Mon, 16 Dec 2013 09:58:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DE0D220270 for ; Mon, 16 Dec 2013 09:58:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 97ED920303 for ; Mon, 16 Dec 2013 09:58:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752188Ab3LPJ56 (ORCPT ); Mon, 16 Dec 2013 04:57:58 -0500 Received: from david.siemens.de ([192.35.17.14]:28129 "EHLO david.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753209Ab3LPJ5m (ORCPT ); Mon, 16 Dec 2013 04:57:42 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by david.siemens.de (8.13.6/8.13.6) with ESMTP id rBG9vYRB025167; Mon, 16 Dec 2013 10:57:34 +0100 Received: from mchn199C.mchp.siemens.de.com ([146.254.78.38]) by mail1.siemens.de (8.14.3/8.14.3) with SMTP id rBG9vTCB007502; Mon, 16 Dec 2013 10:57:34 +0100 From: Jan Kiszka To: Gleb Natapov , Paolo Bonzini Cc: kvm , Arthur Chunqi Li Subject: [PATCH 09/15] VMX: Let init handler decide about test start Date: Mon, 16 Dec 2013 10:57:22 +0100 Message-Id: <882f1f1c8901989851da4a6538630a04a6c218a0.1387187847.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 1.8.1.1.298.ge7eed54 In-Reply-To: References: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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)