* [PATCH 0/2] x86/topology: Add support for Low Power cpu_type
@ 2026-06-29 9:43 Vishal Badole
2026-06-29 9:43 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Vishal Badole
2026-06-29 9:43 ` [PATCH 2/2] x86/topology: Add TOPO_CPU_TYPE_LOW_POWER Vishal Badole
0 siblings, 2 replies; 25+ messages in thread
From: Vishal Badole @ 2026-06-29 9:43 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, hpa, rafael, lenb
Cc: linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae,
wei.w.wang, Vishal Badole
This series extends the x86 topology cpu_type classification to support
a Low Power core type, in addition to the existing Performance and
Efficiency types.
AMD heterogeneous parts report the core type via CPUID Fn0x80000026
EBX[31:28] (Extended CPU Topology, Core Type). Value 2 identifies a
low-power core designed for minimal power consumption during background
or idle workloads. Distinguishing it from a regular efficiency core
matters for:
- user space exposure via /sys/kernel/debug/x86/topo/cpus/*, which
today reports cpu_type "unknown" for low-power cores
- amd_get_boost_ratio_numerator(): on every
X86_FEATURE_AMD_HTR_CORES-capable AMD/Hygon part, low-power cores
must scale by amd_get_highest_perf() rather than the fixed
CPPC_HIGHEST_PERF_PERFORMANCE ceiling, matching the existing
efficiency-core path
The series is structured as:
1/2 Pre-patch: replace the bare 0/1 in get_topology_cpu_type() with
named enum amd_cpu_type constants, mirroring the existing Intel
side. No functional change.
2/2 Add TOPO_CPU_TYPE_LOW_POWER, wire it through
get_topology_cpu_type(), get_topology_cpu_type_name() and the
switch in amd_get_boost_ratio_numerator() so allmodconfig builds
cleanly under -Werror=switch.
Vishal Badole (2):
x86/topology: Name the AMD core-type values
x86/topology: Add TOPO_CPU_TYPE_LOW_POWER
arch/x86/include/asm/topology.h | 7 +++++++
arch/x86/kernel/acpi/cppc.c | 3 ++-
arch/x86/kernel/cpu/topology_common.c | 7 +++++--
3 files changed, 14 insertions(+), 3 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 25+ messages in thread* [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-06-29 9:43 [PATCH 0/2] x86/topology: Add support for Low Power cpu_type Vishal Badole @ 2026-06-29 9:43 ` Vishal Badole 2026-07-02 0:27 ` Borislav Petkov 2026-06-29 9:43 ` [PATCH 2/2] x86/topology: Add TOPO_CPU_TYPE_LOW_POWER Vishal Badole 1 sibling, 1 reply; 25+ messages in thread From: Vishal Badole @ 2026-06-29 9:43 UTC (permalink / raw) To: tglx, mingo, bp, dave.hansen, x86, hpa, rafael, lenb Cc: linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang, Vishal Badole Replace the bare 0/1 in get_topology_cpu_type() with named constants that mirror what the AMD APM publishes for CPUID Fn0x80000026 EBX[31:28] (Extended CPU Topology, Core Type): 0 - Performance core 1 - Efficient core 2 - Low-power core (used by a follow-up) No functional change. Suggested-by: Borislav Petkov (AMD) <bp@alien8.de> Signed-off-by: Vishal Badole <Vishal.Badole@amd.com> --- arch/x86/include/asm/topology.h | 6 ++++++ arch/x86/kernel/cpu/topology_common.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 0ba9bdb99871..9658b5676ce6 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -120,6 +120,12 @@ enum x86_topology_cpu_type { TOPO_CPU_TYPE_UNKNOWN, }; +enum amd_cpu_type { + AMD_CPU_TYPE_PERFORMANCE = 0, + AMD_CPU_TYPE_EFFICIENCY = 1, + AMD_CPU_TYPE_LOW_POWER = 2, +}; + struct x86_topology_system { unsigned int dom_shifts[TOPO_MAX_DOMAIN]; unsigned int dom_size[TOPO_MAX_DOMAIN]; diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c index cf7513416b70..e1cc25a115ca 100644 --- a/arch/x86/kernel/cpu/topology_common.c +++ b/arch/x86/kernel/cpu/topology_common.c @@ -42,8 +42,8 @@ enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c) } if (c->x86_vendor == X86_VENDOR_AMD) { switch (c->topo.amd_type) { - case 0: return TOPO_CPU_TYPE_PERFORMANCE; - case 1: return TOPO_CPU_TYPE_EFFICIENCY; + case AMD_CPU_TYPE_PERFORMANCE: return TOPO_CPU_TYPE_PERFORMANCE; + case AMD_CPU_TYPE_EFFICIENCY: return TOPO_CPU_TYPE_EFFICIENCY; } } -- 2.34.1 ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-06-29 9:43 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Vishal Badole @ 2026-07-02 0:27 ` Borislav Petkov 2026-07-02 22:06 ` Thomas Gleixner 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-02 0:27 UTC (permalink / raw) To: Vishal Badole, dave.hansen, tglx Cc: mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Mon, Jun 29, 2026 at 03:13:48PM +0530, Vishal Badole wrote: > Replace the bare 0/1 in get_topology_cpu_type() with named constants > that mirror what the AMD APM publishes for CPUID Fn0x80000026 > EBX[31:28] (Extended CPU Topology, Core Type): > > 0 - Performance core > 1 - Efficient core > 2 - Low-power core (used by a follow-up) > > No functional change. > > Suggested-by: Borislav Petkov (AMD) <bp@alien8.de> > Signed-off-by: Vishal Badole <Vishal.Badole@amd.com> > --- > arch/x86/include/asm/topology.h | 6 ++++++ > arch/x86/kernel/cpu/topology_common.c | 4 ++-- > 2 files changed, 8 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h > index 0ba9bdb99871..9658b5676ce6 100644 > --- a/arch/x86/include/asm/topology.h > +++ b/arch/x86/include/asm/topology.h > @@ -120,6 +120,12 @@ enum x86_topology_cpu_type { > TOPO_CPU_TYPE_UNKNOWN, > }; > > +enum amd_cpu_type { > + AMD_CPU_TYPE_PERFORMANCE = 0, Sashiko says here: --- Will this break CPU matching if a driver attempts to target only AMD performance cores? The x86_cpu_id matching infrastructure treats 0 as the X86_CPU_TYPE_ANY wildcard. If a developer uses AMD_CPU_TYPE_PERFORMANCE (which evaluates to 0) in an x86_cpu_id match table, the infrastructure will interpret it as a wildcard: arch/x86/kernel/cpu/match.c:x86_match_vendor_cpu_type() { ... if (m->type == X86_CPU_TYPE_ANY) return true; ... } Could this cause drivers to silently bind to all AMD core types, including efficiency and low-power cores, instead of just the performance cores? --- see https://sashiko.dev/#/patchset/20260629094349.533301-1-Vishal.Badole%40amd.com And it does make sense to me - x86_match_vendor_cpu_type() is supposed to receive the *hardware* defined CPU type - not the generic ones. And I think that was a mistake because the value 0 on AMD means a performance core type but in the kernel we called it X86_CPU_TYPE_ANY. Which is also not surprising - all our ANY types are 0. Now, one fix would be if we define X86_CPU_TYPE_ANY as 0xff and hope that Intel will never define it. On AMD that value is guaranteed to be invalid because the core type field is only 4 bits. But it can happen that one vendor's core type field can match another core type of the other vendor. Which would mean that we cannot use X86_VENDOR_ANY in any of the match_id tables when using a core type. Or, we do the proper fix and we map all vendor core types to the kernel's, vendor-agnostic TOPO_CPU_TYPE_* enums and then we're all good - we'd only need to convert the vendor ones to the generic ones on comparison but we do that anyway. Thoughts? > + AMD_CPU_TYPE_EFFICIENCY = 1, > + AMD_CPU_TYPE_LOW_POWER = 2, > +}; > + > struct x86_topology_system { > unsigned int dom_shifts[TOPO_MAX_DOMAIN]; > unsigned int dom_size[TOPO_MAX_DOMAIN]; > diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c > index cf7513416b70..e1cc25a115ca 100644 > --- a/arch/x86/kernel/cpu/topology_common.c > +++ b/arch/x86/kernel/cpu/topology_common.c > @@ -42,8 +42,8 @@ enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c) > } > if (c->x86_vendor == X86_VENDOR_AMD) { > switch (c->topo.amd_type) { > - case 0: return TOPO_CPU_TYPE_PERFORMANCE; > - case 1: return TOPO_CPU_TYPE_EFFICIENCY; > + case AMD_CPU_TYPE_PERFORMANCE: return TOPO_CPU_TYPE_PERFORMANCE; > + case AMD_CPU_TYPE_EFFICIENCY: return TOPO_CPU_TYPE_EFFICIENCY; > } > } > > -- > 2.34.1 > -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-02 0:27 ` Borislav Petkov @ 2026-07-02 22:06 ` Thomas Gleixner 2026-07-02 23:03 ` Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Thomas Gleixner @ 2026-07-02 22:06 UTC (permalink / raw) To: Borislav Petkov, Vishal Badole, dave.hansen Cc: mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 01 2026 at 17:27, Borislav Petkov wrote: > On Mon, Jun 29, 2026 at 03:13:48PM +0530, Vishal Badole wrote: > And it does make sense to me - x86_match_vendor_cpu_type() is supposed to > receive the *hardware* defined CPU type - not the generic ones. And I think > that was a mistake because the value 0 on AMD means a performance core type > but in the kernel we called it X86_CPU_TYPE_ANY. Which is also not surprising > - all our ANY types are 0. > > Now, one fix would be if we define X86_CPU_TYPE_ANY as 0xff and hope that > Intel will never define it. > > On AMD that value is guaranteed to be invalid because the core type field is > only 4 bits. > > But it can happen that one vendor's core type field can match another core > type of the other vendor. Which would mean that we cannot use X86_VENDOR_ANY > in any of the match_id tables when using a core type. > > Or, we do the proper fix and we map all vendor core types to the kernel's, > vendor-agnostic TOPO_CPU_TYPE_* enums and then we're all good - we'd only need > to convert the vendor ones to the generic ones on comparison but we do that > anyway. Just do the mapping to vendor-agnostic types _once_ when you enumerate the CPU and store that information in the per CPU data. Then you can do proper vendor agnostic matching against that and define the TYPE_ANY value as you want without ever colliding with vendor muck. As a bonus get_topology_cpu_type() goes away too as the translation has been done already. Thanks, tglx ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-02 22:06 ` Thomas Gleixner @ 2026-07-02 23:03 ` Borislav Petkov 2026-07-03 19:32 ` Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-02 23:03 UTC (permalink / raw) To: Thomas Gleixner Cc: Vishal Badole, dave.hansen, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Fri, Jul 03, 2026 at 12:06:32AM +0200, Thomas Gleixner wrote: > Just do the mapping to vendor-agnostic types _once_ when you enumerate the CPU > and store that information in the per CPU data. > > Then you can do proper vendor agnostic matching against that and define > the TYPE_ANY value as you want without ever colliding with vendor > muck. > > As a bonus get_topology_cpu_type() goes away too as the translation has > been done already. Yeah, we should've done it from the very beginning this way. Lemme hack it up and see how it looks like. Thanks for the cool idea. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-02 23:03 ` Borislav Petkov @ 2026-07-03 19:32 ` Borislav Petkov 2026-07-03 19:39 ` Thomas Gleixner ` (2 more replies) 0 siblings, 3 replies; 25+ messages in thread From: Borislav Petkov @ 2026-07-03 19:32 UTC (permalink / raw) To: Thomas Gleixner, dave.hansen, Pawan Gupta Cc: Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang + Dave and Pawan. On Thu, Jul 02, 2026 at 04:03:37PM -0700, Borislav Petkov wrote: > On Fri, Jul 03, 2026 at 12:06:32AM +0200, Thomas Gleixner wrote: > > Just do the mapping to vendor-agnostic types _once_ when you enumerate the CPU > > and store that information in the per CPU data. > > > > Then you can do proper vendor agnostic matching against that and define > > the TYPE_ANY value as you want without ever colliding with vendor > > muck. > > > > As a bonus get_topology_cpu_type() goes away too as the translation has > > been done already. > > Yeah, we should've done it from the very beginning this way. Lemme hack it up > and see how it looks like. > > Thanks for the cool idea. Something like the totally untested below - but it builds at least. We've allocated a u8 for the struct x86_cpu_id member type and we compare that to enum x86_topology_cpu_type cpu_type. I guess that's ok for now... There's potential for more cleanup by removing the ->intel_type and ->amd_type and converting them all to our internal represenation of CPU_TYPE but that's for later and other patches anyway. Thoughts? diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 8d8f890c4bc0..746822bd71fb 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -68,9 +68,13 @@ extern u16 __read_mostly tlb_lld_2m; extern u16 __read_mostly tlb_lld_4m; extern u16 __read_mostly tlb_lld_1g; -/* - * CPU type and hardware bug flags. Kept separately for each CPU. - */ +enum x86_topology_cpu_type { + /* X86_CPU_TYPE_ANY */ + TOPO_CPU_TYPE_ANY = 0, + TOPO_CPU_TYPE_PERFORMANCE, + TOPO_CPU_TYPE_EFFICIENCY, + TOPO_CPU_TYPE_UNKNOWN, +}; struct cpuinfo_topology { // Real APIC ID read from the local APIC @@ -104,7 +108,7 @@ struct cpuinfo_topology { // Hardware defined CPU-type union { - u32 cpu_type; + u32 hw_cpu_type; struct { // CPUID.1A.EAX[23-0] u32 intel_native_model_id :24; @@ -119,8 +123,14 @@ struct cpuinfo_topology { amd_type :4; }; }; + + // Linux vendor-agnostic CPU type + enum x86_topology_cpu_type cpu_type; }; +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + */ struct cpuinfo_x86 { union { /* diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 8fb61d2465eb..ef76ba674f1b 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -114,12 +114,6 @@ enum x86_topology_domains { TOPO_MAX_DOMAIN, }; -enum x86_topology_cpu_type { - TOPO_CPU_TYPE_PERFORMANCE, - TOPO_CPU_TYPE_EFFICIENCY, - TOPO_CPU_TYPE_UNKNOWN, -}; - struct x86_topology_system { unsigned int dom_shifts[TOPO_MAX_DOMAIN]; unsigned int dom_size[TOPO_MAX_DOMAIN]; @@ -160,7 +154,6 @@ extern unsigned int __num_nodes_per_package; struct cpuinfo_x86; const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); -enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); static inline unsigned int topology_max_packages(void) { diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index be4c5e9e5ff6..b8f5dd0a8117 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -241,7 +241,6 @@ EXPORT_SYMBOL_GPL(amd_detect_prefcore); */ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) { - enum x86_topology_cpu_type core_type = get_topology_cpu_type(&cpu_data(cpu)); bool prefcore; int ret; u32 tmp; @@ -273,8 +272,9 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) /* detect if running on heterogeneous design */ if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { - switch (core_type) { + switch (cpu_data(cpu).topo.cpu_type) { case TOPO_CPU_TYPE_UNKNOWN: + case TOPO_CPU_TYPE_ANY: pr_warn("Undefined core type found for cpu %d\n", cpu); break; case TOPO_CPU_TYPE_PERFORMANCE: diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index 4604802692da..7ab077f0cc66 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -5,34 +5,6 @@ #include <linux/export.h> #include <linux/slab.h> -/** - * x86_match_vendor_cpu_type - helper function to match the hardware defined - * cpu-type for a single entry in the x86_cpu_id - * table. Note, this function does not match the - * generic cpu-types TOPO_CPU_TYPE_EFFICIENCY and - * TOPO_CPU_TYPE_PERFORMANCE. - * @c: Pointer to the cpuinfo_x86 structure of the CPU to match. - * @m: Pointer to the x86_cpu_id entry to match against. - * - * Return: true if the cpu-type matches, false otherwise. - */ -static bool x86_match_vendor_cpu_type(struct cpuinfo_x86 *c, const struct x86_cpu_id *m) -{ - if (m->type == X86_CPU_TYPE_ANY) - return true; - - /* Hybrid CPUs are special, they are assumed to match all cpu-types */ - if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) - return true; - - if (c->x86_vendor == X86_VENDOR_INTEL) - return m->type == c->topo.intel_type; - if (c->x86_vendor == X86_VENDOR_AMD) - return m->type == c->topo.amd_type; - - return false; -} - /** * x86_match_cpu - match current CPU against an array of x86_cpu_ids * @match: Pointer to array of x86_cpu_ids. Last entry terminated with @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) continue; if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) continue; - if (!x86_match_vendor_cpu_type(c, m)) + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) continue; return m; } diff --git a/arch/x86/kernel/cpu/topology.h b/arch/x86/kernel/cpu/topology.h index 37326297f80c..74e02bacd854 100644 --- a/arch/x86/kernel/cpu/topology.h +++ b/arch/x86/kernel/cpu/topology.h @@ -22,6 +22,7 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, bool cpu_parse_topology_ext(struct topo_scan *tscan); void cpu_parse_topology_amd(struct topo_scan *tscan); void cpu_topology_fixup_amd(struct topo_scan *tscan); +enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom) { diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c index da080d732e10..c5a6944df86a 100644 --- a/arch/x86/kernel/cpu/topology_amd.c +++ b/arch/x86/kernel/cpu/topology_amd.c @@ -177,8 +177,10 @@ static void topoext_fixup(struct topo_scan *tscan) static void parse_topology_amd(struct topo_scan *tscan) { - if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) - tscan->c->topo.cpu_type = cpuid_ebx(0x80000026); + if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { + tscan->c->topo.hw_cpu_type = cpuid_ebx(0x80000026); + tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c); + } /* * Try to get SMT, CORE, TILE, and DIE shifts from extended diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c index cf7513416b70..b9d025f3373a 100644 --- a/arch/x86/kernel/cpu/topology_common.c +++ b/arch/x86/kernel/cpu/topology_common.c @@ -168,8 +168,12 @@ static void parse_topology(struct topo_scan *tscan, bool early) case X86_VENDOR_INTEL: if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan)) parse_legacy(tscan); - if (c->cpuid_level >= 0x1a) - c->topo.cpu_type = cpuid_eax(0x1a); + + if (c->cpuid_level >= 0x1a) { + c->topo.hw_cpu_type = cpuid_eax(0x1a); + c->topo.cpu_type = get_topology_cpu_type(c); + } + break; } } -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-03 19:32 ` Borislav Petkov @ 2026-07-03 19:39 ` Thomas Gleixner 2026-07-06 18:29 ` Pawan Gupta 2026-07-21 9:08 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Badole, Vishal 2 siblings, 0 replies; 25+ messages in thread From: Thomas Gleixner @ 2026-07-03 19:39 UTC (permalink / raw) To: Borislav Petkov, dave.hansen, Pawan Gupta Cc: Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Fri, Jul 03 2026 at 12:32, Borislav Petkov wrote: > Something like the totally untested below - but it builds at least. > > We've allocated a u8 for the struct x86_cpu_id member type and we compare that > to enum x86_topology_cpu_type cpu_type. I guess that's ok for now... > > There's potential for more cleanup by removing the ->intel_type and ->amd_type > and converting them all to our internal represenation of CPU_TYPE but that's > for later and other patches anyway. > > Thoughts? Looks reasonable to me and should avoid all the nonsense you had to work around before. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-03 19:32 ` Borislav Petkov 2026-07-03 19:39 ` Thomas Gleixner @ 2026-07-06 18:29 ` Pawan Gupta 2026-07-07 0:47 ` Borislav Petkov 2026-07-21 9:08 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Badole, Vishal 2 siblings, 1 reply; 25+ messages in thread From: Pawan Gupta @ 2026-07-06 18:29 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Fri, Jul 03, 2026 at 12:32:22PM -0700, Borislav Petkov wrote: > + Dave and Pawan. > > On Thu, Jul 02, 2026 at 04:03:37PM -0700, Borislav Petkov wrote: > > On Fri, Jul 03, 2026 at 12:06:32AM +0200, Thomas Gleixner wrote: > > > Just do the mapping to vendor-agnostic types _once_ when you enumerate the CPU > > > and store that information in the per CPU data. > > > > > > Then you can do proper vendor agnostic matching against that and define > > > the TYPE_ANY value as you want without ever colliding with vendor > > > muck. > > > > > > As a bonus get_topology_cpu_type() goes away too as the translation has > > > been done already. > > > > Yeah, we should've done it from the very beginning this way. Lemme hack it up > > and see how it looks like. > > > > Thanks for the cool idea. > > Something like the totally untested below - but it builds at least. > > We've allocated a u8 for the struct x86_cpu_id member type and we compare that > to enum x86_topology_cpu_type cpu_type. I guess that's ok for now... > > There's potential for more cleanup by removing the ->intel_type and ->amd_type > and converting them all to our internal represenation of CPU_TYPE but that's > for later and other patches anyway. > > Thoughts? > > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h > index 8d8f890c4bc0..746822bd71fb 100644 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -68,9 +68,13 @@ extern u16 __read_mostly tlb_lld_2m; > extern u16 __read_mostly tlb_lld_4m; > extern u16 __read_mostly tlb_lld_1g; > > -/* > - * CPU type and hardware bug flags. Kept separately for each CPU. > - */ > +enum x86_topology_cpu_type { > + /* X86_CPU_TYPE_ANY */ > + TOPO_CPU_TYPE_ANY = 0, > + TOPO_CPU_TYPE_PERFORMANCE, > + TOPO_CPU_TYPE_EFFICIENCY, > + TOPO_CPU_TYPE_UNKNOWN, > +}; > > struct cpuinfo_topology { > // Real APIC ID read from the local APIC > @@ -104,7 +108,7 @@ struct cpuinfo_topology { > > // Hardware defined CPU-type > union { > - u32 cpu_type; > + u32 hw_cpu_type; > struct { > // CPUID.1A.EAX[23-0] > u32 intel_native_model_id :24; > @@ -119,8 +123,14 @@ struct cpuinfo_topology { > amd_type :4; > }; > }; > + > + // Linux vendor-agnostic CPU type > + enum x86_topology_cpu_type cpu_type; This looks good to me. However, we need to take care of some special cases like ... > }; > > +/* > + * CPU type and hardware bug flags. Kept separately for each CPU. > + */ > struct cpuinfo_x86 { > union { > /* > diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h > index 8fb61d2465eb..ef76ba674f1b 100644 > --- a/arch/x86/include/asm/topology.h > +++ b/arch/x86/include/asm/topology.h > @@ -114,12 +114,6 @@ enum x86_topology_domains { > TOPO_MAX_DOMAIN, > }; > > -enum x86_topology_cpu_type { > - TOPO_CPU_TYPE_PERFORMANCE, > - TOPO_CPU_TYPE_EFFICIENCY, > - TOPO_CPU_TYPE_UNKNOWN, > -}; > - > struct x86_topology_system { > unsigned int dom_shifts[TOPO_MAX_DOMAIN]; > unsigned int dom_size[TOPO_MAX_DOMAIN]; > @@ -160,7 +154,6 @@ extern unsigned int __num_nodes_per_package; > struct cpuinfo_x86; > > const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); > -enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); > > static inline unsigned int topology_max_packages(void) > { > diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c > index be4c5e9e5ff6..b8f5dd0a8117 100644 > --- a/arch/x86/kernel/acpi/cppc.c > +++ b/arch/x86/kernel/acpi/cppc.c > @@ -241,7 +241,6 @@ EXPORT_SYMBOL_GPL(amd_detect_prefcore); > */ > int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) > { > - enum x86_topology_cpu_type core_type = get_topology_cpu_type(&cpu_data(cpu)); > bool prefcore; > int ret; > u32 tmp; > @@ -273,8 +272,9 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) > > /* detect if running on heterogeneous design */ > if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { > - switch (core_type) { > + switch (cpu_data(cpu).topo.cpu_type) { > case TOPO_CPU_TYPE_UNKNOWN: > + case TOPO_CPU_TYPE_ANY: > pr_warn("Undefined core type found for cpu %d\n", cpu); > break; > case TOPO_CPU_TYPE_PERFORMANCE: > diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c > index 4604802692da..7ab077f0cc66 100644 > --- a/arch/x86/kernel/cpu/match.c > +++ b/arch/x86/kernel/cpu/match.c > @@ -5,34 +5,6 @@ > #include <linux/export.h> > #include <linux/slab.h> > > -/** > - * x86_match_vendor_cpu_type - helper function to match the hardware defined > - * cpu-type for a single entry in the x86_cpu_id > - * table. Note, this function does not match the > - * generic cpu-types TOPO_CPU_TYPE_EFFICIENCY and > - * TOPO_CPU_TYPE_PERFORMANCE. > - * @c: Pointer to the cpuinfo_x86 structure of the CPU to match. > - * @m: Pointer to the x86_cpu_id entry to match against. > - * > - * Return: true if the cpu-type matches, false otherwise. > - */ > -static bool x86_match_vendor_cpu_type(struct cpuinfo_x86 *c, const struct x86_cpu_id *m) > -{ > - if (m->type == X86_CPU_TYPE_ANY) > - return true; > - > - /* Hybrid CPUs are special, they are assumed to match all cpu-types */ > - if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) > - return true; > - > - if (c->x86_vendor == X86_VENDOR_INTEL) > - return m->type == c->topo.intel_type; > - if (c->x86_vendor == X86_VENDOR_AMD) > - return m->type == c->topo.amd_type; > - > - return false; > -} > - > /** > * x86_match_cpu - match current CPU against an array of x86_cpu_ids > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > continue; > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > continue; > - if (!x86_match_vendor_cpu_type(c, m)) > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) ... matching a hybrid CPU to any cpu_type. Also, I think now cpu_vuln_blacklist[] needs TOPO_CPU_TYPE_EFFICIENCY instead of ATOM. VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS | VMSCAPE), VULNBL_INTEL_STEPS(INTEL_ALDERLAKE, X86_STEP_MAX, VMSCAPE), VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS | VMSCAPE), VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS | VMSCAPE), ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-06 18:29 ` Pawan Gupta @ 2026-07-07 0:47 ` Borislav Petkov 2026-07-07 17:52 ` Pawan Gupta 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-07 0:47 UTC (permalink / raw) To: Pawan Gupta Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Mon, Jul 06, 2026 at 11:29:07AM -0700, Pawan Gupta wrote: > > /** > > * x86_match_cpu - match current CPU against an array of x86_cpu_ids > > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with > > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > > continue; > > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > > continue; > > - if (!x86_match_vendor_cpu_type(c, m)) > > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) > > ... matching a hybrid CPU to any cpu_type. I don't know what you mean here. enum x86_topology_cpu_type { /* X86_CPU_TYPE_ANY */ TOPO_CPU_TYPE_ANY = 0, TOPO_CPU_TYPE_PERFORMANCE, TOPO_CPU_TYPE_EFFICIENCY, TOPO_CPU_TYPE_UNKNOWN, }; These are the Linux-specific CPU types and all vendor CPU types will be mapped to them. I hope 255 are enough. > Also, I think now cpu_vuln_blacklist[] needs TOPO_CPU_TYPE_EFFICIENCY > instead of ATOM. > > VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS | VMSCAPE), > VULNBL_INTEL_STEPS(INTEL_ALDERLAKE, X86_STEP_MAX, VMSCAPE), > VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS | VMSCAPE), > VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS | VMSCAPE), Ack, right, ATOM == EFFICIENCY in Intel-speak, so I'd need to convert those. Thx. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-07 0:47 ` Borislav Petkov @ 2026-07-07 17:52 ` Pawan Gupta 2026-07-07 19:29 ` Thomas Gleixner 0 siblings, 1 reply; 25+ messages in thread From: Pawan Gupta @ 2026-07-07 17:52 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Mon, Jul 06, 2026 at 05:47:13PM -0700, Borislav Petkov wrote: > On Mon, Jul 06, 2026 at 11:29:07AM -0700, Pawan Gupta wrote: > > > /** > > > * x86_match_cpu - match current CPU against an array of x86_cpu_ids > > > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with > > > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > > > continue; > > > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > > > continue; > > > - if (!x86_match_vendor_cpu_type(c, m)) > > > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) > > > > ... matching a hybrid CPU to any cpu_type. > > I don't know what you mean here. Vulnerability enumeration is done on the BSP, for a hybrid system with BSP as a performance-core, a vulnerability that only affects efficiency-cores would not be enumerated. So, x86_match_cpu() currently returns a match for any cpu-type on a hybrid system. > enum x86_topology_cpu_type { > /* X86_CPU_TYPE_ANY */ > TOPO_CPU_TYPE_ANY = 0, > TOPO_CPU_TYPE_PERFORMANCE, > TOPO_CPU_TYPE_EFFICIENCY, > TOPO_CPU_TYPE_UNKNOWN, > }; > > These are the Linux-specific CPU types and all vendor CPU types will be mapped > to them. I hope 255 are enough. 255 should be more than enough, but it doesn't take resolve the problem of matching a hybrid CPU to any cpu_type. Apart from struct cpuinfo_x86 for each CPU, we have separate boot_cpu_data for BSP. One possible solution is to set cpu_type to TOPO_CPU_TYPE_ANY in BSP specific struct for hybrid systems. For more accurate matching, x86_topology_cpu_type could be a u32 with bit-fields for each CPU type. And boot_cpu_data can have: boot_cpu_data.topo.cpu_type = (TOPO_CPU_TYPE_PERFORMANCE | TOPO_CPU_TYPE_EFFICIENCY | ...) on a hybrid system. Problem with this approach is, unless secondary CPUs are brought up, BSP will not know what all cpu-types are present in the system. Also with bit-fields, possible cpu-types are further limited. To circumvent this problem, current implementation matches a hybrid CPU with any cpu_type. > > Also, I think now cpu_vuln_blacklist[] needs TOPO_CPU_TYPE_EFFICIENCY > > instead of ATOM. > > > > VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS | VMSCAPE), > > VULNBL_INTEL_STEPS(INTEL_ALDERLAKE, X86_STEP_MAX, VMSCAPE), > > VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS | VMSCAPE), > > VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS | VMSCAPE), > > Ack, right, ATOM == EFFICIENCY in Intel-speak, so I'd need to convert those. > > Thx. > > -- > Regards/Gruss, > Boris. > > https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-07 17:52 ` Pawan Gupta @ 2026-07-07 19:29 ` Thomas Gleixner 2026-07-07 20:46 ` Pawan Gupta 0 siblings, 1 reply; 25+ messages in thread From: Thomas Gleixner @ 2026-07-07 19:29 UTC (permalink / raw) To: Pawan Gupta, Borislav Petkov Cc: dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Tue, Jul 07 2026 at 10:52, Pawan Gupta wrote: > On Mon, Jul 06, 2026 at 05:47:13PM -0700, Borislav Petkov wrote: >> On Mon, Jul 06, 2026 at 11:29:07AM -0700, Pawan Gupta wrote: >> > > /** >> > > * x86_match_cpu - match current CPU against an array of x86_cpu_ids >> > > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with >> > > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) >> > > continue; >> > > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) >> > > continue; >> > > - if (!x86_match_vendor_cpu_type(c, m)) >> > > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) >> > >> > ... matching a hybrid CPU to any cpu_type. >> >> I don't know what you mean here. > > Vulnerability enumeration is done on the BSP, for a hybrid system with BSP > as a performance-core, a vulnerability that only affects efficiency-cores > would not be enumerated. So, x86_match_cpu() currently returns a match for > any cpu-type on a hybrid system. Abusing the type, which enumerates performance properties, for vulnerability crystal ball logic is simply broken. The type is a per CPU property and has nothing to do with hybrid or not. Hybrid is a packet property. Just because it is convenient does not make it more correct. If you need to enable mitigations on hybrid systems, then explicitely check for the hybrid property. Thanks, tglx ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-07 19:29 ` Thomas Gleixner @ 2026-07-07 20:46 ` Pawan Gupta 2026-07-07 23:24 ` Thomas Gleixner 0 siblings, 1 reply; 25+ messages in thread From: Pawan Gupta @ 2026-07-07 20:46 UTC (permalink / raw) To: Thomas Gleixner Cc: Borislav Petkov, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Tue, Jul 07, 2026 at 09:29:32PM +0200, Thomas Gleixner wrote: > On Tue, Jul 07 2026 at 10:52, Pawan Gupta wrote: > > On Mon, Jul 06, 2026 at 05:47:13PM -0700, Borislav Petkov wrote: > >> On Mon, Jul 06, 2026 at 11:29:07AM -0700, Pawan Gupta wrote: > >> > > /** > >> > > * x86_match_cpu - match current CPU against an array of x86_cpu_ids > >> > > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with > >> > > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > >> > > continue; > >> > > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > >> > > continue; > >> > > - if (!x86_match_vendor_cpu_type(c, m)) > >> > > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) > >> > > >> > ... matching a hybrid CPU to any cpu_type. > >> > >> I don't know what you mean here. > > > > Vulnerability enumeration is done on the BSP, for a hybrid system with BSP > > as a performance-core, a vulnerability that only affects efficiency-cores > > would not be enumerated. So, x86_match_cpu() currently returns a match for > > any cpu-type on a hybrid system. > > Abusing the type, which enumerates performance properties, for > vulnerability crystal ball logic is simply broken. > > The type is a per CPU property and has nothing to do with hybrid or > not. Hybrid is a packet property. > > Just because it is convenient does not make it more correct. If you need > to enable mitigations on hybrid systems, then explicitely check for the > hybrid property. Right, I was convoluting 2 different goals. Vulnerability enumeration should explicitly check for hybrid. Currently, only RFDS needs to check for hybrid. It is probably not worth creating a new mechanism for cpu_type check for vulnerability enumeration. Below should work with current set of CPUs. Please let me know if there is a better way to handle this: --- diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index a3df21d26460..836076b1a3b5 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1316,10 +1316,8 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS | ITS | ITS_NATIVE_ONLY), VULNBL_INTEL_STEPS(INTEL_LAKEFIELD, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED), VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY), - VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS | VMSCAPE), VULNBL_INTEL_STEPS(INTEL_ALDERLAKE, X86_STEP_MAX, VMSCAPE), VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS | VMSCAPE), - VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS | VMSCAPE), VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE, X86_STEP_MAX, VMSCAPE), VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE_P, X86_STEP_MAX, RFDS | VMSCAPE), VULNBL_INTEL_STEPS(INTEL_RAPTORLAKE_S, X86_STEP_MAX, RFDS | VMSCAPE), @@ -1388,7 +1386,20 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr) return true; /* Only consult the blacklist when there is no enumeration: */ - return cpu_matches(cpu_vuln_blacklist, RFDS); + if (!cpu_matches(cpu_vuln_blacklist, RFDS)) + return false; + + /* + * ADL and RPL are only affected if they have Atom CPUs. + * Hybrids have both Core and Atom CPUs, mark them vulnerable. + */ + if ((boot_cpu_data.x86_model == 0x97 || + boot_cpu_data.x86_model == 0xB7) && + boot_cpu_data.topo.hw_cpu_type == INTEL_CPU_TYPE_CORE && + !boot_cpu_has(X86_FEATURE_HYBRID_CPU)) + return false; + + return true; } static bool __init vulnerable_to_its(u64 x86_arch_cap_msr) ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-07 20:46 ` Pawan Gupta @ 2026-07-07 23:24 ` Thomas Gleixner 2026-07-21 3:18 ` [PATCH] x86/topo: Map vendor CPU types to generic Linux such types Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Thomas Gleixner @ 2026-07-07 23:24 UTC (permalink / raw) To: Pawan Gupta Cc: Borislav Petkov, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Tue, Jul 07 2026 at 13:46, Pawan Gupta wrote: > On Tue, Jul 07, 2026 at 09:29:32PM +0200, Thomas Gleixner wrote: >> Just because it is convenient does not make it more correct. If you need >> to enable mitigations on hybrid systems, then explicitely check for the >> hybrid property. > > Right, I was convoluting 2 different goals. Vulnerability enumeration > should explicitly check for hybrid. > > Currently, only RFDS needs to check for hybrid. It is probably not worth > creating a new mechanism for cpu_type check for vulnerability enumeration. > Below should work with current set of CPUs. Please let me know if there is > a better way to handle this: If that's the only case to handle, then sure that open coded check is fine. ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-07 23:24 ` Thomas Gleixner @ 2026-07-21 3:18 ` Borislav Petkov 2026-07-22 18:09 ` Pawan Gupta 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-21 3:18 UTC (permalink / raw) To: Thomas Gleixner Cc: Pawan Gupta, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 08, 2026 at 01:24:05AM +0200, Thomas Gleixner wrote: > If that's the only case to handle, then sure that open coded check is > fine. This is ontop of tip:x86/cpu which already has Pawan's change that drops the one Intel-specific CPU type use. It boots here so... :-P --- From: "Borislav Petkov (AMD)" <bp@alien8.de> Date: Thu, 2 Jul 2026 17:00:28 -0700 Subject: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sashiko reported¹ that a confusion could ensue if a vendor-specific CPU type 0 (performance) gets attempted to be used in a x86_cpu_id match table. The current logic treats 0 as the wildcard X86_CPU_TYPE_ANY and such a thing would end up matching the wrong CPUs. This is all backwards because we started using the vendor-specific CPU type number instead of using a Linux-defined, generic CPU type which is agnostic. Convert the current logic to it before users start appearing. ¹https://sashiko.dev/#/patchset/20260629094349.533301-1-Vishal.Badole%40amd.com Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Link: https://lore.kernel.org/r/20260629094349.533301-2-Vishal.Badole@amd.com --- arch/x86/include/asm/processor.h | 18 ++++++++++++---- arch/x86/include/asm/topology.h | 7 ------- arch/x86/kernel/acpi/cppc.c | 4 ++-- arch/x86/kernel/cpu/match.c | 30 +-------------------------- arch/x86/kernel/cpu/topology.h | 1 + arch/x86/kernel/cpu/topology_amd.c | 6 ++++-- arch/x86/kernel/cpu/topology_common.c | 8 +++++-- 7 files changed, 28 insertions(+), 46 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 87b1d4c0727e..fc0350fe8f5e 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -68,9 +68,13 @@ extern u16 __read_mostly tlb_lld_2m; extern u16 __read_mostly tlb_lld_4m; extern u16 __read_mostly tlb_lld_1g; -/* - * CPU type and hardware bug flags. Kept separately for each CPU. - */ +enum x86_topology_cpu_type { + /* X86_CPU_TYPE_ANY */ + TOPO_CPU_TYPE_ANY = 0, + TOPO_CPU_TYPE_PERFORMANCE, + TOPO_CPU_TYPE_EFFICIENCY, + TOPO_CPU_TYPE_UNKNOWN, +}; struct cpuinfo_topology { // Real APIC ID read from the local APIC @@ -104,7 +108,7 @@ struct cpuinfo_topology { // Hardware defined CPU-type union { - u32 cpu_type; + u32 hw_cpu_type; struct { // CPUID.1A.EAX[23-0] u32 intel_native_model_id :24; @@ -119,8 +123,14 @@ struct cpuinfo_topology { amd_type :4; }; }; + + // Linux vendor-agnostic CPU type + enum x86_topology_cpu_type cpu_type; }; +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + */ struct cpuinfo_x86 { union { /* diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 8fb61d2465eb..ef76ba674f1b 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -114,12 +114,6 @@ enum x86_topology_domains { TOPO_MAX_DOMAIN, }; -enum x86_topology_cpu_type { - TOPO_CPU_TYPE_PERFORMANCE, - TOPO_CPU_TYPE_EFFICIENCY, - TOPO_CPU_TYPE_UNKNOWN, -}; - struct x86_topology_system { unsigned int dom_shifts[TOPO_MAX_DOMAIN]; unsigned int dom_size[TOPO_MAX_DOMAIN]; @@ -160,7 +154,6 @@ extern unsigned int __num_nodes_per_package; struct cpuinfo_x86; const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); -enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); static inline unsigned int topology_max_packages(void) { diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index be4c5e9e5ff6..b8f5dd0a8117 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -241,7 +241,6 @@ EXPORT_SYMBOL_GPL(amd_detect_prefcore); */ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) { - enum x86_topology_cpu_type core_type = get_topology_cpu_type(&cpu_data(cpu)); bool prefcore; int ret; u32 tmp; @@ -273,8 +272,9 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) /* detect if running on heterogeneous design */ if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { - switch (core_type) { + switch (cpu_data(cpu).topo.cpu_type) { case TOPO_CPU_TYPE_UNKNOWN: + case TOPO_CPU_TYPE_ANY: pr_warn("Undefined core type found for cpu %d\n", cpu); break; case TOPO_CPU_TYPE_PERFORMANCE: diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index 4604802692da..7ab077f0cc66 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -5,34 +5,6 @@ #include <linux/export.h> #include <linux/slab.h> -/** - * x86_match_vendor_cpu_type - helper function to match the hardware defined - * cpu-type for a single entry in the x86_cpu_id - * table. Note, this function does not match the - * generic cpu-types TOPO_CPU_TYPE_EFFICIENCY and - * TOPO_CPU_TYPE_PERFORMANCE. - * @c: Pointer to the cpuinfo_x86 structure of the CPU to match. - * @m: Pointer to the x86_cpu_id entry to match against. - * - * Return: true if the cpu-type matches, false otherwise. - */ -static bool x86_match_vendor_cpu_type(struct cpuinfo_x86 *c, const struct x86_cpu_id *m) -{ - if (m->type == X86_CPU_TYPE_ANY) - return true; - - /* Hybrid CPUs are special, they are assumed to match all cpu-types */ - if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) - return true; - - if (c->x86_vendor == X86_VENDOR_INTEL) - return m->type == c->topo.intel_type; - if (c->x86_vendor == X86_VENDOR_AMD) - return m->type == c->topo.amd_type; - - return false; -} - /** * x86_match_cpu - match current CPU against an array of x86_cpu_ids * @match: Pointer to array of x86_cpu_ids. Last entry terminated with @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) continue; if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) continue; - if (!x86_match_vendor_cpu_type(c, m)) + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) continue; return m; } diff --git a/arch/x86/kernel/cpu/topology.h b/arch/x86/kernel/cpu/topology.h index 37326297f80c..74e02bacd854 100644 --- a/arch/x86/kernel/cpu/topology.h +++ b/arch/x86/kernel/cpu/topology.h @@ -22,6 +22,7 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, bool cpu_parse_topology_ext(struct topo_scan *tscan); void cpu_parse_topology_amd(struct topo_scan *tscan); void cpu_topology_fixup_amd(struct topo_scan *tscan); +enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom) { diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c index da080d732e10..c5a6944df86a 100644 --- a/arch/x86/kernel/cpu/topology_amd.c +++ b/arch/x86/kernel/cpu/topology_amd.c @@ -177,8 +177,10 @@ static void topoext_fixup(struct topo_scan *tscan) static void parse_topology_amd(struct topo_scan *tscan) { - if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) - tscan->c->topo.cpu_type = cpuid_ebx(0x80000026); + if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { + tscan->c->topo.hw_cpu_type = cpuid_ebx(0x80000026); + tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c); + } /* * Try to get SMT, CORE, TILE, and DIE shifts from extended diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c index cf7513416b70..b9d025f3373a 100644 --- a/arch/x86/kernel/cpu/topology_common.c +++ b/arch/x86/kernel/cpu/topology_common.c @@ -168,8 +168,12 @@ static void parse_topology(struct topo_scan *tscan, bool early) case X86_VENDOR_INTEL: if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan)) parse_legacy(tscan); - if (c->cpuid_level >= 0x1a) - c->topo.cpu_type = cpuid_eax(0x1a); + + if (c->cpuid_level >= 0x1a) { + c->topo.hw_cpu_type = cpuid_eax(0x1a); + c->topo.cpu_type = get_topology_cpu_type(c); + } + break; } } -- 2.53.0 -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-21 3:18 ` [PATCH] x86/topo: Map vendor CPU types to generic Linux such types Borislav Petkov @ 2026-07-22 18:09 ` Pawan Gupta 2026-07-22 18:31 ` Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Pawan Gupta @ 2026-07-22 18:09 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Mon, Jul 20, 2026 at 08:18:58PM -0700, Borislav Petkov wrote: > On Wed, Jul 08, 2026 at 01:24:05AM +0200, Thomas Gleixner wrote: > > If that's the only case to handle, then sure that open coded check is > > fine. > > This is ontop of tip:x86/cpu which already has Pawan's change that drops the > one Intel-specific CPU type use. > > It boots here so... :-P > > --- > From: "Borislav Petkov (AMD)" <bp@alien8.de> > Date: Thu, 2 Jul 2026 17:00:28 -0700 > Subject: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > Sashiko reported¹ that a confusion could ensue if a vendor-specific CPU > type 0 (performance) gets attempted to be used in a x86_cpu_id match > table. The current logic treats 0 as the wildcard X86_CPU_TYPE_ANY and > such a thing would end up matching the wrong CPUs. > > This is all backwards because we started using the vendor-specific CPU > type number instead of using a Linux-defined, generic CPU type which > is agnostic. > > Convert the current logic to it before users start appearing. > > ¹https://sashiko.dev/#/patchset/20260629094349.533301-1-Vishal.Badole%40amd.com > > Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> > Link: https://lore.kernel.org/r/20260629094349.533301-2-Vishal.Badole@amd.com > --- > arch/x86/include/asm/processor.h | 18 ++++++++++++---- > arch/x86/include/asm/topology.h | 7 ------- > arch/x86/kernel/acpi/cppc.c | 4 ++-- > arch/x86/kernel/cpu/match.c | 30 +-------------------------- > arch/x86/kernel/cpu/topology.h | 1 + > arch/x86/kernel/cpu/topology_amd.c | 6 ++++-- > arch/x86/kernel/cpu/topology_common.c | 8 +++++-- > 7 files changed, 28 insertions(+), 46 deletions(-) > > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h > index 87b1d4c0727e..fc0350fe8f5e 100644 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -68,9 +68,13 @@ extern u16 __read_mostly tlb_lld_2m; > extern u16 __read_mostly tlb_lld_4m; > extern u16 __read_mostly tlb_lld_1g; > > -/* > - * CPU type and hardware bug flags. Kept separately for each CPU. > - */ > +enum x86_topology_cpu_type { > + /* X86_CPU_TYPE_ANY */ > + TOPO_CPU_TYPE_ANY = 0, I don't really understand the purpose of TOPO_CPU_TYPE_ANY here. In the cpu matching infrastructure, X86_CPU_TYPE_ANY makes sense. Here I fail to understand how is TOPO_CPU_TYPE_ANY different from UNKNOWN? A table passed to x86_match_cpu() with X86_CPU_TYPE_ANY entry will match any CPU type including TOPO_CPU_TYPE_UNKNOWN. > + TOPO_CPU_TYPE_PERFORMANCE, > + TOPO_CPU_TYPE_EFFICIENCY, > + TOPO_CPU_TYPE_UNKNOWN, > +}; > > struct cpuinfo_topology { > // Real APIC ID read from the local APIC > @@ -104,7 +108,7 @@ struct cpuinfo_topology { > > // Hardware defined CPU-type > union { > - u32 cpu_type; > + u32 hw_cpu_type; > struct { > // CPUID.1A.EAX[23-0] > u32 intel_native_model_id :24; > @@ -119,8 +123,14 @@ struct cpuinfo_topology { > amd_type :4; > }; > }; > + > + // Linux vendor-agnostic CPU type > + enum x86_topology_cpu_type cpu_type; > }; > > +/* > + * CPU type and hardware bug flags. Kept separately for each CPU. > + */ > struct cpuinfo_x86 { > union { > /* > diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h > index 8fb61d2465eb..ef76ba674f1b 100644 > --- a/arch/x86/include/asm/topology.h > +++ b/arch/x86/include/asm/topology.h > @@ -114,12 +114,6 @@ enum x86_topology_domains { > TOPO_MAX_DOMAIN, > }; > > -enum x86_topology_cpu_type { > - TOPO_CPU_TYPE_PERFORMANCE, > - TOPO_CPU_TYPE_EFFICIENCY, > - TOPO_CPU_TYPE_UNKNOWN, > -}; ... > /** > * x86_match_cpu - match current CPU against an array of x86_cpu_ids > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > continue; > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > continue; > - if (!x86_match_vendor_cpu_type(c, m)) > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) In line with what Thomas pointed that cpu_type is not a system property, I suggest matching cpu_type should be dropped from x86_match_cpu(). More so because it only uses boot_cpu_data and misses the other types of secondary CPUs. I feel it is not a reliable way to match CPU types. Thoughts? > continue; > return m; > } > diff --git a/arch/x86/kernel/cpu/topology.h b/arch/x86/kernel/cpu/topology.h > index 37326297f80c..74e02bacd854 100644 > --- a/arch/x86/kernel/cpu/topology.h > +++ b/arch/x86/kernel/cpu/topology.h > @@ -22,6 +22,7 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, > bool cpu_parse_topology_ext(struct topo_scan *tscan); > void cpu_parse_topology_amd(struct topo_scan *tscan); > void cpu_topology_fixup_amd(struct topo_scan *tscan); > +enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); > > static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom) > { > diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c > index da080d732e10..c5a6944df86a 100644 > --- a/arch/x86/kernel/cpu/topology_amd.c > +++ b/arch/x86/kernel/cpu/topology_amd.c > @@ -177,8 +177,10 @@ static void topoext_fixup(struct topo_scan *tscan) > > static void parse_topology_amd(struct topo_scan *tscan) > { > - if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) > - tscan->c->topo.cpu_type = cpuid_ebx(0x80000026); > + if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { Slightly unrelated to this patch, on AMD is it that hw_cpu_type only available on hybrid systems? On Intel ... > + tscan->c->topo.hw_cpu_type = cpuid_ebx(0x80000026); > + tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c); > + } > > /* > * Try to get SMT, CORE, TILE, and DIE shifts from extended > diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c > index cf7513416b70..b9d025f3373a 100644 > --- a/arch/x86/kernel/cpu/topology_common.c > +++ b/arch/x86/kernel/cpu/topology_common.c > @@ -168,8 +168,12 @@ static void parse_topology(struct topo_scan *tscan, bool early) > case X86_VENDOR_INTEL: > if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan)) > parse_legacy(tscan); > - if (c->cpuid_level >= 0x1a) > - c->topo.cpu_type = cpuid_eax(0x1a); > + > + if (c->cpuid_level >= 0x1a) { > + c->topo.hw_cpu_type = cpuid_eax(0x1a); > + c->topo.cpu_type = get_topology_cpu_type(c); ... hw_cpu_type could be enumerated on non-hybrid parts. > + } > + > break; > } > } ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-22 18:09 ` Pawan Gupta @ 2026-07-22 18:31 ` Borislav Petkov 2026-07-22 19:22 ` Pawan Gupta 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-22 18:31 UTC (permalink / raw) To: Pawan Gupta Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 22, 2026 at 11:09:58AM -0700, Pawan Gupta wrote: > > +enum x86_topology_cpu_type { > > + /* X86_CPU_TYPE_ANY */ > > + TOPO_CPU_TYPE_ANY = 0, > > I don't really understand the purpose of TOPO_CPU_TYPE_ANY here. In the cpu > matching infrastructure, X86_CPU_TYPE_ANY makes sense. Here I fail to > understand how is TOPO_CPU_TYPE_ANY different from UNKNOWN? A table passed > to x86_match_cpu() with X86_CPU_TYPE_ANY entry will match any CPU type > including TOPO_CPU_TYPE_UNKNOWN. This will go away in future patches. We do one logical thing per patch and removing UNKNOWN is not it. I have it on my TODO list to clean up everything here. > > > + TOPO_CPU_TYPE_PERFORMANCE, > > + TOPO_CPU_TYPE_EFFICIENCY, > > + TOPO_CPU_TYPE_UNKNOWN, > > +}; ... > > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > > continue; > > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > > continue; > > - if (!x86_match_vendor_cpu_type(c, m)) > > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) > > In line with what Thomas pointed that cpu_type is not a system property, I > suggest matching cpu_type should be dropped from x86_match_cpu(). More so > because it only uses boot_cpu_data and misses the other types of secondary > CPUs. I feel it is not a reliable way to match CPU types. Thoughts? How do you suggest we match CPU types on the whole system? I.e., "do this workaround only on the performance cores", for example. c->topo.cpu_type is perfect for that then. > Slightly unrelated to this patch, on AMD is it that hw_cpu_type only > available on hybrid systems? No idea. I will dig through that later, when cleaning up. If only available on hybrid systems, we will have to fake something there, X86_CPU_TYPE_ANY perhaps. :-) -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-22 18:31 ` Borislav Petkov @ 2026-07-22 19:22 ` Pawan Gupta 2026-07-22 19:51 ` Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Pawan Gupta @ 2026-07-22 19:22 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 22, 2026 at 11:31:52AM -0700, Borislav Petkov wrote: > On Wed, Jul 22, 2026 at 11:09:58AM -0700, Pawan Gupta wrote: > > > +enum x86_topology_cpu_type { > > > + /* X86_CPU_TYPE_ANY */ > > > + TOPO_CPU_TYPE_ANY = 0, > > > > I don't really understand the purpose of TOPO_CPU_TYPE_ANY here. In the cpu > > matching infrastructure, X86_CPU_TYPE_ANY makes sense. Here I fail to > > understand how is TOPO_CPU_TYPE_ANY different from UNKNOWN? A table passed > > to x86_match_cpu() with X86_CPU_TYPE_ANY entry will match any CPU type > > including TOPO_CPU_TYPE_UNKNOWN. > > This will go away in future patches. We do one logical thing per patch and > removing UNKNOWN is not it. I have it on my TODO list to clean up everything > here. Unless I am misreading, TOPO_CPU_TYPE_ANY is introduced in this patch. X86_*_ANY in x86_match_cpu() are much needed wildcards, I dont really understand why x86_topology_cpu_type needs to carry a wildcard. It should reflect the true state, PERFORMANCE, EFFICIENCY or UNKNOWN. Between ANY and UNKNOWN, I would prefer UNKNOWN when CPU did not report a type. > > > > > + TOPO_CPU_TYPE_PERFORMANCE, > > > + TOPO_CPU_TYPE_EFFICIENCY, > > > + TOPO_CPU_TYPE_UNKNOWN, > > > +}; > > ... > > > > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > > > continue; > > > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > > > continue; > > > - if (!x86_match_vendor_cpu_type(c, m)) > > > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) > > > > In line with what Thomas pointed that cpu_type is not a system property, I > > suggest matching cpu_type should be dropped from x86_match_cpu(). More so > > because it only uses boot_cpu_data and misses the other types of secondary > > CPUs. I feel it is not a reliable way to match CPU types. Thoughts? > > How do you suggest we match CPU types on the whole system? > > I.e., "do this workaround only on the performance cores", for example. > > c->topo.cpu_type is perfect for that then. Ya. If need be, a mask of each possible cpu_type can be built for dispatching work selectively. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-22 19:22 ` Pawan Gupta @ 2026-07-22 19:51 ` Borislav Petkov 2026-07-22 20:57 ` Pawan Gupta 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-22 19:51 UTC (permalink / raw) To: Pawan Gupta Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 22, 2026 at 12:22:11PM -0700, Pawan Gupta wrote: > Unless I am misreading, TOPO_CPU_TYPE_ANY is introduced in this patch. > X86_*_ANY in x86_match_cpu() are much needed wildcards, I dont really > understand why x86_topology_cpu_type needs to carry a wildcard. It should > reflect the true state, PERFORMANCE, EFFICIENCY or UNKNOWN. > > Between ANY and UNKNOWN, I would prefer UNKNOWN when CPU did not report a > type. Because X86_CPU_TYPE_ANY is already there and it is 0 and TOPO_CPU_TYPE_ANY is supposed to be the same and mirror it. Did you even read my mail where I explain that we don't do multiple things in one patch? > Ya. If need be, a mask of each possible cpu_type can be built for > dispatching work selectively. Instead of doing the completely sensible thing and keeping a per-CPU type? -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-22 19:51 ` Borislav Petkov @ 2026-07-22 20:57 ` Pawan Gupta 2026-07-22 21:23 ` Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Pawan Gupta @ 2026-07-22 20:57 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 22, 2026 at 12:51:05PM -0700, Borislav Petkov wrote: > On Wed, Jul 22, 2026 at 12:22:11PM -0700, Pawan Gupta wrote: > > Unless I am misreading, TOPO_CPU_TYPE_ANY is introduced in this patch. > > X86_*_ANY in x86_match_cpu() are much needed wildcards, I dont really > > understand why x86_topology_cpu_type needs to carry a wildcard. It should > > reflect the true state, PERFORMANCE, EFFICIENCY or UNKNOWN. > > > > Between ANY and UNKNOWN, I would prefer UNKNOWN when CPU did not report a > > type. > > Because X86_CPU_TYPE_ANY is already there and it is 0 and TOPO_CPU_TYPE_ANY is > supposed to be the same and mirror it. This is exactly what I don't understand. For a wildcard X86_CPU_TYPE_ANY that matches TOPO_CPU_TYPE_*, do we really need TOPO_CPU_TYPE_ANY for matching to work? > Did you even read my mail where I explain that we don't do multiple things in > one patch? Yes, but my main concern is about addition of TOPO_CPU_TYPE_ANY. If we don't add TOPO_CPU_TYPE_ANY, second patch will not be needed. Sorry if I am mis-interpreting things. > > Ya. If need be, a mask of each possible cpu_type can be built for > > dispatching work selectively. > > Instead of doing the completely sensible thing and keeping a per-CPU type? My earlier comment was unnecessary, and putting us off-track here. Please ignore this part. (Just to clarify what I meant: For dispatching work to all P-cores in your example scenario with something like on_each_cpu_mask() we would need a mask of all P-cores. Such a mask can be built/cached using the per-CPU type information). ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-22 20:57 ` Pawan Gupta @ 2026-07-22 21:23 ` Borislav Petkov 2026-08-27 20:44 ` Borislav Petkov 0 siblings, 1 reply; 25+ messages in thread From: Borislav Petkov @ 2026-07-22 21:23 UTC (permalink / raw) To: Pawan Gupta Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Wed, Jul 22, 2026 at 01:57:57PM -0700, Pawan Gupta wrote: > Yes, but my main concern is about addition of TOPO_CPU_TYPE_ANY. If we > don't add TOPO_CPU_TYPE_ANY, second patch will not be needed. Sorry if I am > mis-interpreting things. Well, I have no idea too what are you even fighting for? It sounds like a giant waste of time to me for something as trivial as this. What second patch? Once the cleanup is done, only one of the two will survive - either TOPO_CPU_TYPE_ANY or TOPO_CPU_TYPE_UNKNOWN. I'm calling the former "ANY" to denote that it is the *same* ANY as X86_CPU_TYPE_ANY. I don't know how else to explain it to you. -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-07-22 21:23 ` Borislav Petkov @ 2026-08-27 20:44 ` Borislav Petkov 2026-08-28 6:04 ` Pawan Gupta 2026-08-28 19:54 ` Pawan Gupta 0 siblings, 2 replies; 25+ messages in thread From: Borislav Petkov @ 2026-08-27 20:44 UTC (permalink / raw) To: Thomas Gleixner Cc: Pawan Gupta, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang Here's the cleanup ontop, lemme know pls whether that makes sense. Some noteworthy things: * this basically switches to TOPO_CPU_TYPE and only the detection code knows about the vendor-specific ones. The generic types are union set of both. * We do some CPUID calls where needed: - native_id = c->topo.intel_native_model_id; + native_id = cpuid_eax(0x1a) & GENMASK(23, 0); and in get_topology_cpu_type() but those will go away too with Ahmed's rework The rest is just manual conversion labour. Oh, and TOPO_CPU_TYPE_ANY is gone too, so that Pawan can sleep at night :-P Thoughts? I think it is better this way instead of carrying intel_type and amd_type in cpuinfo - now the topology code is preparing things for us. I'll split it into proper patches if people are ok with it. Thx. --- diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index cc13164d948f..f14775968308 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -5682,9 +5682,9 @@ static int adl_hw_config(struct perf_event *event) return -EOPNOTSUPP; } -static enum intel_cpu_type adl_get_hybrid_cpu_type(void) +static enum x86_topology_cpu_type adl_get_hybrid_cpu_type(void) { - return INTEL_CPU_TYPE_CORE; + return TOPO_CPU_TYPE_EFFICIENCY; } static inline bool erratum_hsw11(struct perf_event *event) @@ -6292,7 +6292,7 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu) static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void) { struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); - enum intel_cpu_type cpu_type = c->topo.intel_type; + enum x86_topology_cpu_type cpu_type = c->topo.cpu_type; int i; /* @@ -6301,7 +6301,7 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void) * on it. There should be a fixup function provided for these * troublesome CPUs (->get_hybrid_cpu_type). */ - if (cpu_type == INTEL_CPU_TYPE_UNKNOWN) { + if (cpu_type == TOPO_CPU_TYPE_UNKNOWN) { if (x86_pmu.get_hybrid_cpu_type) cpu_type = x86_pmu.get_hybrid_cpu_type(); else @@ -6318,13 +6318,13 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void) enum hybrid_pmu_type pmu_type = x86_pmu.hybrid_pmu[i].pmu_type; u32 native_id; - if (cpu_type == INTEL_CPU_TYPE_CORE && pmu_type == hybrid_big) + if (cpu_type == TOPO_CPU_TYPE_PERFORMANCE && pmu_type == hybrid_big) return &x86_pmu.hybrid_pmu[i]; - if (cpu_type == INTEL_CPU_TYPE_ATOM) { + if (cpu_type == TOPO_CPU_TYPE_EFFICIENCY) { if (x86_pmu.num_hybrid_pmus == 2 && pmu_type == hybrid_small) return &x86_pmu.hybrid_pmu[i]; - native_id = c->topo.intel_native_model_id; + native_id = cpuid_eax(0x1a) & GENMASK(23, 0); if (native_id == INTEL_ATOM_SKT_NATIVE_ID && pmu_type == hybrid_small) return &x86_pmu.hybrid_pmu[i]; if (native_id == INTEL_ATOM_CMT_NATIVE_ID && pmu_type == hybrid_tiny) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 71ed5b2acea2..89418310b788 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1051,7 +1051,7 @@ struct x86_pmu { */ int num_hybrid_pmus; struct x86_hybrid_pmu *hybrid_pmu; - enum intel_cpu_type (*get_hybrid_cpu_type) (void); + enum x86_topology_cpu_type (*get_hybrid_cpu_type) (void); }; struct x86_perf_task_context_opt { diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 66d964afe18a..ee5a88ffc849 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -207,20 +207,6 @@ #define INTEL_P4_PRESCOTT_2M IFM(15, 0x04) #define INTEL_P4_CEDARMILL IFM(15, 0x06) /* Also Xeon Dempsey */ -/* - * Intel CPU core types - * - * CPUID.1AH.EAX[31:0] uniquely identifies the microarchitecture - * of the core. Bits 31-24 indicates its core type (Core or Atom) - * and Bits [23:0] indicates the native model ID of the core. - * Core type and native model ID are defined in below enumerations. - */ -enum intel_cpu_type { - INTEL_CPU_TYPE_UNKNOWN, - INTEL_CPU_TYPE_ATOM = 0x20, - INTEL_CPU_TYPE_CORE = 0x40, -}; - enum intel_native_id { INTEL_ATOM_CMT_NATIVE_ID = 0x2, /* Crestmont */ INTEL_ATOM_SKT_NATIVE_ID = 0x3, /* Skymont */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index ec9db0dfa0df..89b0e0886b54 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -69,12 +69,11 @@ extern u16 __read_mostly tlb_lld_4m; extern u16 __read_mostly tlb_lld_1g; enum x86_topology_cpu_type { - /* X86_CPU_TYPE_ANY */ - TOPO_CPU_TYPE_ANY = 0, + /* Must remain 0 like X86_CPU_TYPE_ANY for x86_match_cpu() to work */ + TOPO_CPU_TYPE_UNKNOWN = 0, TOPO_CPU_TYPE_PERFORMANCE, TOPO_CPU_TYPE_EFFICIENCY, TOPO_CPU_TYPE_LOW_POWER, - TOPO_CPU_TYPE_UNKNOWN, }; struct cpuinfo_topology { @@ -107,24 +106,6 @@ struct cpuinfo_topology { u32 llc_id; u32 l2c_id; - // Hardware defined CPU-type - union { - u32 hw_cpu_type; - struct { - // CPUID.1A.EAX[23-0] - u32 intel_native_model_id :24; - // CPUID.1A.EAX[31-24] - u32 intel_type :8; - }; - struct { - // CPUID 0x80000026.EBX - u32 amd_num_processors :16, - amd_power_eff_ranking :8, - amd_native_model_id :4, - amd_type :4; - }; - }; - // Linux vendor-agnostic CPU type enum x86_topology_cpu_type cpu_type; }; diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 1825691af941..ef76ba674f1b 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -114,12 +114,6 @@ enum x86_topology_domains { TOPO_MAX_DOMAIN, }; -enum amd_cpu_type { - AMD_CPU_TYPE_PERFORMANCE = 0, - AMD_CPU_TYPE_EFFICIENCY = 1, - AMD_CPU_TYPE_LOW_POWER = 2, -}; - struct x86_topology_system { unsigned int dom_shifts[TOPO_MAX_DOMAIN]; unsigned int dom_size[TOPO_MAX_DOMAIN]; diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index bbade0da5130..bb2840c15397 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -274,7 +274,6 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { switch (cpu_data(cpu).topo.cpu_type) { case TOPO_CPU_TYPE_UNKNOWN: - case TOPO_CPU_TYPE_ANY: pr_warn("Undefined core type found for cpu %d\n", cpu); break; case TOPO_CPU_TYPE_PERFORMANCE: diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c7352827f491..d0dd120b9c14 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1394,7 +1394,7 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr) */ if ((boot_cpu_data.x86_model == 0x97 || boot_cpu_data.x86_model == 0xB7) && - boot_cpu_data.topo.intel_type != INTEL_CPU_TYPE_ATOM && + boot_cpu_data.topo.cpu_type != TOPO_CPU_TYPE_EFFICIENCY && !boot_cpu_has(X86_FEATURE_HYBRID_CPU)) return false; diff --git a/arch/x86/kernel/cpu/topology.h b/arch/x86/kernel/cpu/topology.h index 74e02bacd854..b948e87f1722 100644 --- a/arch/x86/kernel/cpu/topology.h +++ b/arch/x86/kernel/cpu/topology.h @@ -2,6 +2,25 @@ #ifndef ARCH_X86_TOPOLOGY_H #define ARCH_X86_TOPOLOGY_H +/* + * Intel CPU core types + * + * CPUID.1AH.EAX[31:0] uniquely identifies the microarchitecture + * of the core. Bits 31-24 indicates its core type (Core or Atom) + * and Bits [23:0] indicates the native model ID of the core. + */ +enum intel_cpu_type { + INTEL_CPU_TYPE_UNKNOWN, + INTEL_CPU_TYPE_ATOM = 0x20, + INTEL_CPU_TYPE_CORE = 0x40, +}; + +enum amd_cpu_type { + AMD_CPU_TYPE_PERFORMANCE = 0, + AMD_CPU_TYPE_EFFICIENCY = 1, + AMD_CPU_TYPE_LOW_POWER = 2, +}; + struct topo_scan { struct cpuinfo_x86 *c; unsigned int dom_shifts[TOPO_MAX_DOMAIN]; diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c index c5a6944df86a..457c27626028 100644 --- a/arch/x86/kernel/cpu/topology_amd.c +++ b/arch/x86/kernel/cpu/topology_amd.c @@ -177,10 +177,8 @@ static void topoext_fixup(struct topo_scan *tscan) static void parse_topology_amd(struct topo_scan *tscan) { - if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { - tscan->c->topo.hw_cpu_type = cpuid_ebx(0x80000026); - tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c); - } + if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) + tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c); /* * Try to get SMT, CORE, TILE, and DIE shifts from extended diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c index 6845e3c63fbb..40476f5c5cfc 100644 --- a/arch/x86/kernel/cpu/topology_common.c +++ b/arch/x86/kernel/cpu/topology_common.c @@ -35,13 +35,17 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c) { if (c->x86_vendor == X86_VENDOR_INTEL) { - switch (c->topo.intel_type) { + unsigned int type = (cpuid_eax(0x1a) >> 24) & 0xff; + + switch (type) { case INTEL_CPU_TYPE_ATOM: return TOPO_CPU_TYPE_EFFICIENCY; case INTEL_CPU_TYPE_CORE: return TOPO_CPU_TYPE_PERFORMANCE; } } if (c->x86_vendor == X86_VENDOR_AMD) { - switch (c->topo.amd_type) { + unsigned int type = (cpuid_ebx(0x80000026) >> 28) & 0xf; + + switch (type) { case AMD_CPU_TYPE_PERFORMANCE: return TOPO_CPU_TYPE_PERFORMANCE; case AMD_CPU_TYPE_EFFICIENCY: return TOPO_CPU_TYPE_EFFICIENCY; case AMD_CPU_TYPE_LOW_POWER: return TOPO_CPU_TYPE_LOW_POWER; @@ -172,10 +176,8 @@ static void parse_topology(struct topo_scan *tscan, bool early) if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan)) parse_legacy(tscan); - if (c->cpuid_level >= 0x1a) { - c->topo.hw_cpu_type = cpuid_eax(0x1a); - c->topo.cpu_type = get_topology_cpu_type(c); - } + if (c->cpuid_level >= 0x1a) + c->topo.cpu_type = get_topology_cpu_type(c); break; } diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index ceb340f7a110..17cfde971f0b 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -868,7 +868,7 @@ static struct freq_attr *hwp_cpufreq_attrs[] = { static u8 hybrid_get_cpu_type(unsigned int cpu) { - return cpu_data(cpu).topo.intel_type; + return cpu_data(cpu).topo.cpu_type; } static bool no_cas __ro_after_init; @@ -931,7 +931,7 @@ static int hybrid_get_cost(struct device *dev, unsigned long freq, * capacity. Similarly, P-cores start to be populated when E-cores are * utilized above 60% of the capacity. */ - if (hybrid_get_cpu_type(dev->id) == INTEL_CPU_TYPE_CORE) /* P-core */ + if (hybrid_get_cpu_type(dev->id) == TOPO_CPU_TYPE_PERFORMANCE) /* P-core */ *cost += 2; else if (hybrid_has_l3(dev->id)) /* E-core */ *cost += 1; @@ -2235,7 +2235,7 @@ static int hwp_get_cpu_scaling(int cpu) * Return the hybrid scaling factor for P-cores and use the * default core scaling for E-cores. */ - if (hybrid_get_cpu_type(cpu) != INTEL_CPU_TYPE_ATOM) + if (hybrid_get_cpu_type(cpu) != TOPO_CPU_TYPE_EFFICIENCY) return hybrid_scaling_factor; return core_get_scaling(); -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-08-27 20:44 ` Borislav Petkov @ 2026-08-28 6:04 ` Pawan Gupta 2026-08-28 19:54 ` Pawan Gupta 1 sibling, 0 replies; 25+ messages in thread From: Pawan Gupta @ 2026-08-28 6:04 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Thu, Aug 27, 2026 at 01:44:25PM -0700, Borislav Petkov wrote: > Here's the cleanup ontop, lemme know pls whether that makes sense. > > Some noteworthy things: > > * this basically switches to TOPO_CPU_TYPE and only the detection code knows > about the vendor-specific ones. The generic types are union set of both. > > * We do some CPUID calls where needed: > > - native_id = c->topo.intel_native_model_id; > + native_id = cpuid_eax(0x1a) & GENMASK(23, 0); > > and in get_topology_cpu_type() but those will go away too with Ahmed's rework > > The rest is just manual conversion labour. Oh, and TOPO_CPU_TYPE_ANY is gone > too, so that Pawan can sleep at night :-P And put my OCD to rest :-) (BTW, some of that is acquired occupational hazard.) > Thoughts? Overall, looks like a good cleanup to me. > I think it is better this way instead of carrying intel_type and amd_type in > cpuinfo - now the topology code is preparing things for us. > > I'll split it into proper patches if people are ok with it. > > Thx. ... > --- a/arch/x86/kernel/cpu/topology_common.c > +++ b/arch/x86/kernel/cpu/topology_common.c > @@ -35,13 +35,17 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, > enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c) > { > if (c->x86_vendor == X86_VENDOR_INTEL) { > - switch (c->topo.intel_type) { > + unsigned int type = (cpuid_eax(0x1a) >> 24) & 0xff; You already mentioned about the cpuid taken care elsewhere, just noting that this needs a (c->cpuid_level >= 0x1a) check. > + switch (type) { > case INTEL_CPU_TYPE_ATOM: return TOPO_CPU_TYPE_EFFICIENCY; > case INTEL_CPU_TYPE_CORE: return TOPO_CPU_TYPE_PERFORMANCE; > } > } Since x86_match_cpu() matches with boot_cpu_data, one rough edge remaining is, a secondary cpu_type in a hybrid system can never be matched. For this reason X86_MATCH_VFM_CPU_TYPE() is of little use now. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH] x86/topo: Map vendor CPU types to generic Linux such types 2026-08-27 20:44 ` Borislav Petkov 2026-08-28 6:04 ` Pawan Gupta @ 2026-08-28 19:54 ` Pawan Gupta 1 sibling, 0 replies; 25+ messages in thread From: Pawan Gupta @ 2026-08-28 19:54 UTC (permalink / raw) To: Borislav Petkov Cc: Thomas Gleixner, dave.hansen, Vishal Badole, mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On Thu, Aug 27, 2026 at 01:44:25PM -0700, Borislav Petkov wrote: > diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c > index cc13164d948f..f14775968308 100644 > --- a/arch/x86/events/intel/core.c > +++ b/arch/x86/events/intel/core.c > @@ -5682,9 +5682,9 @@ static int adl_hw_config(struct perf_event *event) > return -EOPNOTSUPP; > } > > -static enum intel_cpu_type adl_get_hybrid_cpu_type(void) > +static enum x86_topology_cpu_type adl_get_hybrid_cpu_type(void) > { > - return INTEL_CPU_TYPE_CORE; > + return TOPO_CPU_TYPE_EFFICIENCY; Should be: return TOPO_CPU_TYPE_PERFORMANCE; ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/2] x86/topology: Name the AMD core-type values 2026-07-03 19:32 ` Borislav Petkov 2026-07-03 19:39 ` Thomas Gleixner 2026-07-06 18:29 ` Pawan Gupta @ 2026-07-21 9:08 ` Badole, Vishal 2 siblings, 0 replies; 25+ messages in thread From: Badole, Vishal @ 2026-07-21 9:08 UTC (permalink / raw) To: Borislav Petkov, Thomas Gleixner, dave.hansen, Pawan Gupta Cc: mingo, x86, hpa, rafael, lenb, linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang On 7/4/2026 1:02 AM, Borislav Petkov wrote: > + Dave and Pawan. > > On Thu, Jul 02, 2026 at 04:03:37PM -0700, Borislav Petkov wrote: >> On Fri, Jul 03, 2026 at 12:06:32AM +0200, Thomas Gleixner wrote: >>> Just do the mapping to vendor-agnostic types _once_ when you enumerate the CPU >>> and store that information in the per CPU data. >>> >>> Then you can do proper vendor agnostic matching against that and define >>> the TYPE_ANY value as you want without ever colliding with vendor >>> muck. >>> >>> As a bonus get_topology_cpu_type() goes away too as the translation has >>> been done already. >> >> Yeah, we should've done it from the very beginning this way. Lemme hack it up >> and see how it looks like. >> >> Thanks for the cool idea. > > Something like the totally untested below - but it builds at least. > > We've allocated a u8 for the struct x86_cpu_id member type and we compare that > to enum x86_topology_cpu_type cpu_type. I guess that's ok for now... > > There's potential for more cleanup by removing the ->intel_type and ->amd_type > and converting them all to our internal represenation of CPU_TYPE but that's > for later and other patches anyway. > > Thoughts? > > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h > index 8d8f890c4bc0..746822bd71fb 100644 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -68,9 +68,13 @@ extern u16 __read_mostly tlb_lld_2m; > extern u16 __read_mostly tlb_lld_4m; > extern u16 __read_mostly tlb_lld_1g; > > -/* > - * CPU type and hardware bug flags. Kept separately for each CPU. > - */ > +enum x86_topology_cpu_type { > + /* X86_CPU_TYPE_ANY */ > + TOPO_CPU_TYPE_ANY = 0, > + TOPO_CPU_TYPE_PERFORMANCE, > + TOPO_CPU_TYPE_EFFICIENCY, > + TOPO_CPU_TYPE_UNKNOWN, > +}; > > struct cpuinfo_topology { > // Real APIC ID read from the local APIC > @@ -104,7 +108,7 @@ struct cpuinfo_topology { > > // Hardware defined CPU-type > union { > - u32 cpu_type; > + u32 hw_cpu_type; > struct { > // CPUID.1A.EAX[23-0] > u32 intel_native_model_id :24; > @@ -119,8 +123,14 @@ struct cpuinfo_topology { > amd_type :4; > }; > }; > + > + // Linux vendor-agnostic CPU type > + enum x86_topology_cpu_type cpu_type; > }; > > +/* > + * CPU type and hardware bug flags. Kept separately for each CPU. > + */ > struct cpuinfo_x86 { > union { > /* > diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h > index 8fb61d2465eb..ef76ba674f1b 100644 > --- a/arch/x86/include/asm/topology.h > +++ b/arch/x86/include/asm/topology.h > @@ -114,12 +114,6 @@ enum x86_topology_domains { > TOPO_MAX_DOMAIN, > }; > > -enum x86_topology_cpu_type { > - TOPO_CPU_TYPE_PERFORMANCE, > - TOPO_CPU_TYPE_EFFICIENCY, > - TOPO_CPU_TYPE_UNKNOWN, > -}; > - > struct x86_topology_system { > unsigned int dom_shifts[TOPO_MAX_DOMAIN]; > unsigned int dom_size[TOPO_MAX_DOMAIN]; > @@ -160,7 +154,6 @@ extern unsigned int __num_nodes_per_package; > struct cpuinfo_x86; > > const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); > -enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); > > static inline unsigned int topology_max_packages(void) > { > diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c > index be4c5e9e5ff6..b8f5dd0a8117 100644 > --- a/arch/x86/kernel/acpi/cppc.c > +++ b/arch/x86/kernel/acpi/cppc.c > @@ -241,7 +241,6 @@ EXPORT_SYMBOL_GPL(amd_detect_prefcore); > */ > int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) > { > - enum x86_topology_cpu_type core_type = get_topology_cpu_type(&cpu_data(cpu)); > bool prefcore; > int ret; > u32 tmp; > @@ -273,8 +272,9 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) > > /* detect if running on heterogeneous design */ > if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { > - switch (core_type) { > + switch (cpu_data(cpu).topo.cpu_type) { > case TOPO_CPU_TYPE_UNKNOWN: > + case TOPO_CPU_TYPE_ANY: > pr_warn("Undefined core type found for cpu %d\n", cpu); > break; > case TOPO_CPU_TYPE_PERFORMANCE: > diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c > index 4604802692da..7ab077f0cc66 100644 > --- a/arch/x86/kernel/cpu/match.c > +++ b/arch/x86/kernel/cpu/match.c > @@ -5,34 +5,6 @@ > #include <linux/export.h> > #include <linux/slab.h> > > -/** > - * x86_match_vendor_cpu_type - helper function to match the hardware defined > - * cpu-type for a single entry in the x86_cpu_id > - * table. Note, this function does not match the > - * generic cpu-types TOPO_CPU_TYPE_EFFICIENCY and > - * TOPO_CPU_TYPE_PERFORMANCE. > - * @c: Pointer to the cpuinfo_x86 structure of the CPU to match. > - * @m: Pointer to the x86_cpu_id entry to match against. > - * > - * Return: true if the cpu-type matches, false otherwise. > - */ > -static bool x86_match_vendor_cpu_type(struct cpuinfo_x86 *c, const struct x86_cpu_id *m) > -{ > - if (m->type == X86_CPU_TYPE_ANY) > - return true; > - > - /* Hybrid CPUs are special, they are assumed to match all cpu-types */ > - if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) > - return true; > - > - if (c->x86_vendor == X86_VENDOR_INTEL) > - return m->type == c->topo.intel_type; > - if (c->x86_vendor == X86_VENDOR_AMD) > - return m->type == c->topo.amd_type; > - > - return false; > -} > - > /** > * x86_match_cpu - match current CPU against an array of x86_cpu_ids > * @match: Pointer to array of x86_cpu_ids. Last entry terminated with > @@ -81,7 +53,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) > continue; > if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) > continue; > - if (!x86_match_vendor_cpu_type(c, m)) > + if (m->type != X86_CPU_TYPE_ANY && c->topo.cpu_type != m->type) > continue; > return m; > } > diff --git a/arch/x86/kernel/cpu/topology.h b/arch/x86/kernel/cpu/topology.h > index 37326297f80c..74e02bacd854 100644 > --- a/arch/x86/kernel/cpu/topology.h > +++ b/arch/x86/kernel/cpu/topology.h > @@ -22,6 +22,7 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, > bool cpu_parse_topology_ext(struct topo_scan *tscan); > void cpu_parse_topology_amd(struct topo_scan *tscan); > void cpu_topology_fixup_amd(struct topo_scan *tscan); > +enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); > > static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom) > { > diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c > index da080d732e10..c5a6944df86a 100644 > --- a/arch/x86/kernel/cpu/topology_amd.c > +++ b/arch/x86/kernel/cpu/topology_amd.c > @@ -177,8 +177,10 @@ static void topoext_fixup(struct topo_scan *tscan) > > static void parse_topology_amd(struct topo_scan *tscan) > { > - if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) > - tscan->c->topo.cpu_type = cpuid_ebx(0x80000026); > + if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) { > + tscan->c->topo.hw_cpu_type = cpuid_ebx(0x80000026); > + tscan->c->topo.cpu_type = get_topology_cpu_type(tscan->c); > + } > > /* > * Try to get SMT, CORE, TILE, and DIE shifts from extended > diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c > index cf7513416b70..b9d025f3373a 100644 > --- a/arch/x86/kernel/cpu/topology_common.c > +++ b/arch/x86/kernel/cpu/topology_common.c > @@ -168,8 +168,12 @@ static void parse_topology(struct topo_scan *tscan, bool early) > case X86_VENDOR_INTEL: > if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan)) > parse_legacy(tscan); > - if (c->cpuid_level >= 0x1a) > - c->topo.cpu_type = cpuid_eax(0x1a); > + > + if (c->cpuid_level >= 0x1a) { > + c->topo.hw_cpu_type = cpuid_eax(0x1a); > + c->topo.cpu_type = get_topology_cpu_type(c); > + } > + > break; > } > } > Ack! I will send a V2 patch set that includes suggested changes and the LP core patches. ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 2/2] x86/topology: Add TOPO_CPU_TYPE_LOW_POWER 2026-06-29 9:43 [PATCH 0/2] x86/topology: Add support for Low Power cpu_type Vishal Badole 2026-06-29 9:43 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Vishal Badole @ 2026-06-29 9:43 ` Vishal Badole 1 sibling, 0 replies; 25+ messages in thread From: Vishal Badole @ 2026-06-29 9:43 UTC (permalink / raw) To: tglx, mingo, bp, dave.hansen, x86, hpa, rafael, lenb Cc: linux-kernel, linux-acpi, peterz, tony.luck, chang.seok.bae, wei.w.wang, Vishal Badole AMD heterogeneous parts report a third core type via CPUID Fn0x80000026 EBX[31:28] (Extended CPU Topology, Core Type): 0 - Performance 1 - Efficiency 2 - Low Power get_topology_cpu_type() only translates the first two, so on parts that ship low-power cores the third type falls through to TOPO_CPU_TYPE_UNKNOWN. That has two visible effects: - /sys/kernel/debug/x86/topo/cpus/* reports cpu_type "unknown" via get_topology_cpu_type_name(). - amd_get_boost_ratio_numerator() hits the default arm of its x86_topology_cpu_type switch and uses the CPPC_HIGHEST_PERF_PREFCORE fallback instead of scaling by amd_get_highest_perf() as efficiency cores do. Add TOPO_CPU_TYPE_LOW_POWER, translate AMD_CPU_TYPE_LOW_POWER to it in get_topology_cpu_type(), and expose a "low_power" name via get_topology_cpu_type_name(). In amd_get_boost_ratio_numerator(), share the efficiency-core arm of the switch with the new type so low-power cores scale by amd_get_highest_perf() rather than the performance-core ceiling. The new case sits under the existing cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES) gate and therefore applies to every HTR_CORES-capable AMD/Hygon part that reports core type 2. Signed-off-by: Vishal Badole <Vishal.Badole@amd.com> --- arch/x86/include/asm/topology.h | 1 + arch/x86/kernel/acpi/cppc.c | 3 ++- arch/x86/kernel/cpu/topology_common.c | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 9658b5676ce6..1e65a6ea5de4 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -117,6 +117,7 @@ enum x86_topology_domains { enum x86_topology_cpu_type { TOPO_CPU_TYPE_PERFORMANCE, TOPO_CPU_TYPE_EFFICIENCY, + TOPO_CPU_TYPE_LOW_POWER, TOPO_CPU_TYPE_UNKNOWN, }; diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index d7c8ef1e354d..df2c7579309c 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -281,8 +281,9 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator) /* use the max scale for performance cores */ *numerator = CPPC_HIGHEST_PERF_PERFORMANCE; return 0; + case TOPO_CPU_TYPE_LOW_POWER: case TOPO_CPU_TYPE_EFFICIENCY: - /* use the highest perf value for efficiency cores */ + /* use the highest perf value for efficiency and low-power cores */ ret = amd_get_highest_perf(cpu, &tmp); if (ret) return ret; diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c index e1cc25a115ca..8c8267c812e0 100644 --- a/arch/x86/kernel/cpu/topology_common.c +++ b/arch/x86/kernel/cpu/topology_common.c @@ -44,6 +44,7 @@ enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c) switch (c->topo.amd_type) { case AMD_CPU_TYPE_PERFORMANCE: return TOPO_CPU_TYPE_PERFORMANCE; case AMD_CPU_TYPE_EFFICIENCY: return TOPO_CPU_TYPE_EFFICIENCY; + case AMD_CPU_TYPE_LOW_POWER: return TOPO_CPU_TYPE_LOW_POWER; } } @@ -57,6 +58,8 @@ const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c) return "performance"; case TOPO_CPU_TYPE_EFFICIENCY: return "efficiency"; + case TOPO_CPU_TYPE_LOW_POWER: + return "low_power"; default: return "unknown"; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-08-28 19:54 UTC | newest] Thread overview: 25+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-29 9:43 [PATCH 0/2] x86/topology: Add support for Low Power cpu_type Vishal Badole 2026-06-29 9:43 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Vishal Badole 2026-07-02 0:27 ` Borislav Petkov 2026-07-02 22:06 ` Thomas Gleixner 2026-07-02 23:03 ` Borislav Petkov 2026-07-03 19:32 ` Borislav Petkov 2026-07-03 19:39 ` Thomas Gleixner 2026-07-06 18:29 ` Pawan Gupta 2026-07-07 0:47 ` Borislav Petkov 2026-07-07 17:52 ` Pawan Gupta 2026-07-07 19:29 ` Thomas Gleixner 2026-07-07 20:46 ` Pawan Gupta 2026-07-07 23:24 ` Thomas Gleixner 2026-07-21 3:18 ` [PATCH] x86/topo: Map vendor CPU types to generic Linux such types Borislav Petkov 2026-07-22 18:09 ` Pawan Gupta 2026-07-22 18:31 ` Borislav Petkov 2026-07-22 19:22 ` Pawan Gupta 2026-07-22 19:51 ` Borislav Petkov 2026-07-22 20:57 ` Pawan Gupta 2026-07-22 21:23 ` Borislav Petkov 2026-08-27 20:44 ` Borislav Petkov 2026-08-28 6:04 ` Pawan Gupta 2026-08-28 19:54 ` Pawan Gupta 2026-07-21 9:08 ` [PATCH 1/2] x86/topology: Name the AMD core-type values Badole, Vishal 2026-06-29 9:43 ` [PATCH 2/2] x86/topology: Add TOPO_CPU_TYPE_LOW_POWER Vishal Badole
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox