Re: [PATCH v7 012/120] x86/cpuid: Parse CPUID(0x80000000)
From: Borislav Petkov
Date: Mon Jun 01 2026 - 18:23:27 EST
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 <darwi@xxxxxxxxxxxxx>
> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
> Link: https://lore.kernel.org/r/d4fcfd91-cc92-4b3c-9dd2-56ecd754cecc@xxxxxxxxxx
> ---
> 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