From patchwork Wed Dec 9 19:57:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashok Raj X-Patchwork-Id: 7811471 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 391A19F39B for ; Wed, 9 Dec 2015 18:57:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 30AA9204AF for ; Wed, 9 Dec 2015 18:57:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0640E204A2 for ; Wed, 9 Dec 2015 18:57:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753653AbbLIS5T (ORCPT ); Wed, 9 Dec 2015 13:57:19 -0500 Received: from mga02.intel.com ([134.134.136.20]:60069 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753464AbbLIS5R (ORCPT ); Wed, 9 Dec 2015 13:57:17 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 09 Dec 2015 10:57:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,405,1444719600"; d="scan'208";a="868242145" Received: from otc-brkl-03.jf.intel.com ([10.54.39.10]) by orsmga002.jf.intel.com with ESMTP; 09 Dec 2015 10:57:17 -0800 From: Ashok Raj To: kvm@vger.kernel.org Cc: Ashok Raj , Gleb Natapov , Paolo Bonzini , qemu-devel@nongnu.org, linux-kernel@vger.kernel.org, Boris Petkov , Tony Luck , Andi Kleen Subject: [Patch V0] This patch adds some support required for KVM in order to support LMCE. Date: Wed, 9 Dec 2015 14:57:08 -0500 Message-Id: <1449691029-15525-1-git-send-email-ashok.raj@intel.com> X-Mailer: git-send-email 2.4.3 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 - Add support for MSR_IA32_MCG_EXT_CTL - Add MCG_LMCE_P to KVM_MCE_CAP_SUPPORTED - Changes to IA32_FEATURE_CONTROL, allow this MSR to be defined just not for nested VMM, but now its required for Local MCE. Reviewed-by: Andi Kleen Reviewed-by: Tony Luck Tested-by: Gong Chen Signed-off-by: Ashok Raj --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/vmx.c | 26 +++++++++++++++++++++----- arch/x86/kvm/x86.c | 17 ++++++++++++++++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 30cfd64..6940141 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -525,6 +525,7 @@ struct kvm_vcpu_arch { u64 mcg_cap; u64 mcg_status; u64 mcg_ctl; + u64 mcg_ext_ctl; u64 *mce_banks; /* Cache MMIO info */ diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 87acc52..c2ce9f4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2747,6 +2747,20 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) return 0; } +bool can_feature_control_exist(struct kvm_vcpu *vcpu) +{ + /* + * There are some features that require BIOS enabling. + * In such cases BIOS is supposed to set this bit and indicate + * the feature is enabled and available to the OS. + * Local Machine Check Exception (LMCE) is one such feature. + */ + if (vcpu->arch.mcg_cap & MCG_LMCE_P) + return true; + + return (nested_vmx_allowed(vcpu)); +} + /* * Reads an msr value (of 'msr_index') into 'pdata'. * Returns 0 on success, non-0 otherwise. @@ -2789,9 +2803,11 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = vmcs_read64(GUEST_BNDCFGS); break; case MSR_IA32_FEATURE_CONTROL: - if (!nested_vmx_allowed(vcpu)) + if (can_feature_control_exist(vcpu)) + msr_info->data = + to_vmx(vcpu)->nested.msr_ia32_feature_control; + else return 1; - msr_info->data = to_vmx(vcpu)->nested.msr_ia32_feature_control; break; case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: if (!nested_vmx_allowed(vcpu)) @@ -2882,9 +2898,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) ret = kvm_set_msr_common(vcpu, msr_info); break; case MSR_IA32_FEATURE_CONTROL: - if (!nested_vmx_allowed(vcpu) || - (to_vmx(vcpu)->nested.msr_ia32_feature_control & - FEATURE_CONTROL_LOCKED && !msr_info->host_initiated)) + if ((can_feature_control_exist(vcpu) == false) || + ((to_vmx(vcpu)->nested.msr_ia32_feature_control & + FEATURE_CONTROL_LOCKED) && !msr_info->host_initiated)) return 1; vmx->nested.msr_ia32_feature_control = data; if (msr_info->host_initiated && data == 0) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 00462bd..0da3871 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -70,7 +70,7 @@ #define MAX_IO_MSRS 256 #define KVM_MAX_MCE_BANKS 32 -#define KVM_MCE_CAP_SUPPORTED (MCG_CTL_P | MCG_SER_P) +#define KVM_MCE_CAP_SUPPORTED (MCG_CTL_P | MCG_SER_P | MCG_LMCE_P) #define emul_to_vcpu(ctxt) \ container_of(ctxt, struct kvm_vcpu, arch.emulate_ctxt) @@ -974,6 +974,7 @@ static u32 emulated_msrs[] = { MSR_IA32_MISC_ENABLE, MSR_IA32_MCG_STATUS, MSR_IA32_MCG_CTL, + MSR_IA32_MCG_EXT_CTL, MSR_IA32_SMBASE, }; @@ -1913,6 +1914,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data) return -1; vcpu->arch.mcg_ctl = data; break; + case MSR_IA32_MCG_EXT_CTL: + if (!(mcg_cap & MCG_LMCE_P)) + return 1; + if (data != 0 && data != 0x1) + return -1; + vcpu->arch.mcg_ext_ctl = data; + break; default: if (msr >= MSR_IA32_MC0_CTL && msr < MSR_IA32_MCx_CTL(bank_num)) { @@ -2170,6 +2178,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_MCG_CTL: case MSR_IA32_MCG_STATUS: + case MSR_IA32_MCG_EXT_CTL: case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1: return set_msr_mce(vcpu, msr, data); @@ -2266,6 +2275,11 @@ static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) return 1; data = vcpu->arch.mcg_ctl; break; + case MSR_IA32_MCG_EXT_CTL: + if (!(mcg_cap & MCG_LMCE_P)) + return 1; + data = vcpu->arch.mcg_ext_ctl; + break; case MSR_IA32_MCG_STATUS: data = vcpu->arch.mcg_status; break; @@ -2384,6 +2398,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_P5_MC_TYPE: case MSR_IA32_MCG_CAP: case MSR_IA32_MCG_CTL: + case MSR_IA32_MCG_EXT_CTL: case MSR_IA32_MCG_STATUS: case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1: return get_msr_mce(vcpu, msr_info->index, &msr_info->data);