* [PATCH 0/2] Fix MSR_IA32_PLATFORM_ID access for TDX guests
@ 2026-04-28 2:47 Binbin Wu
2026-04-28 2:47 ` [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID Binbin Wu
2026-04-28 2:47 ` [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment Binbin Wu
0 siblings, 2 replies; 12+ messages in thread
From: Binbin Wu @ 2026-04-28 2:47 UTC (permalink / raw)
To: kvm, linux-kernel, x86
Cc: pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe,
vishal.l.verma, xiaoyao.li, chao.gao, binbin.wu
Since commit d8630b67ca1e ("x86/cpu: Add platform ID to CPU info
structure"), the Linux kernel reads MSR_IA32_PLATFORM_ID during CPU
init. This causes unchecked MSR access errors when running as a TDX
guest, because KVM doesn't include MSR_IA32_PLATFORM_ID in
tdx_has_emulated_msr().
On KVM side, this patch set adds MSR_IA32_PLATFORM_ID to
tdx_has_emulated_msr() so that KVM returns 0 for TDs reading this MSR,
consistent with how KVM already handles it for normal VMs.
Optionally, in order to provide back-compatibility for newer Linux guests
running on older KVM hosts without the fix, the second patch skips the
MSR_IA32_PLATFORM_ID read entirely when Linux is running in a
virtualized environment. This could be dropped if we think the fix on
KVM side is sufficient.
Binbin Wu (2):
KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID
x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment
arch/x86/kernel/cpu/microcode/core.c | 2 +-
arch/x86/kernel/cpu/microcode/intel.c | 4 ++++
arch/x86/kernel/cpu/microcode/internal.h | 5 +++++
arch/x86/kvm/vmx/tdx.c | 1 +
4 files changed, 11 insertions(+), 1 deletion(-)
base-commit: 39704f00f747aba3144289870b5fd8ac230a9aaf
--
2.46.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 2:47 [PATCH 0/2] Fix MSR_IA32_PLATFORM_ID access for TDX guests Binbin Wu @ 2026-04-28 2:47 ` Binbin Wu 2026-04-28 5:31 ` Xiaoyao Li ` (2 more replies) 2026-04-28 2:47 ` [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment Binbin Wu 1 sibling, 3 replies; 12+ messages in thread From: Binbin Wu @ 2026-04-28 2:47 UTC (permalink / raw) To: kvm, linux-kernel, x86 Cc: pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, xiaoyao.li, chao.gao, binbin.wu Add MSR_IA32_PLATFORM_ID to tdx_has_emulated_msr() so that TDs can read it. Linux kernel reads MSR_IA32_PLATFORM_ID during init since commit d8630b67ca1e ("x86/cpu: Add platform ID to CPU info structure"). KVM already supports this MSR on read for normal VMs by returning 0. Without support for this MSR, TDs get unchecked MSR access errors. unchecked MSR access error: RDMSR from 0x17 at rIP: 0xffffffffba38d6fc (intel_get_platform_id+0x7c/0xb0) Call Trace: <TASK> ? early_init_intel+0x28/0x2c0 ? early_cpu_init+0x9b/0x930 ? setup_arch+0xbf/0xbb0 ? _printk+0x6b/0x90 ? start_kernel+0x7f/0xaa0 ? x86_64_start_reservations+0x24/0x30 ? x86_64_start_kernel+0xda/0xe0 ? common_startup_64+0x13e/0x141 </TASK> Add MSR_IA32_PLATFORM_ID in tdx_has_emulated_msr() to allow TDs to read the MSR. MSR_IA32_PLATFORM_ID is read-only by hardware definition, i.e. KVM should never add it as writable, no need to add it in tdx_is_read_only_msr(). Fixes: dd50294f3e3c ("KVM: TDX: Implement callbacks for MSR operations") Reported-by: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> --- arch/x86/kvm/vmx/tdx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 04ce321ebdf3..812ad99b11e5 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -2094,6 +2094,7 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, bool tdx_has_emulated_msr(u32 index) { switch (index) { + case MSR_IA32_PLATFORM_ID: case MSR_IA32_UCODE_REV: case MSR_IA32_ARCH_CAPABILITIES: case MSR_IA32_POWER_CTL: -- 2.46.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 2:47 ` [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID Binbin Wu @ 2026-04-28 5:31 ` Xiaoyao Li 2026-04-28 11:44 ` Chao Gao 2026-04-28 18:49 ` Dave Hansen 2 siblings, 0 replies; 12+ messages in thread From: Xiaoyao Li @ 2026-04-28 5:31 UTC (permalink / raw) To: Binbin Wu, kvm, linux-kernel, x86 Cc: pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, chao.gao On 4/28/2026 10:47 AM, Binbin Wu wrote: > Add MSR_IA32_PLATFORM_ID to tdx_has_emulated_msr() so that TDs can read > it. > > Linux kernel reads MSR_IA32_PLATFORM_ID during init since commit > d8630b67ca1e ("x86/cpu: Add platform ID to CPU info structure"). KVM > already supports this MSR on read for normal VMs by returning 0. > Without support for this MSR, TDs get unchecked MSR access errors. > > unchecked MSR access error: RDMSR from 0x17 at rIP: 0xffffffffba38d6fc (intel_get_platform_id+0x7c/0xb0) > Call Trace: > <TASK> > ? early_init_intel+0x28/0x2c0 > ? early_cpu_init+0x9b/0x930 > ? setup_arch+0xbf/0xbb0 > ? _printk+0x6b/0x90 > ? start_kernel+0x7f/0xaa0 > ? x86_64_start_reservations+0x24/0x30 > ? x86_64_start_kernel+0xda/0xe0 > ? common_startup_64+0x13e/0x141 > </TASK> > > Add MSR_IA32_PLATFORM_ID in tdx_has_emulated_msr() to allow TDs to read > the MSR. MSR_IA32_PLATFORM_ID is read-only by hardware definition, i.e. > KVM should never add it as writable, no need to add it in > tdx_is_read_only_msr(). > > Fixes: dd50294f3e3c ("KVM: TDX: Implement callbacks for MSR operations") > Reported-by: Vishal Verma <vishal.l.verma@intel.com> > Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Nit: It would be helpful to add the info that read on this MSR from TDs always triggers #VE so that Linux guest will request emulation from KVM. > --- > arch/x86/kvm/vmx/tdx.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c > index 04ce321ebdf3..812ad99b11e5 100644 > --- a/arch/x86/kvm/vmx/tdx.c > +++ b/arch/x86/kvm/vmx/tdx.c > @@ -2094,6 +2094,7 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, > bool tdx_has_emulated_msr(u32 index) > { > switch (index) { > + case MSR_IA32_PLATFORM_ID: > case MSR_IA32_UCODE_REV: > case MSR_IA32_ARCH_CAPABILITIES: > case MSR_IA32_POWER_CTL: ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 2:47 ` [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID Binbin Wu 2026-04-28 5:31 ` Xiaoyao Li @ 2026-04-28 11:44 ` Chao Gao 2026-04-28 16:30 ` Sean Christopherson 2026-04-28 18:49 ` Dave Hansen 2 siblings, 1 reply; 12+ messages in thread From: Chao Gao @ 2026-04-28 11:44 UTC (permalink / raw) To: Binbin Wu Cc: kvm, linux-kernel, x86, pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, xiaoyao.li On Tue, Apr 28, 2026 at 10:47:45AM +0800, Binbin Wu wrote: >Add MSR_IA32_PLATFORM_ID to tdx_has_emulated_msr() so that TDs can read >it. > >Linux kernel reads MSR_IA32_PLATFORM_ID during init since commit >d8630b67ca1e ("x86/cpu: Add platform ID to CPU info structure"). KVM >already supports this MSR on read for normal VMs by returning 0. >Without support for this MSR, TDs get unchecked MSR access errors. > > unchecked MSR access error: RDMSR from 0x17 at rIP: 0xffffffffba38d6fc (intel_get_platform_id+0x7c/0xb0) > Call Trace: > <TASK> > ? early_init_intel+0x28/0x2c0 > ? early_cpu_init+0x9b/0x930 > ? setup_arch+0xbf/0xbb0 > ? _printk+0x6b/0x90 > ? start_kernel+0x7f/0xaa0 > ? x86_64_start_reservations+0x24/0x30 > ? x86_64_start_kernel+0xda/0xe0 > ? common_startup_64+0x13e/0x141 > </TASK> > >Add MSR_IA32_PLATFORM_ID in tdx_has_emulated_msr() to allow TDs to read >the MSR. MSR_IA32_PLATFORM_ID is read-only by hardware definition, i.e. >KVM should never add it as writable, no need to add it in >tdx_is_read_only_msr(). > >Fixes: dd50294f3e3c ("KVM: TDX: Implement callbacks for MSR operations") >Reported-by: Vishal Verma <vishal.l.verma@intel.com> >Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> >--- > arch/x86/kvm/vmx/tdx.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c >index 04ce321ebdf3..812ad99b11e5 100644 >--- a/arch/x86/kvm/vmx/tdx.c >+++ b/arch/x86/kvm/vmx/tdx.c >@@ -2094,6 +2094,7 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, > bool tdx_has_emulated_msr(u32 index) > { > switch (index) { >+ case MSR_IA32_PLATFORM_ID: > case MSR_IA32_UCODE_REV: > case MSR_IA32_ARCH_CAPABILITIES: > case MSR_IA32_POWER_CTL: This patch looks good to me. But the rule for which MSRs should be emulated by KVM for TDX is not very clear to me. Maybe we can document the rule here, if there is one. That would make it much easier to tell whether future issues like this are guest regressions or missing KVM handling. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 11:44 ` Chao Gao @ 2026-04-28 16:30 ` Sean Christopherson 2026-04-28 18:31 ` Edgecombe, Rick P 0 siblings, 1 reply; 12+ messages in thread From: Sean Christopherson @ 2026-04-28 16:30 UTC (permalink / raw) To: Chao Gao Cc: Binbin Wu, kvm, linux-kernel, x86, pbonzini, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, xiaoyao.li On Tue, Apr 28, 2026, Chao Gao wrote: > On Tue, Apr 28, 2026 at 10:47:45AM +0800, Binbin Wu wrote: > >Add MSR_IA32_PLATFORM_ID to tdx_has_emulated_msr() so that TDs can read > >it. > > > >Linux kernel reads MSR_IA32_PLATFORM_ID during init since commit > >d8630b67ca1e ("x86/cpu: Add platform ID to CPU info structure"). KVM > >already supports this MSR on read for normal VMs by returning 0. > >Without support for this MSR, TDs get unchecked MSR access errors. > > > > unchecked MSR access error: RDMSR from 0x17 at rIP: 0xffffffffba38d6fc (intel_get_platform_id+0x7c/0xb0) > > Call Trace: > > <TASK> > > ? early_init_intel+0x28/0x2c0 > > ? early_cpu_init+0x9b/0x930 > > ? setup_arch+0xbf/0xbb0 > > ? _printk+0x6b/0x90 > > ? start_kernel+0x7f/0xaa0 > > ? x86_64_start_reservations+0x24/0x30 > > ? x86_64_start_kernel+0xda/0xe0 > > ? common_startup_64+0x13e/0x141 > > </TASK> > > > >Add MSR_IA32_PLATFORM_ID in tdx_has_emulated_msr() to allow TDs to read > >the MSR. MSR_IA32_PLATFORM_ID is read-only by hardware definition, i.e. > >KVM should never add it as writable, no need to add it in > >tdx_is_read_only_msr(). > > > >Fixes: dd50294f3e3c ("KVM: TDX: Implement callbacks for MSR operations") > >Reported-by: Vishal Verma <vishal.l.verma@intel.com> > >Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> > >--- > > arch/x86/kvm/vmx/tdx.c | 1 + > > 1 file changed, 1 insertion(+) > > > >diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c > >index 04ce321ebdf3..812ad99b11e5 100644 > >--- a/arch/x86/kvm/vmx/tdx.c > >+++ b/arch/x86/kvm/vmx/tdx.c > >@@ -2094,6 +2094,7 @@ void tdx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, > > bool tdx_has_emulated_msr(u32 index) > > { > > switch (index) { > >+ case MSR_IA32_PLATFORM_ID: > > case MSR_IA32_UCODE_REV: > > case MSR_IA32_ARCH_CAPABILITIES: > > case MSR_IA32_POWER_CTL: > > This patch looks good to me. But the rule for which MSRs should be emulated > by KVM for TDX is not very clear to me. I would strongly prefer to not take this patch, and instead fix the guest. This isn't some latent/pre-existing guest behavior, it's brand new functionality. I.e. Linux-as-a-TDX-guest broke itself. More importantly from a guest security perspective, consuming MSR_IA32_PLATFORM_ID is actively dangerous. E.g. it could allow the untrusted host to steer the guest's behavior with respect to feature detection and enablement. And once KVM allows reads from MSR_IA32_PLATFORM_ID, there's no going back. E.g. if the TDX-Module wants to emulate MSR_IA32_PLATFORM_ID, because there's an actual *need* to do so, then we're going to have a (minor) mess with KVM's ABI. > Maybe we can document the rule here, if there is one. That would make it > much easier to tell whether future issues like this are guest regressions > or missing KVM handling. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 16:30 ` Sean Christopherson @ 2026-04-28 18:31 ` Edgecombe, Rick P 2026-04-28 18:44 ` Sean Christopherson 0 siblings, 1 reply; 12+ messages in thread From: Edgecombe, Rick P @ 2026-04-28 18:31 UTC (permalink / raw) To: seanjc@google.com, Gao, Chao Cc: Hansen, Dave, x86@kernel.org, kas@kernel.org, binbin.wu@linux.intel.com, Li, Xiaoyao, linux-kernel@vger.kernel.org, Verma, Vishal L, kvm@vger.kernel.org, pbonzini@redhat.com On Tue, 2026-04-28 at 09:30 -0700, Sean Christopherson wrote: > > This patch looks good to me. But the rule for which MSRs should be emulated > > by KVM for TDX is not very clear to me. > > I would strongly prefer to not take this patch, and instead fix the guest. > This isn't some latent/pre-existing guest behavior, it's brand new > functionality. I.e. Linux-as-a-TDX-guest broke itself. > > More importantly from a guest security perspective, consuming > MSR_IA32_PLATFORM_ID is actively dangerous. E.g. it could allow the untrusted > host to steer the guest's behavior with respect to feature detection and > enablement. I feel like you could make similar cases about a lot the VMM controlled MSRs. > > And once KVM allows reads from MSR_IA32_PLATFORM_ID, there's no going back. > E.g. if the TDX-Module wants to emulate MSR_IA32_PLATFORM_ID, because there's > an actual *need* to do so, then we're going to have a (minor) mess with KVM's > ABI. This is a problem with the bare metal KVM behavior too, and it's just super old? For TDX, hmm. I guess the standard thing to do in order to avoid creating a KVM ABI problems is just match the arch behavior. But for TDs, it is a very special type of VM. The special TDX guest things can't work on bare metal. Furthermore, guest opt ins can change what arch is even supposed to be virtualized. So the normal KVM default thing to do doesn't always fit. So instead we will just virtualize as little as possible to keep Linux guest running? Ok. > > > Maybe we can document the rule here, if there is one. That would make it > > much easier to tell whether future issues like this are guest regressions > > or missing KVM handling. Speaking in general now about TDX guest ABI, not about this specific MSR. I agree it would be good to have some story about how this is supposed to work and evolve. Similar to the CPUID bit stuff we are trying to clean up. I'm also remembering the debate about what to do about the MTRR bit being forced on, but not being able to apply the KVM solution (which got ripped out anyway) to the S-EPT. Or the guest maxpfn thing, where we got the TDX module to add CPUID bit support we needed. By default, we can try to make it so the TDX module will, or will let us, faithfully match the normal x86 arch bit behavior. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 18:31 ` Edgecombe, Rick P @ 2026-04-28 18:44 ` Sean Christopherson 0 siblings, 0 replies; 12+ messages in thread From: Sean Christopherson @ 2026-04-28 18:44 UTC (permalink / raw) To: Rick P Edgecombe Cc: Chao Gao, Dave Hansen, x86@kernel.org, kas@kernel.org, binbin.wu@linux.intel.com, Xiaoyao Li, linux-kernel@vger.kernel.org, Vishal L Verma, kvm@vger.kernel.org, pbonzini@redhat.com On Tue, Apr 28, 2026, Rick P Edgecombe wrote: > On Tue, 2026-04-28 at 09:30 -0700, Sean Christopherson wrote: > > > This patch looks good to me. But the rule for which MSRs should be emulated > > > by KVM for TDX is not very clear to me. > > > > I would strongly prefer to not take this patch, and instead fix the guest. > > This isn't some latent/pre-existing guest behavior, it's brand new > > functionality. I.e. Linux-as-a-TDX-guest broke itself. > > > > More importantly from a guest security perspective, consuming > > MSR_IA32_PLATFORM_ID is actively dangerous. E.g. it could allow the untrusted > > host to steer the guest's behavior with respect to feature detection and > > enablement. > > I feel like you could make similar cases about a lot the VMM controlled MSRs. Oh, for sure. And far worse (yet another reminder that I need to refresh this series). https://lore.kernel.org/all/20250227021855.3257188-1-seanjc@google.com > > And once KVM allows reads from MSR_IA32_PLATFORM_ID, there's no going back. > > E.g. if the TDX-Module wants to emulate MSR_IA32_PLATFORM_ID, because there's > > an actual *need* to do so, then we're going to have a (minor) mess with KVM's > > ABI. > > This is a problem with the bare metal KVM behavior too, and it's just super old? No? Oh, I see what you're asking. I'm mostly concerned about the host side of things. The problem with TDX is that a TDX-Module update could effectively change KVM's behavior, i.e. if the TDX-Module decides it needs to emulate PLATFORM_ID for whatever reason. So not only would KVM need to enumerate to userspace that the MSR is supported/emulated for TDX guests, KVM would also need to differentiate between emulated by KVM and emulated by the TDX-Module. > For TDX, hmm. I guess the standard thing to do in order to avoid creating a KVM > ABI problems is just match the arch behavior. But for TDs, it is a very special > type of VM. The special TDX guest things can't work on bare metal. Furthermore, > guest opt ins can change what arch is even supposed to be virtualized. So the > normal KVM default thing to do doesn't always fit. > > So instead we will just virtualize as little as possible to keep Linux guest > running? Ok. Yeah, and the sequence of events matters. Most of KVM's half-hearted emulation of random MSRs exists because KVM needed to be able to run existing kernels. But once KVM (and other hypervisors) existed, kernels learned to run as guests (and hardware vendors largely did a better job of explicitly enumerating MSRs and whatnot), and so the need to throw hacks into KVM mostly went away. > > > Maybe we can document the rule here, if there is one. That would make it > > > much easier to tell whether future issues like this are guest regressions > > > or missing KVM handling. > > Speaking in general now about TDX guest ABI, not about this specific MSR. I > agree it would be good to have some story about how this is supposed to work and > evolve. Similar to the CPUID bit stuff we are trying to clean up. > > I'm also remembering the debate about what to do about the MTRR bit being forced > on, but not being able to apply the KVM solution (which got ripped out anyway) > to the S-EPT. Or the guest maxpfn thing, where we got the TDX module to add > CPUID bit support we needed. By default, we can try to make it so the TDX module > will, or will let us, faithfully match the normal x86 arch bit behavior. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID 2026-04-28 2:47 ` [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID Binbin Wu 2026-04-28 5:31 ` Xiaoyao Li 2026-04-28 11:44 ` Chao Gao @ 2026-04-28 18:49 ` Dave Hansen 2 siblings, 0 replies; 12+ messages in thread From: Dave Hansen @ 2026-04-28 18:49 UTC (permalink / raw) To: Binbin Wu, kvm, linux-kernel, x86 Cc: pbonzini, seanjc, kas, rick.p.edgecombe, vishal.l.verma, xiaoyao.li, chao.gao On 4/27/26 19:47, Binbin Wu wrote: > Linux kernel reads MSR_IA32_PLATFORM_ID during init since commit > d8630b67ca1e ("x86/cpu: Add platform ID to CPU info structure"). KVM > already supports this MSR on read for normal VMs by returning 0. > Without support for this MSR, TDs get unchecked MSR access errors. NAK from me on this. The platform ID is used for one thing and one thing only: microcode updates. Those updates are solely the domain of the bare-metal OS. The (guest) kernel code that's even trying to touch this MSR is buggy and insane. We need to turn that code it off when X86_FEATURE_HYPERVISOR==1. There's already a patch floating around to do that. Please don't add more smoke and mirrors. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment 2026-04-28 2:47 [PATCH 0/2] Fix MSR_IA32_PLATFORM_ID access for TDX guests Binbin Wu 2026-04-28 2:47 ` [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID Binbin Wu @ 2026-04-28 2:47 ` Binbin Wu 2026-04-28 6:01 ` Xiaoyao Li 1 sibling, 1 reply; 12+ messages in thread From: Binbin Wu @ 2026-04-28 2:47 UTC (permalink / raw) To: kvm, linux-kernel, x86 Cc: pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, xiaoyao.li, chao.gao, binbin.wu The Linux kernel now reads MSR_IA32_PLATFORM_ID during CPU init. When running as a guest, if the underlying hypervisor does not emulate the MSR, the RDMSR from 0x17 in intel_get_platform_id() can trigger an unchecked MSR access during early boot. unchecked MSR access error: RDMSR from 0x17 at rIP: 0xffffffffba38d6fc (intel_get_platform_id+0x7c/0xb0) Call Trace: <TASK> ? early_init_intel+0x28/0x2c0 ? early_cpu_init+0x9b/0x930 ? setup_arch+0xbf/0xbb0 ? _printk+0x6b/0x90 ? start_kernel+0x7f/0xaa0 ? x86_64_start_reservations+0x24/0x30 ? x86_64_start_kernel+0xda/0xe0 ? common_startup_64+0x13e/0x141 </TASK> Currently, KVM does not support guest reads of MSR_IA32_PLATFORM_ID for TDX. This should be fixed in the hypervisor, but for compatibility with newer guests running on older KVM hosts, skip reading MSR_IA32_PLATFORM_ID and return 0. It's meaningless to read MSR_IA32_PLATFORM_ID since guests are not allowed to do microcode update. cpu_has_old_microcode(), which uses platform ID for CPU match, also skips checking whether the microcode is old or not in a virtualized environment. Since intel_get_platform_id() can be called early before cpuinfo_x86 is fully initialized, check whether it's running in a virtualized environment from CPUID and opportunistically add a helper. Fixes: d8630b67ca1ed ("x86/cpu: Add platform ID to CPU info structure") Reported-by: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> --- arch/x86/kernel/cpu/microcode/core.c | 2 +- arch/x86/kernel/cpu/microcode/intel.c | 4 ++++ arch/x86/kernel/cpu/microcode/internal.h | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 651202e6fefb..ee204c8a90bf 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -135,7 +135,7 @@ bool __init microcode_loader_disabled(void) * 3) Certain AMD patch levels are not allowed to be * overwritten. */ - hypervisor_present = native_cpuid_ecx(1) & BIT(31); + hypervisor_present = x86_cpuid_has_hypervisor(); if ((hypervisor_present && !IS_ENABLED(CONFIG_MICROCODE_DBG)) || amd_check_current_patch_level()) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 37ac4afe0972..cb93e4ea410e 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -147,6 +147,10 @@ u32 intel_get_platform_id(void) if (intel_cpuid_vfm() <= INTEL_PENTIUM_II_KLAMATH) return 0; + /* Don't try to read microcode bits when virtualized. */ + if (x86_cpuid_has_hypervisor()) + return 0; + /* get processor flags from MSR 0x17 */ native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h index 3b93c0676b4f..0233e074d76b 100644 --- a/arch/x86/kernel/cpu/microcode/internal.h +++ b/arch/x86/kernel/cpu/microcode/internal.h @@ -100,6 +100,11 @@ static inline unsigned int x86_cpuid_family(void) return x86_family(eax); } +static inline bool x86_cpuid_has_hypervisor(void) +{ + return native_cpuid_ecx(1) & BIT(31); +} + extern bool force_minrev; #ifdef CONFIG_CPU_SUP_AMD -- 2.46.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment 2026-04-28 2:47 ` [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment Binbin Wu @ 2026-04-28 6:01 ` Xiaoyao Li 2026-04-28 9:57 ` Binbin Wu 2026-04-28 18:54 ` Edgecombe, Rick P 0 siblings, 2 replies; 12+ messages in thread From: Xiaoyao Li @ 2026-04-28 6:01 UTC (permalink / raw) To: Binbin Wu, kvm, linux-kernel, x86 Cc: pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, chao.gao On 4/28/2026 10:47 AM, Binbin Wu wrote: > The Linux kernel now reads MSR_IA32_PLATFORM_ID during CPU init. When > running as a guest, if the underlying hypervisor does not emulate the > MSR, the RDMSR from 0x17 in intel_get_platform_id() can trigger an > unchecked MSR access during early boot. > > unchecked MSR access error: RDMSR from 0x17 at rIP: 0xffffffffba38d6fc (intel_get_platform_id+0x7c/0xb0) > Call Trace: > <TASK> > ? early_init_intel+0x28/0x2c0 > ? early_cpu_init+0x9b/0x930 > ? setup_arch+0xbf/0xbb0 > ? _printk+0x6b/0x90 > ? start_kernel+0x7f/0xaa0 > ? x86_64_start_reservations+0x24/0x30 > ? x86_64_start_kernel+0xda/0xe0 > ? common_startup_64+0x13e/0x141 > </TASK> > > Currently, KVM does not support guest reads of MSR_IA32_PLATFORM_ID for > TDX. This should be fixed in the hypervisor, but for compatibility with > newer guests running on older KVM hosts, skip reading MSR_IA32_PLATFORM_ID > and return 0. It's meaningless to read MSR_IA32_PLATFORM_ID since guests > are not allowed to do microcode update. cpu_has_old_microcode(), which > uses platform ID for CPU match, also skips checking whether the microcode > is old or not in a virtualized environment. > > Since intel_get_platform_id() can be called early before cpuinfo_x86 > is fully initialized, check whether it's running in a virtualized > environment from CPUID and opportunistically add a helper. > > Fixes: d8630b67ca1ed ("x86/cpu: Add platform ID to CPU info structure") > Reported-by: Vishal Verma <vishal.l.verma@intel.com> > Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com> > --- > arch/x86/kernel/cpu/microcode/core.c | 2 +- > arch/x86/kernel/cpu/microcode/intel.c | 4 ++++ > arch/x86/kernel/cpu/microcode/internal.h | 5 +++++ > 3 files changed, 10 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c > index 651202e6fefb..ee204c8a90bf 100644 > --- a/arch/x86/kernel/cpu/microcode/core.c > +++ b/arch/x86/kernel/cpu/microcode/core.c > @@ -135,7 +135,7 @@ bool __init microcode_loader_disabled(void) > * 3) Certain AMD patch levels are not allowed to be > * overwritten. > */ > - hypervisor_present = native_cpuid_ecx(1) & BIT(31); > + hypervisor_present = x86_cpuid_has_hypervisor(); > > if ((hypervisor_present && !IS_ENABLED(CONFIG_MICROCODE_DBG)) || > amd_check_current_patch_level()) > diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c > index 37ac4afe0972..cb93e4ea410e 100644 > --- a/arch/x86/kernel/cpu/microcode/intel.c > +++ b/arch/x86/kernel/cpu/microcode/intel.c > @@ -147,6 +147,10 @@ u32 intel_get_platform_id(void) > if (intel_cpuid_vfm() <= INTEL_PENTIUM_II_KLAMATH) > return 0; > > + /* Don't try to read microcode bits when virtualized. */ The platform ID is not only used by microcode update. I don't think calling them microcode bits is proper. It's also stashed in struct cpuinfo_x86::intel_platform_id and used in x86_match_cpu() as a factor as the generic FMS (Family, Model, Stepping) bits. We skip things due to hypervisor is set usually when the thing is known unable to be virtualized. From the perspective of microcode update, it's OK to skip reading it due to hypervisor bit. However, from the perspective of generic platform ID, it seems not that reasonable to skip reading it due to hypervisor bit. Especially KVM has supported this MSR for normal VMs. So how about using the safe version of RDMSR, if we want the enhancement? > + if (x86_cpuid_has_hypervisor()) > + return 0; > + > /* get processor flags from MSR 0x17 */ > native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); > > diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h > index 3b93c0676b4f..0233e074d76b 100644 > --- a/arch/x86/kernel/cpu/microcode/internal.h > +++ b/arch/x86/kernel/cpu/microcode/internal.h > @@ -100,6 +100,11 @@ static inline unsigned int x86_cpuid_family(void) > return x86_family(eax); > } > > +static inline bool x86_cpuid_has_hypervisor(void) > +{ > + return native_cpuid_ecx(1) & BIT(31); > +} > + > extern bool force_minrev; > > #ifdef CONFIG_CPU_SUP_AMD ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment 2026-04-28 6:01 ` Xiaoyao Li @ 2026-04-28 9:57 ` Binbin Wu 2026-04-28 18:54 ` Edgecombe, Rick P 1 sibling, 0 replies; 12+ messages in thread From: Binbin Wu @ 2026-04-28 9:57 UTC (permalink / raw) To: Xiaoyao Li Cc: kvm, linux-kernel, x86, pbonzini, seanjc, dave.hansen, kas, rick.p.edgecombe, vishal.l.verma, chao.gao On 4/28/2026 2:01 PM, Xiaoyao Li wrote: [...] >> diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c >> index 37ac4afe0972..cb93e4ea410e 100644 >> --- a/arch/x86/kernel/cpu/microcode/intel.c >> +++ b/arch/x86/kernel/cpu/microcode/intel.c >> @@ -147,6 +147,10 @@ u32 intel_get_platform_id(void) >> if (intel_cpuid_vfm() <= INTEL_PENTIUM_II_KLAMATH) >> return 0; >> + /* Don't try to read microcode bits when virtualized. */ > > The platform ID is not only used by microcode update. I don't think calling them microcode bits is proper. It's also stashed in struct cpuinfo_x86::intel_platform_id and used in x86_match_cpu() as a factor as the generic FMS (Family, Model, Stepping) bits. It's still related to microcode though. The platform id is used to detect whether the microcode is old or not in this case. > > We skip things due to hypervisor is set usually when the thing is known unable to be virtualized. From the perspective of microcode update, it's OK to skip reading it due to hypervisor bit. However, from the perspective of generic platform ID, it seems not that reasonable to skip reading it due to hypervisor bit. Especially KVM has supported this MSR for normal VMs. Considering the microcode related code, Linux kernel does special handling when running as a guest, microcode_loader_disabled() sets dis_ucode_ldr and cpu_has_old_microcode() also skips to check whether the microcode is old if it's running in a virtualized environment. I.e. the special handling for virtualization make it meaningless to read the MSR. > > So how about using the safe version of RDMSR, if we want the enhancement? I am open to this. Let's wait to see if the change on guest side is wanted or not. > >> + if (x86_cpuid_has_hypervisor()) >> + return 0; >> + >> /* get processor flags from MSR 0x17 */ >> native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); >> diff --git a/arch/x86/kernel/cpu/microcode/internal.h b/arch/x86/kernel/cpu/microcode/internal.h >> index 3b93c0676b4f..0233e074d76b 100644 >> --- a/arch/x86/kernel/cpu/microcode/internal.h >> +++ b/arch/x86/kernel/cpu/microcode/internal.h >> @@ -100,6 +100,11 @@ static inline unsigned int x86_cpuid_family(void) >> return x86_family(eax); >> } >> +static inline bool x86_cpuid_has_hypervisor(void) >> +{ >> + return native_cpuid_ecx(1) & BIT(31); >> +} >> + >> extern bool force_minrev; >> #ifdef CONFIG_CPU_SUP_AMD > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment 2026-04-28 6:01 ` Xiaoyao Li 2026-04-28 9:57 ` Binbin Wu @ 2026-04-28 18:54 ` Edgecombe, Rick P 1 sibling, 0 replies; 12+ messages in thread From: Edgecombe, Rick P @ 2026-04-28 18:54 UTC (permalink / raw) To: Li, Xiaoyao, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, binbin.wu@linux.intel.com, x86@kernel.org Cc: Verma, Vishal L, pbonzini@redhat.com, Hansen, Dave, seanjc@google.com, Gao, Chao, kas@kernel.org On Tue, 2026-04-28 at 14:01 +0800, Xiaoyao Li wrote: > > + /* Don't try to read microcode bits when virtualized. */ > > The platform ID is not only used by microcode update. From the series with the blamed commit: Today, the only code that cares about the platform ID is the microcode update code itself. To facilitate storing the platform ID in a more generic place and using it outside of the microcode update itself, put the enumeration into a helper function. But it is still only used for microcode stuff AFAICT... It seems it was just moved to be "consistent with the other fields which can be matched". > I don't think > calling them microcode bits is proper. It's also stashed in struct > cpuinfo_x86::intel_platform_id and used in x86_match_cpu() as a factor > as the generic FMS (Family, Model, Stepping) bits. > > We skip things due to hypervisor is set usually when the thing is known > unable to be virtualized. From the perspective of microcode update, it's > OK to skip reading it due to hypervisor bit. However, from the > perspective of generic platform ID, it seems not that reasonable to skip > reading it due to hypervisor bit. Especially KVM has supported this MSR > for normal VMs. > > So how about using the safe version of RDMSR, if we want the enhancement? With the check if we are not virtualized we can get a nice warning if run on some weird platform with this MSR missing. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-04-28 18:55 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-28 2:47 [PATCH 0/2] Fix MSR_IA32_PLATFORM_ID access for TDX guests Binbin Wu 2026-04-28 2:47 ` [PATCH 1/2] KVM: TDX: Allow TDs to read MSR_IA32_PLATFORM_ID Binbin Wu 2026-04-28 5:31 ` Xiaoyao Li 2026-04-28 11:44 ` Chao Gao 2026-04-28 16:30 ` Sean Christopherson 2026-04-28 18:31 ` Edgecombe, Rick P 2026-04-28 18:44 ` Sean Christopherson 2026-04-28 18:49 ` Dave Hansen 2026-04-28 2:47 ` [PATCH 2/2] x86/cpu: Skip reading MSR_IA32_PLATFORM_ID in virtualized environment Binbin Wu 2026-04-28 6:01 ` Xiaoyao Li 2026-04-28 9:57 ` Binbin Wu 2026-04-28 18:54 ` Edgecombe, Rick P
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox