[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