[PATCH v7 093/120] x86/cpuid: Parse CPUID(0x23)
"Ahmed S. Darwish" <[email protected]> Thu, 28 May 2026 17:38:55 +0200
| Newsgroups | dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Parse Intel PMU CPUID(0x23), and all its known subleaves. This allows converting their call sites to the CPUID API next. Note, for all subleaves, make sure that subleaf 0 declares their support beforehand. Signed-off-by: Ahmed S. Darwish <[email protected]> --- arch/x86/include/asm/cpuid/types.h | 6 ++++++ arch/x86/kernel/cpu/cpuid_parser.c | 33 ++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/cpuid_parser.h | 7 +++++++ 3 files changed, 46 insertions(+) diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h index 81a84483297c..08c338909506 100644 --- a/arch/x86/include/asm/cpuid/types.h +++ b/arch/x86/include/asm/cpuid/types.h @@ -222,6 +222,12 @@ struct cpuid_leaves { CPUID_LEAF ( 0x15, 0 ); CPUID_LEAF ( 0x16, 0 ); CPUID_LEAF ( 0x1c, 0 ); + CPUID_LEAF ( 0x23, 0 ); + CPUID_LEAF ( 0x23, 1 ); + CPUID_LEAF ( 0x23, 2 ); + CPUID_LEAF ( 0x23, 3 ); + CPUID_LEAF ( 0x23, 4 ); + CPUID_LEAF ( 0x23, 5 ); CPUID_LEAF ( 0x80000000, 0 ); CPUID_LEAF ( 0x80000002, 0 ); CPUID_LEAF ( 0x80000003, 0 ); diff --git a/arch/x86/kernel/cpu/cpuid_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c index 7ab4e01c6c33..452b5b317e4d 100644 --- a/arch/x86/kernel/cpu/cpuid_parser.c +++ b/arch/x86/kernel/cpu/cpuid_parser.c @@ -97,6 +97,39 @@ cpuid_read_0x2(const struct cpuid_parse_entry *e, const struct cpuid_read_output output->info->nr_entries = 1; } +static bool cpuid_0x23_has_subleaf(u32 subleaf) +{ + struct leaf_0x23_0 l; + + cpuid_read_subleaf(0x23, 0, &l); + + switch (subleaf) { + case 0: return l.subleaf_0; + case 1: return l.counters_subleaf; + case 2: return l.acr_subleaf; + case 3: return l.events_subleaf; + case 4: return l.pebs_caps_subleaf; + case 5: return l.pebs_subleaf; + default: return false; + } +} + +#define define_cpuid_0x23_subleaf_read_function(subl) \ +static void \ +cpuid_read_0x23_##subl(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output) \ +{ \ + if (!cpuid_0x23_has_subleaf(subl)) \ + return; \ + \ + cpuid_read_generic(e, output); \ +} + +define_cpuid_0x23_subleaf_read_function(1); +define_cpuid_0x23_subleaf_read_function(2); +define_cpuid_0x23_subleaf_read_function(3); +define_cpuid_0x23_subleaf_read_function(4); +define_cpuid_0x23_subleaf_read_function(5); + /* * Shared read function for Intel CPUID(0x4) and AMD CPUID(0x8000001d), as both have * the same subleaf enumeration logic and register output format. diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h index bd3c99cb985c..6767923f86d9 100644 --- a/arch/x86/kernel/cpu/cpuid_parser.h +++ b/arch/x86/kernel/cpu/cpuid_parser.h @@ -156,6 +156,12 @@ struct cpuid_parse_entry { CPUID_PARSE_ENTRY ( 0x15, 0, generic ), \ CPUID_PARSE_ENTRY ( 0x16, 0, generic ), \ CPUID_PARSE_ENTRY ( 0x1c, 0, generic ), \ + CPUID_PARSE_ENTRY ( 0x23, 0, generic ), \ + CPUID_PARSE_ENTRY ( 0x23, 1, 0x23_1 ), \ + CPUID_PARSE_ENTRY ( 0x23, 2, 0x23_2 ), \ + CPUID_PARSE_ENTRY ( 0x23, 3, 0x23_3 ), \ + CPUID_PARSE_ENTRY ( 0x23, 4, 0x23_4 ), \ + CPUID_PARSE_ENTRY ( 0x23, 5, 0x23_5 ), \ CPUID_PARSE_ENTRY ( 0x80000000, 0, 0x80000000 ), \ CPUID_PARSE_ENTRY ( 0x80000002, 0, generic ), \ CPUID_PARSE_ENTRY ( 0x80000003, 0, generic ), \ @@ -212,6 +218,7 @@ struct cpuid_vendor_entry { CPUID_VENDOR_ENTRY(0x15, X86_VENDOR_INTEL, X86_VENDOR_CENTAUR, X86_VENDOR_ZHAOXIN),\ CPUID_VENDOR_ENTRY(0x16, X86_VENDOR_INTEL), \ CPUID_VENDOR_ENTRY(0x1c, X86_VENDOR_INTEL), \ + CPUID_VENDOR_ENTRY(0x23, X86_VENDOR_INTEL), \ CPUID_VENDOR_ENTRY(0x8000001d, X86_VENDOR_AMD, X86_VENDOR_HYGON), \ CPUID_VENDOR_ENTRY(0x80860000, X86_VENDOR_TRANSMETA), \ CPUID_VENDOR_ENTRY(0x80860001, X86_VENDOR_TRANSMETA), \ -- 2.54.0