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

Borislav Petkov <[email protected]> Mon, 1 Jun 2026 15:22:39 -0700
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <20260601222239.GBah4GL777WIRuj-Wk@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

Why are those here?

insert_tag: WARNING: Unknown tag: [References: 67ad24e6d39c ("- pre5:    - Rasmus Andersen: add proper...")  # Historical git], ignoring it... 
insert_tag: WARNING: Unknown tag: [References: 8a50e5135af0 ("x86-32: Use symbolic constants, safer CPUID when enabling EFER.NX")], ignoring it... 

> 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(+)
> 
> diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
> index 3d0e611c97ba..c020fb8fed59 100644
> --- a/arch/x86/include/asm/cpuid/types.h
> +++ b/arch/x86/include/asm/cpuid/types.h
> @@ -36,7 +36,10 @@ enum cpuid_regs_idx {
>  #define CPUID_RANGE_MAX(idx)	(CPUID_RANGE(idx) + 0xffff)
>  
>  #define CPUID_BASE_START	0x00000000
> +#define CPUID_EXT_START		0x80000000
> +
>  #define CPUID_BASE_END		CPUID_RANGE_MAX(CPUID_BASE_START)
> +#define CPUID_EXT_END		CPUID_RANGE_MAX(CPUID_EXT_START)
>  
>  /*
>   * Types for CPUID(0x2) parsing:
> @@ -203,6 +206,7 @@ struct cpuid_leaves {
>  	/*		Leaf		Subleaf number (or max number of subleaves) */
>  	CPUID_LEAF   (	0x0,		0  );
>  	CPUID_LEAF   (	0x1,		0  );
> +	CPUID_LEAF   (  0x80000000,	0  );
>  };
>  
>  /*
> diff --git a/arch/x86/kernel/cpu/cpuid_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c
> index 898b0c441431..2cebe15f75d4 100644
> --- a/arch/x86/kernel/cpu/cpuid_parser.c
> +++ b/arch/x86/kernel/cpu/cpuid_parser.c
> @@ -38,6 +38,24 @@ cpuid_read_generic(const struct cpuid_parse_entry *e, const struct cpuid_read_ou
>  		cpuid_read_subleaf(e->leaf, e->subleaf + i, regs);
>  }
>  
> +static void
> +cpuid_read_0x80000000(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)

For your whole patchset - remove all those linebreaks pls.

> +{
> +	struct leaf_0x80000000_0 *el0 = (struct leaf_0x80000000_0 *)output->regs;
> +
> +	cpuid_read_subleaf(e->leaf, e->subleaf, el0);
> +
> +	/*
> +	 * Protect against Intel 32-bit CPUs lacking an extended CPUID range.  A
> +	 * CPUID(0x80000000) query on such machines will repeat the output of the
> +	 * highest standard CPUID leaf instead.
> +	 */
> +	if (CPUID_RANGE(el0->max_ext_leaf) != CPUID_EXT_START)
> +		return;
> +
> +	output->info->nr_entries = 1;
> +}
> +
>  /*
>   * CPUID parser table:
>   */
> @@ -53,9 +71,11 @@ static const struct cpuid_parse_entry cpuid_parse_entries[] = {
>  static unsigned int cpuid_range_max_leaf(const struct cpuid_table *t, unsigned int range)
>  {
>  	const struct leaf_0x0_0 *l0 = __cpuid_table_subleaf(t, 0x0, 0);
> +	const struct leaf_0x80000000_0 *el0 = __cpuid_table_subleaf(t, 0x80000000, 0);

The tip-tree preferred ordering of variable declarations at the
beginning of a function is reverse fir tree order::

	struct long_struct_name *descriptive_name;
	unsigned long foo, bar;
	unsigned int tmp;
	int ret;

The above is faster to parse than the reverse ordering::

	int ret;
	unsigned int tmp;
	unsigned long foo, bar;
	struct long_struct_name *descriptive_name;

And even more so than random ordering::

	unsigned long foo, bar;
	int ret;
	struct long_struct_name *descriptive_name;
	unsigned int tmp;

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette