mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
KVM: TDX: Enable guest access to LMCE related MSRs
Allow TDX guest to configure LMCE (Local Machine Check Event) by handling MSR IA32_FEAT_CTL and IA32_MCG_EXT_CTL. MCE and MCA are advertised via cpuid based on the TDX module spec. Guest kernel can access IA32_FEAT_CTL to check whether LMCE is opted-in by the platform or not. If LMCE is opted-in by the platform, guest kernel can access IA32_MCG_EXT_CTL to enable/disable LMCE. Handle MSR IA32_FEAT_CTL and IA32_MCG_EXT_CTL for TDX guests to avoid failure when a guest accesses them with TDG.VP.VMCALL<MSR> on #VE. E.g., Linux guest will treat the failure as a #GP(0). Userspace VMM may not opt-in LMCE by default, e.g., QEMU disables it by default, "-cpu lmce=on" is needed in QEMU command line to opt-in it. Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> [binbin: rework changelog] Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Message-ID: <20250227012021.1778144-11-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
081385dbc6
commit
9fc3402a20
|
|
@ -2065,6 +2065,7 @@ bool tdx_has_emulated_msr(u32 index)
|
|||
case MSR_MISC_FEATURES_ENABLES:
|
||||
case MSR_IA32_APICBASE:
|
||||
case MSR_EFER:
|
||||
case MSR_IA32_FEAT_CTL:
|
||||
case MSR_IA32_MCG_CAP:
|
||||
case MSR_IA32_MCG_STATUS:
|
||||
case MSR_IA32_MCG_CTL:
|
||||
|
|
@ -2097,26 +2098,53 @@ bool tdx_has_emulated_msr(u32 index)
|
|||
|
||||
static bool tdx_is_read_only_msr(u32 index)
|
||||
{
|
||||
return index == MSR_IA32_APICBASE || index == MSR_EFER;
|
||||
return index == MSR_IA32_APICBASE || index == MSR_EFER ||
|
||||
index == MSR_IA32_FEAT_CTL;
|
||||
}
|
||||
|
||||
int tdx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
{
|
||||
if (!tdx_has_emulated_msr(msr->index))
|
||||
return 1;
|
||||
switch (msr->index) {
|
||||
case MSR_IA32_FEAT_CTL:
|
||||
/*
|
||||
* MCE and MCA are advertised via cpuid. Guest kernel could
|
||||
* check if LMCE is enabled or not.
|
||||
*/
|
||||
msr->data = FEAT_CTL_LOCKED;
|
||||
if (vcpu->arch.mcg_cap & MCG_LMCE_P)
|
||||
msr->data |= FEAT_CTL_LMCE_ENABLED;
|
||||
return 0;
|
||||
case MSR_IA32_MCG_EXT_CTL:
|
||||
if (!msr->host_initiated && !(vcpu->arch.mcg_cap & MCG_LMCE_P))
|
||||
return 1;
|
||||
msr->data = vcpu->arch.mcg_ext_ctl;
|
||||
return 0;
|
||||
default:
|
||||
if (!tdx_has_emulated_msr(msr->index))
|
||||
return 1;
|
||||
|
||||
return kvm_get_msr_common(vcpu, msr);
|
||||
return kvm_get_msr_common(vcpu, msr);
|
||||
}
|
||||
}
|
||||
|
||||
int tdx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
{
|
||||
if (tdx_is_read_only_msr(msr->index))
|
||||
return 1;
|
||||
switch (msr->index) {
|
||||
case MSR_IA32_MCG_EXT_CTL:
|
||||
if ((!msr->host_initiated && !(vcpu->arch.mcg_cap & MCG_LMCE_P)) ||
|
||||
(msr->data & ~MCG_EXT_CTL_LMCE_EN))
|
||||
return 1;
|
||||
vcpu->arch.mcg_ext_ctl = msr->data;
|
||||
return 0;
|
||||
default:
|
||||
if (tdx_is_read_only_msr(msr->index))
|
||||
return 1;
|
||||
|
||||
if (!tdx_has_emulated_msr(msr->index))
|
||||
return 1;
|
||||
if (!tdx_has_emulated_msr(msr->index))
|
||||
return 1;
|
||||
|
||||
return kvm_set_msr_common(vcpu, msr);
|
||||
return kvm_set_msr_common(vcpu, msr);
|
||||
}
|
||||
}
|
||||
|
||||
static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user