[PATCH v1 18/26] x86/cpuid: Scan deterministic cache params CPUID leaves

"Ahmed S. Darwish" <[email protected]>
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Add CPUID scanner logic for Intel CPUID(0x4) and AMD CPUID(0x8000001d).
Define a single CPUID "deterministic cache" read function for both leaves
as both have the same subleaf cache enumeration logic.

Introduce __define_cpuid_read_function() to avoid duplication between
cpuid_read_generic(), the CPUID scanner default read function, and the
new cpuid_read_deterministic_cache().

Signed-off-by: Ahmed S. Darwish <[email protected]>
---
 arch/x86/include/asm/cpuid/types.h  |  2 ++
 arch/x86/kernel/cpu/cpuid_scanner.c | 40 ++++++++++++++++++++++++-----
 arch/x86/kernel/cpu/cpuid_scanner.h |  4 ++-
 3 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index b8e525725def..2ac3d05c3fe4 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -181,7 +181,9 @@ struct cpuid_leaves {
 	CPUID_LEAF(0x0,		0,		1);
 	CPUID_LEAF(0x1,		0,		1);
 	CPUID_LEAF(0x2,		0,		1);
+	CPUID_LEAF(0x4,		0,		8);
 	CPUID_LEAF(0x80000000,	0,		1);
+	CPUID_LEAF(0x8000001d,	0,		8);
 };
 
 /**
diff --git a/arch/x86/kernel/cpu/cpuid_scanner.c b/arch/x86/kernel/cpu/cpuid_scanner.c
index aaee1ede0472..664946ebe675 100644
--- a/arch/x86/kernel/cpu/cpuid_scanner.c
+++ b/arch/x86/kernel/cpu/cpuid_scanner.c
@@ -10,15 +10,43 @@
 
 #include "cpuid_scanner.h"
 
+/**
+ * __define_cpuid_read_function() - Generate a CPUID scanner read function
+ * @_suffix:	Suffix for the generated function name (full name: cpuid_read_@_suffix())
+ * @_leaf_t:	Type to cast the CPUID query output storage pointer
+ * @_leaf:	Name of the CPUID query storage pointer
+ * @_break_c:	Condition to break the CPUID scanning loop, which may reference @_leaf,
+ *		and where @_leaf stores each iteration's CPUID query output.
+ *
+ * Define a CPUID scanner read function according to the requirements stated
+ * at &struct cpuid_scan_entry->read().
+ */
+#define __define_cpuid_read_function(_suffix, _leaf_t, _leaf, _break_c)				\
+static void											\
+cpuid_read_##_suffix(const struct cpuid_scan_entry *e, struct cpuid_read_output *output)	\
+{												\
+	struct _leaf_t *_leaf = (struct _leaf_t *)output->leaf;					\
+												\
+	static_assert(sizeof(*_leaf) == 16);							\
+												\
+	output->info->nr_entries = 0;								\
+	for (int i = 0; i < e->maxcnt; i++, _leaf++, output->info->nr_entries++) {		\
+		cpuid_subleaf(e->leaf, e->subleaf + i, _leaf);					\
+		if (_break_c)									\
+			break;									\
+	}											\
+}
+
 /*
  * Default CPUID scanner read function
  */
-static void cpuid_read_generic(const struct cpuid_scan_entry *e, struct cpuid_read_output *output)
-{
-	output->info->nr_entries = 0;
-	for (int i = 0; i < e->maxcnt; i++, output->leaf++, output->info->nr_entries++)
-		cpuid_subleaf(e->leaf, e->subleaf + i, output->leaf);
-}
+__define_cpuid_read_function(generic, cpuid_regs, ignored, false);
+
+/*
+ * Shared read function for Intel CPUID leaf 0x4 and AMD CPUID leaf 0x8000001d,
+ * as both have the same subleaf enumeration logic and registers output format.
+ */
+__define_cpuid_read_function(deterministic_cache, leaf_0x4_0, leaf, leaf->cache_type == 0);
 
 static void cpuid_read_0x2(const struct cpuid_scan_entry *e, struct cpuid_read_output *output)
 {
diff --git a/arch/x86/kernel/cpu/cpuid_scanner.h b/arch/x86/kernel/cpu/cpuid_scanner.h
index dc1d518c9768..a09110a4c72c 100644
--- a/arch/x86/kernel/cpu/cpuid_scanner.h
+++ b/arch/x86/kernel/cpu/cpuid_scanner.h
@@ -93,7 +93,9 @@ struct cpuid_scan_entry {
 	SCAN_ENTRY(0x0,		0,		generic),			\
 	SCAN_ENTRY(0x1,		0,		generic),			\
 	SCAN_ENTRY(0x2,		0,		0x2),				\
-	SCAN_ENTRY(0x80000000,  0,              0x80000000),
+	SCAN_ENTRY(0x4,		0,		deterministic_cache),		\
+	SCAN_ENTRY(0x80000000,  0,              0x80000000),			\
+	SCAN_ENTRY(0x8000001d,  0,              deterministic_cache),		\
 
 /**
  * struct cpuid_scan_info - Parameters for generic CPUID scan logic
-- 
2.49.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.