Skip to content

Commit 9fc3402

Browse files
yamahatabonzini
authored andcommitted
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>
1 parent 081385d commit 9fc3402

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

arch/x86/kvm/vmx/tdx.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,7 @@ bool tdx_has_emulated_msr(u32 index)
20652065
case MSR_MISC_FEATURES_ENABLES:
20662066
case MSR_IA32_APICBASE:
20672067
case MSR_EFER:
2068+
case MSR_IA32_FEAT_CTL:
20682069
case MSR_IA32_MCG_CAP:
20692070
case MSR_IA32_MCG_STATUS:
20702071
case MSR_IA32_MCG_CTL:
@@ -2097,26 +2098,53 @@ bool tdx_has_emulated_msr(u32 index)
20972098

20982099
static bool tdx_is_read_only_msr(u32 index)
20992100
{
2100-
return index == MSR_IA32_APICBASE || index == MSR_EFER;
2101+
return index == MSR_IA32_APICBASE || index == MSR_EFER ||
2102+
index == MSR_IA32_FEAT_CTL;
21012103
}
21022104

21032105
int tdx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
21042106
{
2105-
if (!tdx_has_emulated_msr(msr->index))
2106-
return 1;
2107+
switch (msr->index) {
2108+
case MSR_IA32_FEAT_CTL:
2109+
/*
2110+
* MCE and MCA are advertised via cpuid. Guest kernel could
2111+
* check if LMCE is enabled or not.
2112+
*/
2113+
msr->data = FEAT_CTL_LOCKED;
2114+
if (vcpu->arch.mcg_cap & MCG_LMCE_P)
2115+
msr->data |= FEAT_CTL_LMCE_ENABLED;
2116+
return 0;
2117+
case MSR_IA32_MCG_EXT_CTL:
2118+
if (!msr->host_initiated && !(vcpu->arch.mcg_cap & MCG_LMCE_P))
2119+
return 1;
2120+
msr->data = vcpu->arch.mcg_ext_ctl;
2121+
return 0;
2122+
default:
2123+
if (!tdx_has_emulated_msr(msr->index))
2124+
return 1;
21072125

2108-
return kvm_get_msr_common(vcpu, msr);
2126+
return kvm_get_msr_common(vcpu, msr);
2127+
}
21092128
}
21102129

21112130
int tdx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
21122131
{
2113-
if (tdx_is_read_only_msr(msr->index))
2114-
return 1;
2132+
switch (msr->index) {
2133+
case MSR_IA32_MCG_EXT_CTL:
2134+
if ((!msr->host_initiated && !(vcpu->arch.mcg_cap & MCG_LMCE_P)) ||
2135+
(msr->data & ~MCG_EXT_CTL_LMCE_EN))
2136+
return 1;
2137+
vcpu->arch.mcg_ext_ctl = msr->data;
2138+
return 0;
2139+
default:
2140+
if (tdx_is_read_only_msr(msr->index))
2141+
return 1;
21152142

2116-
if (!tdx_has_emulated_msr(msr->index))
2117-
return 1;
2143+
if (!tdx_has_emulated_msr(msr->index))
2144+
return 1;
21182145

2119-
return kvm_set_msr_common(vcpu, msr);
2146+
return kvm_set_msr_common(vcpu, msr);
2147+
}
21202148
}
21212149

21222150
static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd)

0 commit comments

Comments
 (0)