From patchwork Mon Dec 16 09:57:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 3352751 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 C32B2C0D4A for ; Mon, 16 Dec 2013 09:58:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A9FD020378 for ; Mon, 16 Dec 2013 09:57:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 83BF620270 for ; Mon, 16 Dec 2013 09:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753229Ab3LPJ5p (ORCPT ); Mon, 16 Dec 2013 04:57:45 -0500 Received: from goliath.siemens.de ([192.35.17.28]:34518 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753212Ab3LPJ5n (ORCPT ); Mon, 16 Dec 2013 04:57:43 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.13.6/8.13.6) with ESMTP id rBG9vaBl002998; Mon, 16 Dec 2013 10:57:36 +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 rBG9vTCF007502; Mon, 16 Dec 2013 10:57:36 +0100 From: Jan Kiszka To: Gleb Natapov , Paolo Bonzini Cc: kvm , Arthur Chunqi Li Subject: [PATCH 13/15] VMX: Rework and enhance initial feature detection/enabling Date: Mon, 16 Dec 2013 10:57:26 +0100 Message-Id: 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 So far we ran into an unhandled GP when VMX was unavailable. Change the logic to handle this gracefully. Rework test_vmx_capability to test_vmx_feature_control which not only enables VMX in the feature control MSR but also test related error behavior. Signed-off-by: Jan Kiszka --- x86/vmx.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/x86/vmx.c b/x86/vmx.c index f6f2f59..fe950e6 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -539,22 +539,74 @@ static void init_vmx(void) memset(guest_syscall_stack, 0, PAGE_SIZE); } -static int test_vmx_capability(void) +static bool exception; +static void *exception_return; + +static void exception_handler(struct ex_regs *regs) +{ + exception = true; + regs->rip = (u64)exception_return; +} + +static int test_for_exception(unsigned int ex, void (*func)(void)) +{ + handle_exception(ex, exception_handler); + exception = false; + func(); + handle_exception(ex, NULL); + return exception; +} + +static void do_vmxon_off(void) +{ + exception_return = &&resume; + barrier(); + vmx_on(); + vmx_off(); +resume: + return; +} + +static void do_write_feature_control(void) +{ + exception_return = &&resume; + barrier(); + wrmsr(MSR_IA32_FEATURE_CONTROL, 0); +resume: + return; +} + +static int test_vmx_feature_control(void) { - struct cpuid r; - u64 ret1, ret2; u64 ia32_feature_control; - r = cpuid(1); - ret1 = ((r.c) >> 5) & 1; + bool vmx_enabled; + ia32_feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL); - ret2 = ((ia32_feature_control & 0x5) == 0x5); - if ((!ret2) && ((ia32_feature_control & 0x1) == 0)) { - wrmsr(MSR_IA32_FEATURE_CONTROL, 0x5); - ia32_feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL); - ret2 = ((ia32_feature_control & 0x5) == 0x5); + vmx_enabled = ((ia32_feature_control & 0x5) == 0x5); + if ((ia32_feature_control & 0x5) == 0x5) { + printf("VMX enabled and locked by BIOS\n"); + return 0; + } else if (ia32_feature_control & 0x1) { + printf("ERROR: VMX locked out by BIOS!?\n"); + return 1; } - report("test vmx capability", ret1 & ret2); - return !(ret1 & ret2); + + wrmsr(MSR_IA32_FEATURE_CONTROL, 0); + report("test vmxon with FEATURE_CONTROL cleared", + test_for_exception(GP_VECTOR, &do_vmxon_off)); + + wrmsr(MSR_IA32_FEATURE_CONTROL, 0x4); + report("test vmxon without FEATURE_CONTROL lock", + test_for_exception(GP_VECTOR, &do_vmxon_off)); + + wrmsr(MSR_IA32_FEATURE_CONTROL, 0x5); + vmx_enabled = ((rdmsr(MSR_IA32_FEATURE_CONTROL) & 0x5) == 0x5); + report("test enable VMX in FEATURE_CONTROL", vmx_enabled); + + report("test FEATURE_CONTROL lock bit", + test_for_exception(GP_VECTOR, &do_write_feature_control)); + + return !vmx_enabled; } static int test_vmxon(void) @@ -758,11 +810,13 @@ int main(void) fails = tests = 0; hypercall_field = 0; - if (test_vmx_capability() != 0) { - printf("ERROR : vmx not supported, check +vmx option\n"); + if (!(cpuid(1).c & (1 << 5))) { + printf("WARNING: vmx not supported, add '-cpu host'\n"); goto exit; } init_vmx(); + if (test_vmx_feature_control() != 0) + goto exit; /* Set basic test ctxt the same as "null" */ current = &vmx_tests[0]; if (test_vmxon() != 0)