[PATCH v6 63/90] x86/cpuid: Parse CPUID(0x23)

Ahmed S. Darwish posted 90 patches 6 days, 16 hours ago
[PATCH v6 63/90] x86/cpuid: Parse CPUID(0x23)
Posted by Ahmed S. Darwish 6 days, 16 hours ago
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@linutronix.de>
---
 arch/x86/include/asm/cpuid/types.h |  6 +++++
 arch/x86/kernel/cpu/cpuid_parser.c | 37 ++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/cpuid_parser.h |  7 ++++++
 3 files changed, 50 insertions(+)

diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index 128898d4434b..70ccd52a6848 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -215,6 +215,12 @@ struct cpuid_leaves {
 	CPUID_LEAF   (  0xa,		0  );
 	CPUID_LEAF   (  0x1c,		0  );
 	CPUID_LEAF   (	0x16,		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 99507e99d8d9..de11fb4116f2 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.c
+++ b/arch/x86/kernel/cpu/cpuid_parser.c
@@ -105,6 +105,43 @@ cpuid_read_0x2(const struct cpuid_parse_entry *e, const struct cpuid_read_output
  */
 define_cpuid_read_function(deterministic_cache, leaf_0x4_n, l, l->cache_type == 0);
 
+static bool cpuid_0x23_has_subleaf(u32 subleaf)
+{
+	struct leaf_0x23_0 l;
+
+	cpuid_read_subleaf(0x23, 0, &l);
+
+	if (subleaf == 1)
+		return l.counters_subleaf;
+	if (subleaf == 2)
+		return l.acr_subleaf;
+	if (subleaf == 3)
+		return l.events_subleaf;
+	if (subleaf == 4)
+		return l.pebs_caps_subleaf;
+	if (subleaf == 5)
+		return l.pebs_subleaf;
+
+	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_subleaf(e->leaf, e->subleaf, output->regs);					\
+	output->info->nr_entries = 1;								\
+}
+
+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);
+
 /*
  * Define an extended range CPUID read function
  *
diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h
index 8e147e7223e0..46f06792afb1 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.h
+++ b/arch/x86/kernel/cpu/cpuid_parser.h
@@ -149,6 +149,12 @@ struct cpuid_parse_entry {
 	CPUID_PARSE_ENTRY   (	0xa,		0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x1c,		0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x16,		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			),	\
@@ -203,6 +209,7 @@ struct cpuid_vendor_entry {
 	CPUID_VENDOR_ENTRY(0xa,		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.53.0