Re: [PATCH v7 012/120] x86/cpuid: Parse CPUID(0x80000000)

Borislav Petkov <[email protected]>
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <20260805025323.GCanKlox0DF7Gwhpf1@fat_crate.local>
On Thu, May 28, 2026 at 05:37:34PM +0200, Ahmed S. Darwish wrote:
> Add CPUID parser logic for CPUID(0x80000000).
> 
> Verify the CPUID output since legacy Intel machines without an extended
> range will repeat the highest standard CPUID leaf output instead.
> 
> This verification is similar to what is done at arch/x86/kernel/head_32.S
> and arch/x86/kernel/cpu/common.c.
> 
> References: 8a50e5135af0 ("x86-32: Use symbolic constants, safer CPUID when enabling EFER.NX")
> References: 67ad24e6d39c ("- pre5:    - Rasmus Andersen: add proper...")  # Historical git
> Signed-off-by: Ahmed S. Darwish <[email protected]>
> Cc: "H. Peter Anvin" <[email protected]>
> Link: https://lore.kernel.org/r/[email protected]
> ---
>  arch/x86/include/asm/cpuid/types.h |  4 ++++
>  arch/x86/kernel/cpu/cpuid_parser.c | 21 +++++++++++++++++++++
>  arch/x86/kernel/cpu/cpuid_parser.h |  1 +
>  3 files changed, 26 insertions(+)

Before we continue with this, I wanna a bit of a cleanup to the parser:

struct cpuid_read_output was a bit too much. And also those linebreaks should
be like I did them - this is how we usually do them.

Thx.

---
From: "Borislav Petkov (AMD)" <[email protected]>
Date: Tue, 4 Aug 2026 18:53:41 -0700
Subject: [PATCH] x86/CPU: Rename struct cpuid_read_output to struct
 cpuid_output

There's no CPUID "write" operation so there's no need to have
a cpuid_read_output thing - cpuid_output is perfectly clear. And
shortens the code just fine.

Remove the funky function signature line breaks while at it.

No functional changes.

Signed-off-by: Borislav Petkov (AMD) <[email protected]>
---
 arch/x86/kernel/cpu/cpuid_parser.c | 42 ++++++++++++++----------------
 arch/x86/kernel/cpu/cpuid_parser.h | 20 +++++++-------
 2 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/arch/x86/kernel/cpu/cpuid_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c
index 898b0c441431..dcf8fffbfb88 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.c
+++ b/arch/x86/kernel/cpu/cpuid_parser.c
@@ -11,14 +11,14 @@
 #include "cpuid_parser.h"
 
 /* Clear a single CPUID table entry */
-static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)
+static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_output *out)
 {
-	struct cpuid_regs *regs = output->regs;
+	struct cpuid_regs *regs = out->regs;
 
 	for (int i = 0; i < e->maxcnt; i++, regs++)
 		memset(regs, 0, sizeof(*regs));
 
-	memset(output->info, 0, sizeof(*output->info));
+	memset(out->info, 0, sizeof(*out->info));
 }
 
 /*
@@ -29,12 +29,11 @@ static void cpuid_clear(const struct cpuid_parse_entry *e, const struct cpuid_re
  * Default CPUID read function
  * Satisfies the requirements stated at 'struct cpuid_parse_entry'->read().
  */
-static void
-cpuid_read_generic(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)
+static void cpuid_read_generic(const struct cpuid_parse_entry *e, const struct cpuid_output *out)
 {
-	struct cpuid_regs *regs = output->regs;
+	struct cpuid_regs *regs = out->regs;
 
-	for (int i = 0; i < e->maxcnt; i++, regs++, output->info->nr_entries++)
+	for (int i = 0; i < e->maxcnt; i++, regs++, out->info->nr_entries++)
 		cpuid_read_subleaf(e->leaf, e->subleaf + i, regs);
 }
 
@@ -60,15 +59,14 @@ static unsigned int cpuid_range_max_leaf(const struct cpuid_table *t, unsigned i
 	}
 }
 
-static void
-__cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
-		    unsigned int nr_entries, unsigned int start, unsigned int end, bool fill)
+static void __cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
+				unsigned int nr_entries, unsigned int start, unsigned int end, bool fill)
 {
 	const struct cpuid_parse_entry *entry = entries;
 	unsigned int range = CPUID_RANGE(start);
 
 	for (unsigned int i = 0; i < nr_entries; i++, entry++) {
-		struct cpuid_read_output output = {
+		struct cpuid_output out = {
 			.regs = cpuid_table_regs_p(t, entry->regs_offs),
 			.info = cpuid_table_info_p(t, entry->info_offs),
 		};
@@ -76,14 +74,14 @@ __cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entrie
 		if (entry->leaf < start || entry->leaf > end)
 			continue;
 
-		cpuid_clear(entry, &output);
+		cpuid_clear(entry, &out);
 
 		/*
 		 * Read the range's anchor leaf unconditionally so that the cached
 		 * maximum valid leaf value is available for the remaining entries.
 		 */
 		if (fill && (entry->leaf == range || entry->leaf <= cpuid_range_max_leaf(t, range)))
-			entry->read(entry, &output);
+			entry->read(entry, &out);
 	}
 }
 
@@ -91,22 +89,20 @@ __cpuid_reset_table(struct cpuid_table *t, const struct cpuid_parse_entry entrie
  * Zero all cached CPUID entries within [@start-@end] range.  This is needed when
  * certain operations like MSR writes induce changes to the CPU's CPUID layout.
  */
-static void
-__cpuid_zero_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
-		   unsigned int nr_entries, unsigned int start, unsigned int end)
+static void __cpuid_zero_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
+			       unsigned int nr_entries, unsigned int start, unsigned int end)
 {
 	__cpuid_reset_table(t, entries, nr_entries, start, end, false);
 }
 
-static void
-__cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
-		   unsigned int nr_entries, unsigned int start, unsigned int end)
+static void __cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
+			       unsigned int nr_entries, unsigned int start, unsigned int end)
 {
 	__cpuid_reset_table(t, entries, nr_entries, start, end, true);
 }
 
-static void
-cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[], unsigned int nr_entries)
+static void cpuid_fill_table(struct cpuid_table *t, const struct cpuid_parse_entry entries[],
+			     unsigned int nr_entries)
 {
 	static const struct {
 		unsigned int start;
@@ -127,8 +123,8 @@ static void __cpuid_scan_cpu_full(struct cpuinfo_x86 *c)
 	cpuid_fill_table(table, cpuid_parse_entries, nr_entries);
 }
 
-static void
-__cpuid_scan_cpu_partial(struct cpuinfo_x86 *c, unsigned int start_leaf, unsigned int end_leaf)
+static void __cpuid_scan_cpu_partial(struct cpuinfo_x86 *c, unsigned int start_leaf,
+				     unsigned int end_leaf)
 {
 	unsigned int nr_entries = ARRAY_SIZE(cpuid_parse_entries);
 	struct cpuid_table *table = &c->cpuid;
diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h
index df627306cc8c..3d8337323958 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.h
+++ b/arch/x86/kernel/cpu/cpuid_parser.h
@@ -35,21 +35,21 @@
  * Translation of compile time offsets to generic runtime pointers:
  */
 
-static inline struct cpuid_regs *
-cpuid_table_regs_p(const struct cpuid_table *t, unsigned long regs_offset)
+static inline struct cpuid_regs *cpuid_table_regs_p(const struct cpuid_table *t,
+						    unsigned long regs_offset)
 {
 	return (struct cpuid_regs *)((unsigned long)(&t->leaves) + regs_offset);
 }
 
-static inline struct leaf_parse_info *
-cpuid_table_info_p(const struct cpuid_table *t, unsigned long info_offset)
+static inline struct leaf_parse_info *cpuid_table_info_p(const struct cpuid_table *t,
+							 unsigned long info_offset)
 {
 	return (struct leaf_parse_info *)((unsigned long)(&t->leaves) + info_offset);
 }
 
 /**
- * struct cpuid_read_output - Output of a CPUID read operation
- * @regs:	Pointer to an array of CPUID outputs, where each array element covers the
+ * struct cpuid_output - Output of a CPUID operation
+ * @regs:	Pointer to an array of CPUID results, where each array element covers the
  *		full EAX->EDX output range.
  * @info:	Pointer to query info; for saving the number of filled elements at @regs.
  *
@@ -59,7 +59,7 @@ cpuid_table_info_p(const struct cpuid_table *t, unsigned long info_offset)
  *
  * See struct cpuid_parse_entry.read().
  */
-struct cpuid_read_output {
+struct cpuid_output {
 	struct cpuid_regs	*regs;
 	struct leaf_parse_info	*info;
 };
@@ -74,8 +74,8 @@ struct cpuid_read_output {
  *		passed to cpuid_table_info_p().
  * @maxcnt:	Maximum number of output storage entries available for the CPUID query.
  * @read:	Read function for this entry.  It must save the parsed CPUID output to the passed
- *		'struct cpuid_read_output'->regs array of size >= @maxcnt.  It must set
- *		'struct cpuid_read_output'->info.nr_entries to the number of CPUID output entries
+ *		'struct cpuid_output'->regs array of size >= @maxcnt.  It must set
+ *		'struct cpuid_output'->info.nr_entries to the number of CPUID output entries
  *		parsed and filled.  A generic implementation is provided at cpuid_read_generic().
  */
 struct cpuid_parse_entry {
@@ -84,7 +84,7 @@ struct cpuid_parse_entry {
 	unsigned int	regs_offs;
 	unsigned int	info_offs;
 	unsigned int	maxcnt;
-	void		(*read)(const struct cpuid_parse_entry *e, const struct cpuid_read_output *o);
+	void		(*read)(const struct cpuid_parse_entry *e, const struct cpuid_output *o);
 };
 
 #define __CPUID_PARSE_ENTRY(_leaf, _subleaf, _suffix, _reader_fn)		\
-- 
2.53.0

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
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.