- 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 <andi.kl...@intel.com> Reviewed-by: Tony Luck <tony.l...@intel.com> Tested-by: Gong Chen <gong.c...@intel.com> Signed-off-by: Ashok Raj <ashok....@intel.com> --- 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); -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html