[PATCH v7 093/120] x86/cpuid: Parse CPUID(0x23)
From: Ahmed S. Darwish
Date: Thu May 28 2026 - 12:12:13 EST
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 <darwi@xxxxxxxxxxxxx>
---
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