* [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F()
@ 2026-02-08 16:42 Carlos López
2026-02-08 18:28 ` Borislav Petkov
2026-02-09 10:02 ` Binbin Wu
0 siblings, 2 replies; 19+ messages in thread
From: Carlos López @ 2026-02-08 16:42 UTC (permalink / raw)
To: seanjc, bp, kvm
Cc: Carlos López, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)
KVM incorrectly synthesizes TSA_SQ_NO and TSA_L1_NO when running
on AMD Family 19h CPUs by using SYNTHESIZED_F(), which unconditionally
enables features for KVM-only CPUID leaves (as is the case with
CPUID_8000_0021_ECX), regardless of the kernel's synthesis logic in
tsa_init(). This is due to the following logic in kvm_cpu_cap_init():
if (leaf < NCAPINTS)
kvm_cpu_caps[leaf] &= kernel_cpu_caps[leaf];
This can cause an unexpected failure on Family 19h CPUs during SEV-SNP
guest setup, when userspace issues SNP_LAUNCH_UPDATE, as setting these
bits in the CPUID page on vulnerable CPUs is explicitly rejected by SNP
firmware.
Switch to SCATTERED_F(), so that the bits are only set if the features
have been force-set by the kernel in tsa_init(), or if they are reported
in the raw CPUID.
Fixes: 31272abd5974 ("KVM: SVM: Advertise TSA CPUID bits to guests")
Signed-off-by: Carlos López <clopez@suse.de>
---
arch/x86/kvm/cpuid.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 88a5426674a1..819c176e02ff 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -1230,8 +1230,8 @@ void kvm_set_cpu_caps(void)
);
kvm_cpu_cap_init(CPUID_8000_0021_ECX,
- SYNTHESIZED_F(TSA_SQ_NO),
- SYNTHESIZED_F(TSA_L1_NO),
+ SCATTERED_F(TSA_SQ_NO),
+ SCATTERED_F(TSA_L1_NO),
);
kvm_cpu_cap_init(CPUID_8000_0022_EAX,
base-commit: 0de4a0eec25b9171f2a2abb1a820e125e6797770
--
2.51.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-08 16:42 [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() Carlos López @ 2026-02-08 18:28 ` Borislav Petkov 2026-02-08 20:50 ` Jim Mattson 2026-02-09 10:02 ` Binbin Wu 1 sibling, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-08 18:28 UTC (permalink / raw) To: Carlos López, seanjc Cc: kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Sun, Feb 08, 2026 at 05:42:33PM +0100, Carlos López wrote: > KVM incorrectly synthesizes TSA_SQ_NO and TSA_L1_NO when running > on AMD Family 19h CPUs by using SYNTHESIZED_F(), which unconditionally > enables features for KVM-only CPUID leaves (as is the case with > CPUID_8000_0021_ECX), regardless of the kernel's synthesis logic in > tsa_init(). This is due to the following logic in kvm_cpu_cap_init(): > > if (leaf < NCAPINTS) > kvm_cpu_caps[leaf] &= kernel_cpu_caps[leaf]; > > This can cause an unexpected failure on Family 19h CPUs during SEV-SNP > guest setup, when userspace issues SNP_LAUNCH_UPDATE, as setting these > bits in the CPUID page on vulnerable CPUs is explicitly rejected by SNP > firmware. > > Switch to SCATTERED_F(), so that the bits are only set if the features > have been force-set by the kernel in tsa_init(), or if they are reported > in the raw CPUID. > > Fixes: 31272abd5974 ("KVM: SVM: Advertise TSA CPUID bits to guests") > Signed-off-by: Carlos López <clopez@suse.de> > --- > arch/x86/kvm/cpuid.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > index 88a5426674a1..819c176e02ff 100644 > --- a/arch/x86/kvm/cpuid.c > +++ b/arch/x86/kvm/cpuid.c > @@ -1230,8 +1230,8 @@ void kvm_set_cpu_caps(void) > ); > > kvm_cpu_cap_init(CPUID_8000_0021_ECX, > - SYNTHESIZED_F(TSA_SQ_NO), > - SYNTHESIZED_F(TSA_L1_NO), Well: /* * Synthesized Feature - For features that are synthesized into boot_cpu_data, * i.e. may not be present in the raw CPUID, but can still be advertised to * userspace. Primarily used for mitigation related feature flags. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ #define SYNTHESIZED_F(name) > + SCATTERED_F(TSA_SQ_NO), > + SCATTERED_F(TSA_L1_NO), And scattered are of the same type. Sean, what's the subtle difference here? -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-08 18:28 ` Borislav Petkov @ 2026-02-08 20:50 ` Jim Mattson 2026-02-08 21:13 ` Borislav Petkov 0 siblings, 1 reply; 19+ messages in thread From: Jim Mattson @ 2026-02-08 20:50 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, seanjc, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Sun, Feb 8, 2026 at 10:29 AM Borislav Petkov <bp@alien8.de> wrote: > > On Sun, Feb 08, 2026 at 05:42:33PM +0100, Carlos López wrote: > > KVM incorrectly synthesizes TSA_SQ_NO and TSA_L1_NO when running > > on AMD Family 19h CPUs by using SYNTHESIZED_F(), which unconditionally > > enables features for KVM-only CPUID leaves (as is the case with > > CPUID_8000_0021_ECX), regardless of the kernel's synthesis logic in > > tsa_init(). This is due to the following logic in kvm_cpu_cap_init(): > > > > if (leaf < NCAPINTS) > > kvm_cpu_caps[leaf] &= kernel_cpu_caps[leaf]; > > > > This can cause an unexpected failure on Family 19h CPUs during SEV-SNP > > guest setup, when userspace issues SNP_LAUNCH_UPDATE, as setting these > > bits in the CPUID page on vulnerable CPUs is explicitly rejected by SNP > > firmware. > > > > Switch to SCATTERED_F(), so that the bits are only set if the features > > have been force-set by the kernel in tsa_init(), or if they are reported > > in the raw CPUID. > > > > Fixes: 31272abd5974 ("KVM: SVM: Advertise TSA CPUID bits to guests") > > Signed-off-by: Carlos López <clopez@suse.de> > > --- > > arch/x86/kvm/cpuid.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > > index 88a5426674a1..819c176e02ff 100644 > > --- a/arch/x86/kvm/cpuid.c > > +++ b/arch/x86/kvm/cpuid.c > > @@ -1230,8 +1230,8 @@ void kvm_set_cpu_caps(void) > > ); > > > > kvm_cpu_cap_init(CPUID_8000_0021_ECX, > > - SYNTHESIZED_F(TSA_SQ_NO), > > - SYNTHESIZED_F(TSA_L1_NO), > > Well: > > /* > * Synthesized Feature - For features that are synthesized into boot_cpu_data, > * i.e. may not be present in the raw CPUID, but can still be advertised to > * userspace. Primarily used for mitigation related feature flags. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > */ > #define SYNTHESIZED_F(name) > > > + SCATTERED_F(TSA_SQ_NO), > > + SCATTERED_F(TSA_L1_NO), > > And scattered are of the same type. > > Sean, what's the subtle difference here? SYNTHESIZED_F() sets the bit unconditionally. SCATTERED_F() propagates the bit (if set) from the host's cpufeature flags. Using SYNTHESIZED_F() is fine, but it needs to be applied conditionally. Per AMD's guidance in https://www.amd.com/content/dam/amd/en/documents/resources/bulletin/technical-guidance-for-mitigating-transient-scheduler-attacks.pdf: As of the date of this paper, AMD’s analysis has determined that only Family 19h CPUs are vulnerable to TSA. AMD CPUs that are older than Family 19h are not vulnerable to TSA but do not set TSA_L1_NO or TSA_SQ_NO. Bare-metal software that detects such a CPU should assume the CPU is not vulnerable to TSA. Hypervisor software should synthesize the value of the TSA_L1_NO and TSA_SQ_NO CPUID bits on such platforms so guest software can rely on CPUID to detect if TSA mitigations are required. So, the original code should have checked for family and model if running on bare metal, and should not have synthesized the feature for Zen3 and Zen4. However, as Carlos notes, this logic is already present in tsa_init(). Even though unaffected hardware doesn't report the TSA_NO CPUID bits, tsa_init() sets the corresponding cpufeature flags. Rather than replicate the tsa_init() logic in kvm, SCATTERED_F() can be used to propagate the cpufeature flags from the host. Reviewed-by: Jim Mattson <jmattson@google.com> ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-08 20:50 ` Jim Mattson @ 2026-02-08 21:13 ` Borislav Petkov 2026-02-09 5:48 ` Jim Mattson 0 siblings, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-08 21:13 UTC (permalink / raw) To: Jim Mattson Cc: Carlos López, seanjc, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Sun, Feb 08, 2026 at 12:50:18PM -0800, Jim Mattson wrote: > > /* > > * Synthesized Feature - For features that are synthesized into boot_cpu_data, > > * i.e. may not be present in the raw CPUID, but can still be advertised to > > * userspace. Primarily used for mitigation related feature flags. > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > */ > > #define SYNTHESIZED_F(name) > > > > > + SCATTERED_F(TSA_SQ_NO), > > > + SCATTERED_F(TSA_L1_NO), > > > > And scattered are of the same type. > > > > Sean, what's the subtle difference here? > > SYNTHESIZED_F() sets the bit unconditionally. SCATTERED_F() propagates > the bit (if set) from the host's cpufeature flags. Yah, and I was hinting at the scarce documentation. SYNTHESIZED_F() is "Primarily used for mitigation related feature flags." SCATTERED_F() is "For features that are scattered by cpufeatures.h." And frankly, I don't understand why there needs to be a difference whether the feature is scattered or synthesized. If the flag is set on baremetal, then it is and it being set, denotes what it means. And if it is not set, then it means the absence of that feature. It is that simple. Then it becomes a decision of the hypervisor whether to expose it to the guest or not. Not whether it is synthesized or scattered. But maybe I'm missing an aspect which is important for virt... -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-08 21:13 ` Borislav Petkov @ 2026-02-09 5:48 ` Jim Mattson 2026-02-09 11:40 ` Carlos López 0 siblings, 1 reply; 19+ messages in thread From: Jim Mattson @ 2026-02-09 5:48 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, seanjc, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Sun, Feb 8, 2026 at 1:14 PM Borislav Petkov <bp@alien8.de> wrote: > > On Sun, Feb 08, 2026 at 12:50:18PM -0800, Jim Mattson wrote: > > > /* > > > * Synthesized Feature - For features that are synthesized into boot_cpu_data, > > > * i.e. may not be present in the raw CPUID, but can still be advertised to > > > * userspace. Primarily used for mitigation related feature flags. > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > > */ > > > #define SYNTHESIZED_F(name) > > > > > > > + SCATTERED_F(TSA_SQ_NO), > > > > + SCATTERED_F(TSA_L1_NO), > > > > > > And scattered are of the same type. > > > > > > Sean, what's the subtle difference here? > > > > SYNTHESIZED_F() sets the bit unconditionally. SCATTERED_F() propagates > > the bit (if set) from the host's cpufeature flags. > > Yah, and I was hinting at the scarce documentation. > > SYNTHESIZED_F() is "Primarily used for mitigation related feature flags." > SCATTERED_F() is "For features that are scattered by cpufeatures.h." Ugh. I have to rescind my Reviewed-by. IIUC, SCATTERED_F() implies a logical and with hardware CPUID, which means that the current proposal will never set the ITS_NO bits. I clearly don't have any idea how the new infrastructure works, and there's too much CPP nonsense for me to care. I'll just defer to Sean. > And frankly, I don't understand why there needs to be a difference whether the > feature is scattered or synthesized. If the flag is set on baremetal, then it > is and it being set, denotes what it means. And if it is not set, then it > means the absence of that feature. > > It is that simple. > > Then it becomes a decision of the hypervisor whether to expose it to the guest > or not. > > Not whether it is synthesized or scattered. > > But maybe I'm missing an aspect which is important for virt... > > -- > Regards/Gruss, > Boris. > > https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 5:48 ` Jim Mattson @ 2026-02-09 11:40 ` Carlos López 2026-02-09 15:06 ` Sean Christopherson 0 siblings, 1 reply; 19+ messages in thread From: Carlos López @ 2026-02-09 11:40 UTC (permalink / raw) To: Jim Mattson, Borislav Petkov Cc: seanjc, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger Hi, On 2/9/26 6:48 AM, Jim Mattson wrote: > On Sun, Feb 8, 2026 at 1:14 PM Borislav Petkov <bp@alien8.de> wrote: >> >> On Sun, Feb 08, 2026 at 12:50:18PM -0800, Jim Mattson wrote: >>>> /* >>>> * Synthesized Feature - For features that are synthesized into boot_cpu_data, >>>> * i.e. may not be present in the raw CPUID, but can still be advertised to >>>> * userspace. Primarily used for mitigation related feature flags. >>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >>>> */ >>>> #define SYNTHESIZED_F(name) >>>> >>>>> + SCATTERED_F(TSA_SQ_NO), >>>>> + SCATTERED_F(TSA_L1_NO), >>>> >>>> And scattered are of the same type. >>>> >>>> Sean, what's the subtle difference here? >>> >>> SYNTHESIZED_F() sets the bit unconditionally. SCATTERED_F() propagates >>> the bit (if set) from the host's cpufeature flags. >> >> Yah, and I was hinting at the scarce documentation. >> >> SYNTHESIZED_F() is "Primarily used for mitigation related feature flags." >> SCATTERED_F() is "For features that are scattered by cpufeatures.h." > > Ugh. I have to rescind my Reviewed-by. IIUC, SCATTERED_F() implies a > logical and with hardware CPUID, which means that the current proposal > will never set the ITS_NO bits. Right, I see what you mean now. SCATTERED_F() will set kvm_cpu_caps correctly, but then this will clear the bits, because kvm_cpu_cap_synthesized is now 0: kvm_cpu_caps[leaf] &= (raw_cpuid_get(cpuid) | kvm_cpu_cap_synthesized); So to me it seems like SYNTHESIZED_F() is just wrong, since it always enables bits for KVM-only leafs. So how about the following (I think Binbin Wu suggests this in his other email): diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 819c176e02ff..5e863e213f54 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -769,7 +769,8 @@ do { \ */ #define SYNTHESIZED_F(name) \ ({ \ - kvm_cpu_cap_synthesized |= feature_bit(name); \ + if (boot_cpu_has(X86_FEATURE_##name)) \ + kvm_cpu_cap_synthesized |= feature_bit(name); \ F(name); \ }) ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 11:40 ` Carlos López @ 2026-02-09 15:06 ` Sean Christopherson 2026-02-09 15:32 ` Borislav Petkov 0 siblings, 1 reply; 19+ messages in thread From: Sean Christopherson @ 2026-02-09 15:06 UTC (permalink / raw) To: Carlos López Cc: Jim Mattson, Borislav Petkov, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Mon, Feb 09, 2026, Carlos López wrote: > Hi, > > On 2/9/26 6:48 AM, Jim Mattson wrote: > > On Sun, Feb 8, 2026 at 1:14 PM Borislav Petkov <bp@alien8.de> wrote: > >> > >> On Sun, Feb 08, 2026 at 12:50:18PM -0800, Jim Mattson wrote: > >>>> /* > >>>> * Synthesized Feature - For features that are synthesized into boot_cpu_data, > >>>> * i.e. may not be present in the raw CPUID, but can still be advertised to > >>>> * userspace. Primarily used for mitigation related feature flags. > >>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > >>>> */ > >>>> #define SYNTHESIZED_F(name) > >>>> > >>>>> + SCATTERED_F(TSA_SQ_NO), > >>>>> + SCATTERED_F(TSA_L1_NO), > >>>> > >>>> And scattered are of the same type. > >>>> > >>>> Sean, what's the subtle difference here? > >>> > >>> SYNTHESIZED_F() sets the bit unconditionally. SCATTERED_F() propagates > >>> the bit (if set) from the host's cpufeature flags. As noted below, SYNTHESIZED_F() isn't entirely unconditional. kvm_cpu_cap_init() factors in boot_cpu_data.x86_capability, the problem here is that SYNTHESIZED_F() is now being used for KVM-only leafs, and so the common code doesn't work as intended. > >> Yah, and I was hinting at the scarce documentation. Maybe I could add a table showing how the XXX_F() macros map to various controls? > >> SYNTHESIZED_F() is "Primarily used for mitigation related feature flags." > >> SCATTERED_F() is "For features that are scattered by cpufeatures.h." > > > > Ugh. I have to rescind my Reviewed-by. IIUC, SCATTERED_F() implies a > > logical and with hardware CPUID, which means that the current proposal > > will never set the ITS_NO bits. > > Right, I see what you mean now. SCATTERED_F() will set kvm_cpu_caps > correctly, but then this will clear the bits, because > kvm_cpu_cap_synthesized is now 0: > > kvm_cpu_caps[leaf] &= (raw_cpuid_get(cpuid) | > kvm_cpu_cap_synthesized); > > So to me it seems like SYNTHESIZED_F() is just wrong, It was right when I wrote it :-) > since it always enables bits for KVM-only leafs. Yes, I didn't anticipate synthesizing flags into KVM-only leafs. > So how about the following > (I think Binbin Wu suggests this in his other email): > > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > index 819c176e02ff..5e863e213f54 100644 > --- a/arch/x86/kvm/cpuid.c > +++ b/arch/x86/kvm/cpuid.c > @@ -769,7 +769,8 @@ do { \ > */ > #define SYNTHESIZED_F(name) \ > ({ \ > - kvm_cpu_cap_synthesized |= feature_bit(name); \ > + if (boot_cpu_has(X86_FEATURE_##name)) \ > + kvm_cpu_cap_synthesized |= feature_bit(name); \ I would rather do this: diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 88a5426674a1..5f41924987c7 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -770,7 +770,10 @@ do { \ #define SYNTHESIZED_F(name) \ ({ \ kvm_cpu_cap_synthesized |= feature_bit(name); \ - F(name); \ + \ + BUILD_BUG_ON(X86_FEATURE_##name >= MAX_CPU_FEATURES); \ + if (boot_cpu_has(X86_FEATURE_##name)) \ + F(name); \ }) /* because I'd like to keep kvm_cpu_cap_synthesized unconditional and have kvm_cpu_cap_features reflect what is supported. And with Fixes: 31272abd5974 ("KVM: SVM: Advertise TSA CPUID bits to guests") because everything was fine before that commit (though it was set up to fail). > F(name); \ > }) > ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 15:06 ` Sean Christopherson @ 2026-02-09 15:32 ` Borislav Petkov 2026-02-09 16:29 ` Sean Christopherson 0 siblings, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-09 15:32 UTC (permalink / raw) To: Sean Christopherson Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Mon, Feb 09, 2026 at 07:06:36AM -0800, Sean Christopherson wrote: > Maybe I could add a table showing how the XXX_F() macros map to various controls? Perhaps start first, please, with explaining the difference between SYNTHESIZED_F and SCATTERED_F and why you even need it? I mean, KVM and guests only care whether X86_FEATURE flags are set or not, no? Not how they get defined underneath... -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 15:32 ` Borislav Petkov @ 2026-02-09 16:29 ` Sean Christopherson 2026-02-09 17:45 ` Borislav Petkov 0 siblings, 1 reply; 19+ messages in thread From: Sean Christopherson @ 2026-02-09 16:29 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Mon, Feb 09, 2026, Borislav Petkov wrote: > On Mon, Feb 09, 2026 at 07:06:36AM -0800, Sean Christopherson wrote: > > Maybe I could add a table showing how the XXX_F() macros map to various controls? > > Perhaps start first, please, with explaining the difference between > SYNTHESIZED_F and SCATTERED_F and why you even need it? SCATTERED_F requires the feature flag to be present in raw CPUID, SYNTHESIZED_F does not. > I mean, KVM and guests only care whether X86_FEATURE flags are set or not, no? Nope. KVM cares about what KVM can virtualize/emulate, and about helping userspace accurately represent the virtual CPU that will be enumerated to the guest. F : Features that must be present in boot_cpu_data and raw CPUID SCATTERED_F : Same as F(), but are scattered by the kernel X86_64_F : Same as F(), but are restricted to 64-bit kernels EMULATED_F : Always supported; the feature is unconditionally emulated in software SYNTHESIZED_F : Features that must be present in boot_cpu_data, but may or may not be in raw CPUID. May also be scattered. PASSTHROUGH_F : Features that must be present in raw CPUID, but may or may not be present in boot_cpu_data ALIASED_1_EDX_F : Features in 0x8000_0001.EDX that are duplicates of identical 0x1.EDX features VENDOR_F : Features that are controlled by vendor code, often because they are guarded by a vendor specific module param. Rules vary, but typically they are handled like basic F() features RUNTIME_F : Features that KVM dynamically sets/clears at runtime, but that are never adveristed to userspace. E.g. OSXSAVE and OSPKE. > Not how they get defined underneath... ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 16:29 ` Sean Christopherson @ 2026-02-09 17:45 ` Borislav Petkov 2026-02-09 21:12 ` Sean Christopherson 0 siblings, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-09 17:45 UTC (permalink / raw) To: Sean Christopherson Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Mon, Feb 09, 2026 at 08:29:36AM -0800, Sean Christopherson wrote: > Nope. KVM cares about what KVM can virtualize/emulate, and about helping userspace > accurately represent the virtual CPU that will be enumerated to the guest. So why don't you key on that in those macros instead of how they're defined? EXPOSE_TO_GUEST_F() and then underneath we can figure out how to expose them. We could have a helper table which determines what each feature is and how it should interact with raw host CPUID or something slicker. > F : Features that must be present in boot_cpu_data and raw CPUID > SCATTERED_F : Same as F(), but are scattered by the kernel > X86_64_F : Same as F(), but are restricted to 64-bit kernels > EMULATED_F : Always supported; the feature is unconditionally emulated in software > SYNTHESIZED_F : Features that must be present in boot_cpu_data, but may or > may not be in raw CPUID. May also be scattered. > PASSTHROUGH_F : Features that must be present in raw CPUID, but may or may > not be present in boot_cpu_data > ALIASED_1_EDX_F : Features in 0x8000_0001.EDX that are duplicates of identical 0x1.EDX features > VENDOR_F : Features that are controlled by vendor code, often because > they are guarded by a vendor specific module param. Rules > vary, but typically they are handled like basic F() features > RUNTIME_F : Features that KVM dynamically sets/clears at runtime, but that > are never adveristed to userspace. E.g. OSXSAVE and OSPKE. And for the time being, I'd love if this were somewhere in arch/x86/kvm/cpuid.c so that it is clear how one should use those macros. The end goal of having the user not care about which macro to use would be the ultimate, super-duper thing tho. I'd say. Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 17:45 ` Borislav Petkov @ 2026-02-09 21:12 ` Sean Christopherson 2026-02-10 20:07 ` Borislav Petkov 0 siblings, 1 reply; 19+ messages in thread From: Sean Christopherson @ 2026-02-09 21:12 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Mon, Feb 09, 2026, Borislav Petkov wrote: > On Mon, Feb 09, 2026 at 08:29:36AM -0800, Sean Christopherson wrote: > > Nope. KVM cares about what KVM can virtualize/emulate, and about helping userspace > > accurately represent the virtual CPU that will be enumerated to the guest. > > So why don't you key on that in those macros instead of how they're defined? > > EXPOSE_TO_GUEST_F() > > and then underneath we can figure out how to expose them. Huh? That's what the macros do, they describe KVM's handling of the associated feature. SYNTHESIZED is a bit weird because it bleeds some kernel details into KVM, but ultimately it's still KVM decision as to whether or not "forced" features can be synthesized for the guest. > We could have a helper table which determines what each feature is and how it > should interact with raw host CPUID or something slicker. > > > F : Features that must be present in boot_cpu_data and raw CPUID > > SCATTERED_F : Same as F(), but are scattered by the kernel > > X86_64_F : Same as F(), but are restricted to 64-bit kernels > > EMULATED_F : Always supported; the feature is unconditionally emulated in software > > SYNTHESIZED_F : Features that must be present in boot_cpu_data, but may or > > may not be in raw CPUID. May also be scattered. > > PASSTHROUGH_F : Features that must be present in raw CPUID, but may or may > > not be present in boot_cpu_data > > ALIASED_1_EDX_F : Features in 0x8000_0001.EDX that are duplicates of identical 0x1.EDX features > > VENDOR_F : Features that are controlled by vendor code, often because > > they are guarded by a vendor specific module param. Rules > > vary, but typically they are handled like basic F() features > > RUNTIME_F : Features that KVM dynamically sets/clears at runtime, but that > > are never adveristed to userspace. E.g. OSXSAVE and OSPKE. > > And for the time being, I'd love if this were somewhere in > arch/x86/kvm/cpuid.c so that it is clear how one should use those macros. I'll a patch with the above and more guidance. > The end goal of having the user not care about which macro to use would be the > ultimate, super-duper thing tho. And impossible, for all intents and purposes. The user/contributor/developer needs to define KVM's handling semantics *somehwere*. Sure, we could to that in a big array or something, but that's just a different way of dressing up the same pig. All of this very much is an ugly pig, but it's the concepts and mechanics that are ugly and convoluted. E.g. if we define a giant array or table, the contributor will need to map the feature to one of the above macros. In other words, kvm_initialize_cpu_caps() _is_ the helper table. If someone wants to try and do better, by all means, have at it. But I won't hold my breath. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 21:12 ` Sean Christopherson @ 2026-02-10 20:07 ` Borislav Petkov 2026-02-10 23:48 ` Sean Christopherson 0 siblings, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-10 20:07 UTC (permalink / raw) To: Sean Christopherson Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Mon, Feb 09, 2026 at 01:12:45PM -0800, Sean Christopherson wrote: > On Mon, Feb 09, 2026, Borislav Petkov wrote: > > On Mon, Feb 09, 2026 at 08:29:36AM -0800, Sean Christopherson wrote: > > > Nope. KVM cares about what KVM can virtualize/emulate, and about helping userspace > > > accurately represent the virtual CPU that will be enumerated to the guest. > > > > So why don't you key on that in those macros instead of how they're defined? > > > > EXPOSE_TO_GUEST_F() > > > > and then underneath we can figure out how to expose them. > > Huh? That's what the macros do, they describe KVM's handling of the associated > feature. SYNTHESIZED is a bit weird because it bleeds some kernel details into > KVM, but ultimately it's still KVM decision as to whether or not "forced" features > can be synthesized for the guest. My point is that you have to know *which* macro of all the available ones you need to use, in order to expose the feature. This thread is a case-in-point example about how it can get confusing. And it dudn't have to... > > > We could have a helper table which determines what each feature is and how it > > should interact with raw host CPUID or something slicker. > > > > > F : Features that must be present in boot_cpu_data and raw CPUID > > > SCATTERED_F : Same as F(), but are scattered by the kernel Right, so what happens if we unscatter a leaf? And why does it matter to KVM if the baremetal feature is scattered or not? KVM should only care whether the kernel has set it or not. > > > X86_64_F : Same as F(), but are restricted to 64-bit kernels > > > EMULATED_F : Always supported; the feature is unconditionally emulated in software And an emulated feature *can* be scattered or synthesized or whatever... > > > SYNTHESIZED_F : Features that must be present in boot_cpu_data, but may or > > > may not be in raw CPUID. May also be scattered. So which one do I use here? This is the confusion I'm taking about. > > > PASSTHROUGH_F : Features that must be present in raw CPUID, but may or may > > > not be present in boot_cpu_data Maybe there's a reason for it but why would the guest care if the feature is present in raw CPUID or not? The hypervisor controls what the guest sees in CPUID... > > > ALIASED_1_EDX_F : Features in 0x8000_0001.EDX that are duplicates of identical 0x1.EDX features > > > VENDOR_F : Features that are controlled by vendor code, often because > > > they are guarded by a vendor specific module param. Rules > > > vary, but typically they are handled like basic F() features > > > RUNTIME_F : Features that KVM dynamically sets/clears at runtime, but that > > > are never adveristed to userspace. E.g. OSXSAVE and OSPKE. > > Also, we're rewriting the whole CPUID handling on baremetal and someday the CPUID table in the kernel will be the only thing you query - not the CPUID insn. Then those names above become wrong/obsolete. > > And for the time being, I'd love if this were somewhere in > > arch/x86/kvm/cpuid.c so that it is clear how one should use those macros. > > I'll a patch with the above and more guidance. > > > The end goal of having the user not care about which macro to use would be the > > ultimate, super-duper thing tho. > > And impossible, for all intents and purposes. The user/contributor/developer > needs to define KVM's handling semantics *somehwere*. I still don't get this: why does KVM need to know whether a X86_FEATURE is scattered or synthesized or whatnot? > Sure, we could to that in a big array or something, but that's just > a different way of dressing up the same pig. All of this very much is an > ugly pig, but it's the concepts and mechanics that are ugly and convoluted. Well, if we're redoing how feature flags and CPUID leafs etc are being handled on baremetal, why not extend that handling so that KVM can put info there too, about each feature and how it is going to be exposed to the guest instead of doing a whole bucket of _F() macros? > E.g. if we define a giant array or table, the contributor will need to map the > feature to one of the above macros. We are on the way to a giant array/table anyway: https://lore.kernel.org/r/20250905121515.192792-1-darwi@linutronix.de > In other words, kvm_initialize_cpu_caps() _is_ the helper table. $ git grep kvm_initialize_cpu_caps $ I'm on current Linus/master. Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-10 20:07 ` Borislav Petkov @ 2026-02-10 23:48 ` Sean Christopherson 2026-02-11 13:32 ` Borislav Petkov 0 siblings, 1 reply; 19+ messages in thread From: Sean Christopherson @ 2026-02-10 23:48 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Tue, Feb 10, 2026, Borislav Petkov wrote: > On Mon, Feb 09, 2026 at 01:12:45PM -0800, Sean Christopherson wrote: > > On Mon, Feb 09, 2026, Borislav Petkov wrote: > > > On Mon, Feb 09, 2026 at 08:29:36AM -0800, Sean Christopherson wrote: > > > > Nope. KVM cares about what KVM can virtualize/emulate, and about helping userspace > > > > accurately represent the virtual CPU that will be enumerated to the guest. > > > > > > So why don't you key on that in those macros instead of how they're defined? > > > > > > EXPOSE_TO_GUEST_F() > > > > > > and then underneath we can figure out how to expose them. > > > > Huh? That's what the macros do, they describe KVM's handling of the associated > > feature. SYNTHESIZED is a bit weird because it bleeds some kernel details into > > KVM, but ultimately it's still KVM decision as to whether or not "forced" features > > can be synthesized for the guest. > > My point is that you have to know *which* macro of all the available ones you > need to use, in order to expose the feature. This thread is a case-in-point > example about how it can get confusing. And it dudn't have to... Yes, it did have to. These are the choices. Whether they're in raw C code, macro hell, or a spreadsheet, the choices remain the same. > > > We could have a helper table which determines what each feature is and how it > > > should interact with raw host CPUID or something slicker. > > > > > > > F : Features that must be present in boot_cpu_data and raw CPUID > > > > SCATTERED_F : Same as F(), but are scattered by the kernel > > Right, so what happens if we unscatter a leaf? The build will fail. Explicitly because of this: BUILD_BUG_ON(X86_FEATURE_##name >= MAX_CPU_FEATURES); \ and also because attempting to defined the CPUID_fn_idx_REG enum will collide with the existing enum in kvm_only_cpuid_leafs, and we'll go unscatter the KVM code. Even without those safeguards, everything would be totally fine, the "overhead" is negligible. In other words, scattered leafs require a bit of extra code to handle correctly in KVM, whereas normal F() leaves Just Work. > And why does it matter to KVM if the baremetal feature is scattered or not? > KVM should only care whether the kernel has set it or not. Because KVM needs to query features in _guest_ CPUID, and so the bit position must match the architectural values. KVM also cares if the feature is present in raw CPUID. E.g. X86_FEATURE_SGX1 is bit 8 in Linux-defined word 11. But in CPUID, SGX1 is bit 0 in CPUID.0x12.0.EAX. If KVM tried to query bit 8 in CPUID.0x12.0.EAX, it would read garbage. > > > > X86_64_F : Same as F(), but are restricted to 64-bit kernels > > > > EMULATED_F : Always supported; the feature is unconditionally emulated in software > > And an emulated feature *can* be scattered or synthesized or whatever... Yep. > > > > SYNTHESIZED_F : Features that must be present in boot_cpu_data, but may or > > > > may not be in raw CPUID. May also be scattered. > > So which one do I use here? > > This is the confusion I'm taking about. For the TSA stuff? SYNTHESIZED_F(), because KVM's ABI is to advertise support for the "features" even if they're not present in raw CPUID, so long as they're supported by the host kernel. > > > > PASSTHROUGH_F : Features that must be present in raw CPUID, but may or may > > > > not be present in boot_cpu_data > > Maybe there's a reason for it but why would the guest care if the feature is > present in raw CPUID or not? The hypervisor controls what the guest sees in > CPUID... The VMM controls what the guest sees, _KVM_ does not. > > > > ALIASED_1_EDX_F : Features in 0x8000_0001.EDX that are duplicates of identical 0x1.EDX features > > > > VENDOR_F : Features that are controlled by vendor code, often because > > > > they are guarded by a vendor specific module param. Rules > > > > vary, but typically they are handled like basic F() features > > > > RUNTIME_F : Features that KVM dynamically sets/clears at runtime, but that > > > > are never adveristed to userspace. E.g. OSXSAVE and OSPKE. > > > > > Also, we're rewriting the whole CPUID handling on baremetal and someday the > CPUID table in the kernel will be the only thing you query - not the CPUID > insn. Perhaps. But the only if the table provides both the kernel's configuration *and* raw CPUID, and is 100% comprehensive. And even if that happens, it won't change anything about KVM's macros, except I guess remove the need for SCATTERED_F() if the tables are truly comprehensive. > Then those names above become wrong/obsolete. No, because the concepts won't change. The code may look different, and KVM may need to #define a pile of things to do what it needs to do, but the semantics of how KVM supports various features isn't changing. > > > And for the time being, I'd love if this were somewhere in > > > arch/x86/kvm/cpuid.c so that it is clear how one should use those macros. > > > > I'll a patch with the above and more guidance. > > > > > The end goal of having the user not care about which macro to use would be the > > > ultimate, super-duper thing tho. > > > > And impossible, for all intents and purposes. The user/contributor/developer > > needs to define KVM's handling semantics *somehwere*. > > I still don't get this: why does KVM need to know whether a X86_FEATURE is > scattered or synthesized or whatnot? See above regarding scattered. As for synthesized, KVM is paranoid and so by default, requires features to be supported by the host kernel *and* present in raw CPUID in order to advertise support to the guest. Whether or not the paranoia is justified is arguable, but in practice it costs KVM almost nothing, and at the very least, IMO it's very helpful to document KVM's exact expectations/rules. > > Sure, we could to that in a big array or something, but that's just > > a different way of dressing up the same pig. All of this very much is an > > ugly pig, but it's the concepts and mechanics that are ugly and convoluted. > > Well, if we're redoing how feature flags and CPUID leafs etc are being handled > on baremetal, why not extend that handling so that KVM can put info there too, > about each feature and how it is going to be exposed to the guest instead of > doing a whole bucket of _F() macros? Because IMO, that would be a huge net negative. I have zero desire to go lookup a table to figure out KVM's rules for supporting a given feature, and even less desire to have to route KVM-internal changes through a giant shared table. I'm also skeptical that a table would provide as many safeguards as the macro magic, at least not without a lot more development. > > E.g. if we define a giant array or table, the contributor will need to map the > > feature to one of the above macros. > > We are on the way to a giant array/table anyway: > > https://lore.kernel.org/r/20250905121515.192792-1-darwi@linutronix.de Using something like that for the core kernel makes a lot of sense. But I don't see what would be gained by shoehorning KVM's ABI into that table. > > In other words, kvm_initialize_cpu_caps() _is_ the helper table. > > $ git grep kvm_initialize_cpu_caps > $ > > I'm on current Linus/master. Ah, sorry, it's kvm_set_cpu_caps() until this pull request: https://lore.kernel.org/all/20260207041011.913471-5-seanjc@google.com ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-10 23:48 ` Sean Christopherson @ 2026-02-11 13:32 ` Borislav Petkov 2026-02-11 15:54 ` Sean Christopherson 0 siblings, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-11 13:32 UTC (permalink / raw) To: Sean Christopherson Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Tue, Feb 10, 2026 at 03:48:56PM -0800, Sean Christopherson wrote: > See above regarding scattered. As for synthesized, KVM is paranoid and so by > default, requires features to be supported by the host kernel *and* present in > raw CPUID in order to advertise support to the guest. Yes, it will check for X86_FEATURE to be and then look at CPUID. > Because IMO, that would be a huge net negative. I have zero desire to go lookup > a table to figure out KVM's rules for supporting a given feature, and even less > desire to have to route KVM-internal changes through a giant shared table. I'm > also skeptical that a table would provide as many safeguards as the macro magic, > at least not without a lot more development. Lemme cut to the chase because it seems to me like my point is not coming across: We're changing how CPUID is handled on baremetal. Consider how much trouble there was and is between how the baremetal kernel handles CPUID features and how KVM wants to handle them and how those should be independent but they aren't and if we change baremetal handling - i.e., unscatter a leaf - we break KVM, yadda yadda, and all the friction over the years. Now we have the chance to define that cleanly and also accomodate KVM's needs. As in, you add a CPUID flag in baremetal and then in the representation of that flag in our internal structures, there are KVM-specific attributes which are used by it to do that feature flag's representation to guests. The new scheme will get rid of the scattered crap as it is not needed anymore - we'll have the *whole* CPUID leaf hierarchy. Now wouldn't it be lovely to have a .kvm_flags = EMULATED_F | X86_64_F ... RUNTIME_F which is per CPUID feature bit and which KVM code queries? SCATTERED_F, SYNTHESIZED_F, PASSTHROUGH_F become obsolete. No need for those macros, adding new CPUID feature flags would mean simply adding those .kvm_flags things which denote what KVM does with the feature. Not how it is defined internally. And then everything JustWorks(tm) naturally without having to deal with those macros. And you'd get rid of the KVM-only CPUID leafs too because everything will be in one central place. Now why wouldn't you want that wonderful and charming thing?! :-) -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-11 13:32 ` Borislav Petkov @ 2026-02-11 15:54 ` Sean Christopherson 2026-02-11 16:17 ` Borislav Petkov 0 siblings, 1 reply; 19+ messages in thread From: Sean Christopherson @ 2026-02-11 15:54 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Wed, Feb 11, 2026, Borislav Petkov wrote: > On Tue, Feb 10, 2026 at 03:48:56PM -0800, Sean Christopherson wrote: > > See above regarding scattered. As for synthesized, KVM is paranoid and so by > > default, requires features to be supported by the host kernel *and* present in > > raw CPUID in order to advertise support to the guest. > > Yes, it will check for X86_FEATURE to be and then look at CPUID. > > > Because IMO, that would be a huge net negative. I have zero desire to go lookup > > a table to figure out KVM's rules for supporting a given feature, and even less > > desire to have to route KVM-internal changes through a giant shared table. I'm > > also skeptical that a table would provide as many safeguards as the macro magic, > > at least not without a lot more development. > > Lemme cut to the chase because it seems to me like my point is not coming > across: I understand what the goal is, I just don't want to buy what you're selling. > We're changing how CPUID is handled on baremetal. Consider how much trouble > there was and is between how the baremetal kernel handles CPUID features and > how KVM wants to handle them and how those should be independent but they > aren't and if we change baremetal handling - i.e., unscatter a leaf - we break > KVM, yadda yadda, and all the friction over the years. Those problems are _entirely_ limited to the fact that the kernel's feature tracking isn't 100% comprehensive. It's completely orthogonal to KVM's enumeration of its supported feature. > Now we have the chance to define that cleanly and also accomodate KVM's needs. > > As in, you add a CPUID flag in baremetal and then in the representation of > that flag in our internal structures, there are KVM-specific attributes which > are used by it to do that feature flag's representation to guests. > > The new scheme will get rid of the scattered crap as it is not needed anymore > - we'll have the *whole* CPUID leaf hierarchy. Now wouldn't it be lovely to > have a > > .kvm_flags = EMULATED_F | X86_64_F ... RUNTIME_F > > which is per CPUID feature bit and which KVM code queries? No, it honestly sounds rather awful. > SCATTERED_F, SYNTHESIZED_F, PASSTHROUGH_F become obsolete. SCATTERED_F will become obsolete, SYNTHESIZED_F and PASSTHROUGH_F will not. They cannot. It's impossible to express three states with one bit. SYNTHESIZED_F PASSTHROUGH_F F raw CPUID DONT_CARE Y Y kernel caps Y DONT_CARE Y If the kernel tracks both raw CPUID *and* kernel caps, then KVM can use the table without having to (re)do CPUID when configuring KVM's feature set. But KVM would still need to have processing for SYNTHESIZED_F, PASSTHROUGH_F, and F, to derive the correct state from the raw+kernel tables. > No need for those macros, adding new CPUID feature flags would mean simply > adding those .kvm_flags things which denote what KVM does with the feature. > Not how it is defined internally. > > And then everything JustWorks(tm) naturally without having to deal with those > macros. > > And you'd get rid of the KVM-only CPUID leafs too because everything will be > in one central place. Again, that's achieved purely by tracking the full CPUID hierarchy. It has nothing to do with EMULATED_F, X86_64_F, RUNTIME_F, SYNTHESIZED_F, PASSTHROUGH_F, etc. > Now why wouldn't you want that wonderful and charming thing?! Because from my perspective, centralizing *everything* is all pain, no gain. It would bleed KVM details into the broader kernel, unnecessarily limit KVM's ability to change how KVM emulates/virtualizes features, and require querying a lookaside table to understand KVM's rules/handling. No thanks. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-11 15:54 ` Sean Christopherson @ 2026-02-11 16:17 ` Borislav Petkov 2026-02-11 16:28 ` Sean Christopherson 0 siblings, 1 reply; 19+ messages in thread From: Borislav Petkov @ 2026-02-11 16:17 UTC (permalink / raw) To: Sean Christopherson Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Wed, Feb 11, 2026 at 07:54:30AM -0800, Sean Christopherson wrote: > Those problems are _entirely_ limited to the fact that the kernel's feature tracking > isn't 100% comprehensive. Thus the rewrite. :) > If the kernel tracks both raw CPUID *and* kernel caps, then KVM can use the > table without having to (re)do CPUID when configuring KVM's feature set. But > KVM would still need to have processing for SYNTHESIZED_F, PASSTHROUGH_F, and F, > to derive the correct state from the raw+kernel tables. That's what I meant - the macros and the confusion which one to use would go away. > Because from my perspective, centralizing *everything* is all pain, no gain. It > would bleed KVM details into the broader kernel, unnecessarily limit KVM's ability > to change how KVM emulates/virtualizes features, and require querying a lookaside > table to understand KVM's rules/handling. No thanks. The point is not to limit KVM's ability but *augment* the internal representation so that it *accomodates* KVM fully. But ok, your call. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-11 16:17 ` Borislav Petkov @ 2026-02-11 16:28 ` Sean Christopherson 0 siblings, 0 replies; 19+ messages in thread From: Sean Christopherson @ 2026-02-11 16:28 UTC (permalink / raw) To: Borislav Petkov Cc: Carlos López, Jim Mattson, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT), Babu Moger On Wed, Feb 11, 2026, Borislav Petkov wrote: > On Wed, Feb 11, 2026 at 07:54:30AM -0800, Sean Christopherson wrote: > > If the kernel tracks both raw CPUID *and* kernel caps, then KVM can use the > > table without having to (re)do CPUID when configuring KVM's feature set. But > > KVM would still need to have processing for SYNTHESIZED_F, PASSTHROUGH_F, and F, > > to derive the correct state from the raw+kernel tables. > > That's what I meant - the macros and the confusion which one to use would go > away. Again, the macros would go away, but they would simply be replaced by labels in a table. I.e. the "confusion" won't go away, because it can't simply disappear. That knowledge must live somewhere. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-08 16:42 [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() Carlos López 2026-02-08 18:28 ` Borislav Petkov @ 2026-02-09 10:02 ` Binbin Wu 2026-02-09 11:43 ` Carlos López 1 sibling, 1 reply; 19+ messages in thread From: Binbin Wu @ 2026-02-09 10:02 UTC (permalink / raw) To: Carlos López, seanjc Cc: bp, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT) On 2/9/2026 12:42 AM, Carlos López wrote: > KVM incorrectly synthesizes TSA_SQ_NO and TSA_L1_NO when running > on AMD Family 19h CPUs by using SYNTHESIZED_F(), which unconditionally > enables features for KVM-only CPUID leaves (as is the case with > CPUID_8000_0021_ECX), regardless of the kernel's synthesis logic in > tsa_init(). This is due to the following logic in kvm_cpu_cap_init(): > > if (leaf < NCAPINTS) > kvm_cpu_caps[leaf] &= kernel_cpu_caps[leaf]; Since TSA_SQ_NO and TSA_L1_NO are defined in CPUID_8000_0021_ECX, and CPUID_8000_0021_ECX > NCAPINTS, the code above doesn't take effect. The code makes the two bits set unconditionally is: SYNTHESIZED_F() sets kvm_cpu_cap_synthesized and later kvm_cpu_caps[leaf] &= (raw_cpuid_get(cpuid) | kvm_cpu_cap_synthesized); > > This can cause an unexpected failure on Family 19h CPUs during SEV-SNP > guest setup, when userspace issues SNP_LAUNCH_UPDATE, as setting these > bits in the CPUID page on vulnerable CPUs is explicitly rejected by SNP > firmware. > > Switch to SCATTERED_F(), so that the bits are only set if the features > have been force-set by the kernel in tsa_init(), or if they are reported > in the raw CPUID. When you switch to SCATTERED_F(), if the two bits are not in raw cpuid, the two bits will not be set to kvm_cpu_caps[CPUID_8000_0021_ECX], regardless the setting initialized in tsa_init(). TSA_SQ_NO and TSA_L1_NO are conditional kernel synthesis bits, should SYNTHESIZED_F() check that the related bit is actually synthesized into boot_cpu_data before setting to kvm_cpu_cap_synthesized? > > Fixes: 31272abd5974 ("KVM: SVM: Advertise TSA CPUID bits to guests") > Signed-off-by: Carlos López <clopez@suse.de> > --- > arch/x86/kvm/cpuid.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > index 88a5426674a1..819c176e02ff 100644 > --- a/arch/x86/kvm/cpuid.c > +++ b/arch/x86/kvm/cpuid.c > @@ -1230,8 +1230,8 @@ void kvm_set_cpu_caps(void) > ); > > kvm_cpu_cap_init(CPUID_8000_0021_ECX, > - SYNTHESIZED_F(TSA_SQ_NO), > - SYNTHESIZED_F(TSA_L1_NO), > + SCATTERED_F(TSA_SQ_NO), > + SCATTERED_F(TSA_L1_NO), > ); > > kvm_cpu_cap_init(CPUID_8000_0022_EAX, > > base-commit: 0de4a0eec25b9171f2a2abb1a820e125e6797770 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() 2026-02-09 10:02 ` Binbin Wu @ 2026-02-09 11:43 ` Carlos López 0 siblings, 0 replies; 19+ messages in thread From: Carlos López @ 2026-02-09 11:43 UTC (permalink / raw) To: Binbin Wu, seanjc Cc: bp, kvm, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin, open list:X86 ARCHITECTURE (32-BIT AND 64-BIT) Hi, On 2/9/26 11:02 AM, Binbin Wu wrote: > > > On 2/9/2026 12:42 AM, Carlos López wrote: >> KVM incorrectly synthesizes TSA_SQ_NO and TSA_L1_NO when running >> on AMD Family 19h CPUs by using SYNTHESIZED_F(), which unconditionally >> enables features for KVM-only CPUID leaves (as is the case with >> CPUID_8000_0021_ECX), regardless of the kernel's synthesis logic in >> tsa_init(). This is due to the following logic in kvm_cpu_cap_init(): >> >> if (leaf < NCAPINTS) >> kvm_cpu_caps[leaf] &= kernel_cpu_caps[leaf]; > > Since TSA_SQ_NO and TSA_L1_NO are defined in CPUID_8000_0021_ECX, and > CPUID_8000_0021_ECX > NCAPINTS, the code above doesn't take effect. I should have explained it better, but that is precisely what I meant. Since the &= never takes place, kvm_cpu_cap_features always has the bits set. In other words: the branch always evaluates to false for KVM-only CPUID leaves, so the bits are always set. > The code makes the two bits set unconditionally is: > SYNTHESIZED_F() sets kvm_cpu_cap_synthesized > and later > kvm_cpu_caps[leaf] &= (raw_cpuid_get(cpuid) | > kvm_cpu_cap_synthesized); > >> >> This can cause an unexpected failure on Family 19h CPUs during SEV-SNP >> guest setup, when userspace issues SNP_LAUNCH_UPDATE, as setting these >> bits in the CPUID page on vulnerable CPUs is explicitly rejected by SNP >> firmware. >> >> Switch to SCATTERED_F(), so that the bits are only set if the features >> have been force-set by the kernel in tsa_init(), or if they are reported >> in the raw CPUID. > > When you switch to SCATTERED_F(), if the two bits are not in raw cpuid, the two > bits will not be set to kvm_cpu_caps[CPUID_8000_0021_ECX], regardless the > setting initialized in tsa_init(). Yes, I think you're right. > TSA_SQ_NO and TSA_L1_NO are conditional kernel synthesis bits, should > SYNTHESIZED_F() check that the related bit is actually synthesized into > boot_cpu_data before setting to kvm_cpu_cap_synthesized? Right, I thought this is what SCATTERED_F() already did, but I missed that there is the logical AND with the raw CPUID later. See the diff in my reply to Jim Mattson, I think that is what you propose as well. ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-02-11 16:28 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-08 16:42 [PATCH] KVM: x86: synthesize TSA CPUID bits via SCATTERED_F() Carlos López 2026-02-08 18:28 ` Borislav Petkov 2026-02-08 20:50 ` Jim Mattson 2026-02-08 21:13 ` Borislav Petkov 2026-02-09 5:48 ` Jim Mattson 2026-02-09 11:40 ` Carlos López 2026-02-09 15:06 ` Sean Christopherson 2026-02-09 15:32 ` Borislav Petkov 2026-02-09 16:29 ` Sean Christopherson 2026-02-09 17:45 ` Borislav Petkov 2026-02-09 21:12 ` Sean Christopherson 2026-02-10 20:07 ` Borislav Petkov 2026-02-10 23:48 ` Sean Christopherson 2026-02-11 13:32 ` Borislav Petkov 2026-02-11 15:54 ` Sean Christopherson 2026-02-11 16:17 ` Borislav Petkov 2026-02-11 16:28 ` Sean Christopherson 2026-02-09 10:02 ` Binbin Wu 2026-02-09 11:43 ` Carlos López
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox