lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250815070227.19981-23-darwi@linutronix.de>
Date: Fri, 15 Aug 2025 09:02:15 +0200
From: "Ahmed S. Darwish" <darwi@...utronix.de>
To: Borislav Petkov <bp@...en8.de>,
	Ingo Molnar <mingo@...hat.com>,
	Dave Hansen <dave.hansen@...ux.intel.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
	Andrew Cooper <andrew.cooper3@...rix.com>,
	"H. Peter Anvin" <hpa@...or.com>,
	David Woodhouse <dwmw2@...radead.org>,
	Sean Christopherson <seanjc@...gle.com>,
	Peter Zijlstra <peterz@...radead.org>,
	Sohil Mehta <sohil.mehta@...el.com>,
	John Ogness <john.ogness@...utronix.de>,
	x86@...nel.org,
	x86-cpuid@...ts.linux.dev,
	LKML <linux-kernel@...r.kernel.org>,
	"Ahmed S. Darwish" <darwi@...utronix.de>
Subject: [PATCH v4 22/34] x86/cpuid: Parse 'deterministic cache parameters' CPUID leaves

Add CPUID(0x4) and CPUID(0x8000001d) support to the CPUID parser.

Query CPUID(0x4) only for Intel, Centaur, and Zhaoxin as these are the
only x86 vendors where it is supported.  Query CPUID(0x8000001d) only for
AMD and Hygon.

Define a single output parsing function for both CPUID leaves, as both
have the same subleaf cache enumeration logic.

Introduce the macro

    __define_cpuid_read_function()

to avoid code duplication between the CPUID parser default read function,
cpuid_read_generic(), and the new CPUID(0x4)/CPUID(0x8000001d) parsing
logic.

Signed-off-by: Ahmed S. Darwish <darwi@...utronix.de>
---
 arch/x86/include/asm/cpuid/types.h |  2 ++
 arch/x86/kernel/cpu/cpuid_parser.c | 37 +++++++++++++++++++++++++-----
 arch/x86/kernel/cpu/cpuid_parser.h |  4 ++++
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index 7bbf0671cb95..89c399629e58 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -216,7 +216,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_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c
index c340ad6eca3d..60da1e452831 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.c
+++ b/arch/x86/kernel/cpu/cpuid_parser.c
@@ -22,17 +22,36 @@ static const struct cpuid_vendor_entry cpuid_vendor_entries[] = {
  * Leaf read functions:
  */
 
-/*
- * Default CPUID parser read function
+/**
+ * __define_cpuid_parser_read_function() - Generate a CPUID parser leaf read function
+ * @suffix:	Generated function name suffix (full name becomes: cpuid_read_@...fix())
+ * @_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 parsing loop, which may reference @_leaf, and
+ *		where @_leaf stores each iteration's CPUID query output.
  *
  * Satisfies the requirements stated at 'struct cpuid_parse_entry'->read().
+ * Define a CPUID parser read function according to the requirements stated at
+ * 'struct cpuid_parse_entry'->read().
  */
-static void cpuid_read_generic(const struct cpuid_parse_entry *e, struct cpuid_read_output *output)
-{
-	for (int i = 0; i < e->maxcnt; i++, output->regs++, output->info->nr_entries++)
-		cpuid_read_subleaf(e->leaf, e->subleaf + i, output->regs);
+#define __define_cpuid_parser_read_function(suffix, _leaf_t, _leaf, _break_c)			\
+static void											\
+cpuid_read_##suffix(const struct cpuid_parse_entry *e, struct cpuid_read_output *output)	\
+{												\
+	struct _leaf_t *_leaf = (struct _leaf_t *)output->regs;					\
+												\
+	for (int i = 0; i < e->maxcnt; i++, _leaf++, output->info->nr_entries++) {		\
+		cpuid_read_subleaf(e->leaf, e->subleaf + i, _leaf);				\
+		if (_break_c)									\
+			break;									\
+	}											\
 }
 
+/*
+ * Default CPUID parser read function
+ */
+__define_cpuid_parser_read_function(generic, cpuid_regs, ignored, false);
+
 static void cpuid_read_0x2(const struct cpuid_parse_entry *e, struct cpuid_read_output *output)
 {
 	union leaf_0x2_regs *regs = (union leaf_0x2_regs *)output->regs;
@@ -71,6 +90,12 @@ static void cpuid_read_0x2(const struct cpuid_parse_entry *e, struct cpuid_read_
 	output->info->nr_entries = 1;
 }
 
+/*
+ * Shared read function for Intel CPUID(0x4) and AMD CPUID(0x8000001d), as both have
+ * the same subleaf enumeration logic and registers output format.
+ */
+__define_cpuid_parser_read_function(deterministic_cache, leaf_0x4_0, l, l->cache_type == 0);
+
 static void cpuid_read_0x80000000(const struct cpuid_parse_entry *e, struct cpuid_read_output *output)
 {
 	struct leaf_0x80000000_0 *l = (struct leaf_0x80000000_0 *)output->regs;
diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h
index 0e3ac9a7700d..15ad37b0b3b2 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.h
+++ b/arch/x86/kernel/cpu/cpuid_parser.h
@@ -128,7 +128,9 @@ struct cpuid_parse_entry {
 #define CPUID_COMMON_PARSE_ENTRIES							\
 	/*		  Leaf		Subleaf		Reader function */		\
 	CPUID_PARSE_ENTRY(0x2,		0,		0x2),				\
+	CPUID_PARSE_ENTRY(0x4,		0,		deterministic_cache),		\
 	CPUID_PARSE_ENTRY(0x80000000,	0,		0x80000000),			\
+	CPUID_PARSE_ENTRY(0x8000001d,	0,		deterministic_cache),		\
 
 /*
  * CPUID parser tables repository:
@@ -162,5 +164,7 @@ struct cpuid_vendor_entry {
 #define CPUID_VENDOR_ENTRIES								\
  	/*		   Leaf		Vendor list */					\
 	CPUID_VENDOR_ENTRY(0x2,		X86_VENDOR_INTEL, X86_VENDOR_CENTAUR, X86_VENDOR_ZHAOXIN),\
+	CPUID_VENDOR_ENTRY(0x4,		X86_VENDOR_INTEL, X86_VENDOR_CENTAUR, X86_VENDOR_ZHAOXIN),\
+	CPUID_VENDOR_ENTRY(0x8000001d,	X86_VENDOR_AMD, X86_VENDOR_HYGON),		\
 
 #endif /* _ARCH_X86_CPUID_PARSER_H */
-- 
2.50.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ