linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/26] x86: Introduce centralized CPUID model
@ 2025-05-06  5:04 Ahmed S. Darwish
  2025-05-06  5:04 ` [PATCH v1 01/26] tools/x86/kcpuid: Update bitfields to x86-cpuid-db v2.4 Ahmed S. Darwish
                   ` (27 more replies)
  0 siblings, 28 replies; 55+ messages in thread
From: Ahmed S. Darwish @ 2025-05-06  5:04 UTC (permalink / raw)
  To: Ingo Molnar, Borislav Petkov, Dave Hansen
  Cc: Thomas Gleixner, Andrew Cooper, H. Peter Anvin, John Ogness, x86,
	x86-cpuid, LKML, Ahmed S. Darwish

Hi,

This series introduces a CPUID model for the x86 subsystem.

It is based on top of the CPUID refactorings and bugfixes currently
merged at tip:x86/cpu:

    https://lore.kernel.org/lkml/20250304085152.51092-1-darwi@linutronix.de
    https://lore.kernel.org/lkml/20250324133324.23458-1-darwi@linutronix.de
    https://lore.kernel.org/lkml/20250409122233.1058601-1-darwi@linutronix.de
    https://lore.kernel.org/lkml/20250324142042.29010-1-darwi@linutronix.de

First, deploy <asm/cpuid/leaves.h>, as generated by x86-cpuid-db. [*]
The header is in the form:

    /* SPDX-License-Identifier: MIT */
    /* Generator: x86-cpuid-db v2.4 */

    /*
     * Leaf 0x0
     * Maximum standard leaf number + CPU vendor string
     */

    struct leaf_0x0_0 {
     	u32	max_std_leaf		: 32; // Highest standard CPUID leaf supported
     	u32	cpu_vendorid_0		: 32; // CPU vendor ID string bytes 0 - 3
     	u32	cpu_vendorid_2		: 32; // CPU vendor ID string bytes 8 - 11
     	u32	cpu_vendorid_1		: 32; // CPU vendor ID string bytes 4 - 7
    };

    /*
     * Leaf 0x1
     * CPU FMS (Family/Model/Stepping) + standard feature flags
     */

    struct leaf_0x1_0 {
	// eax
	u32	stepping		:  4, // Stepping ID
		base_model		:  4, // Base CPU model ID
		base_family_id		:  4, // Base CPU family ID
		...;
	// ebx
	u32	brand_id		:  8, // Brand index
		clflush_size		:  8, // CLFLUSH instruction cache line size
		n_logical_cpu		:  8, // Logical CPU count
		local_apic_id		:  8; // Initial local APIC physical ID
	// ecx		
	...
    };

    ...

where for each 'struct leaf_0xN_M', N is the leaf number and M is the
subleaf.  The bitfields mirror the x86-cpuid-db kcpuid auto-generated
file, as already merged mainline at tools/arch/x86/kcpuid/cpuid.csv.

Create a 'struct cpuid_leaves' in <cpuid/types.h> to hold scanned CPUID
data:

    struct cpuid_leaves {
     	struct leaf_0x0_0	leaf_0x0_0[1];
     	struct leaf_query_info	leaf_0x0_0_info;

     	struct leaf_0x1_0	leaf_0x1_0[1];
     	struct leaf_query_info	leaf_0x0_0_info;

     	struct leaf_0x4_0	leaf_0x4_0[8];
     	struct leaf_query_info	leaf_0x4_0_info;
     	...
    };

where the 'struct leaf_0xN_M' definitions are auto-generated.  Use arrays
to handle CPUID leaves with uniform subleaf structures, which is typical
for enumerating hierarchical objects; e.g., CPUID(0x4) cache topology
enumeration, CPUID(0xd) XSAVE enumeration, CPUID(0x12) SGX enclaves
enumeration, and CPUID(0x8000001d) AMD cache enumeration.

For each entry in the CPUID table, associate a 'struct leaf_query_info'.
It is to be filled for each available CPUID leaf by the generic CPUID
scanning logic.

Define a 'struct cpuid_table' for caching each CPU's CPUID table, and
embed in it a 'struct cpuid_leaves' instance.  This way, global table
data can also be added.  Embed an instance of 'struct cpuid_table' in the
'struct cpuinfo_x86' CPU capability structure(s):

    struct cpuinfo_x86 {
     	...
     	struct cpuid_table	cpuid_table;
     	...
    };

This way, centralized CPUID data can be accessed on early boot using
'boot_cpu_data', and later on a per-CPU basis using the 'cpu_info'
per-CPU CPU capability structures.

Build the CPUID data in that "struct leaf_0xN_M leaf_0xN_M" format to
facilitate direct CPUID table and CPUID bitfields access.  Accessing
scanned CPUID bitfields can be done using statements like:

    u32 level = cpudata_cpuid(c, 0x0)->max_std_leaf;

    const struct leaf_0x1_0 *l1 = cpudata_cpuid(c, 0x1);
    c->x86_stepping		= l1->stepping;
    c->x86_clflush_size		= l1->clflush_size * 8;

    const struct leaf_0x80000005_0 *el5 = cpudata_cpuid(c, 0x80000005);
    unsigned assoc		= el5->l1_dcache_assoc;
    unsigned line_size		= el5->l1_dcache_line_size;

    unsigned l1d_index = 0;	// CPUID(0x4) subleaf 0: L1 data cache
    unsigned l1i_index = 1;	// CPUID(0x4) subleaf 1: L1 inst cache
    const struct leaf_0x4_0 *l1d = cpudata_cpuid_index(0x4, l1d_index);
    const struct leaf_0x4_0 *l1i = cpudata_cpuid_index(0x4, l1i_index);
    
    /* Then access l1d->cache_nways, l1d->cache_nsets, ... */

where in the above snippet, 'c' is the CPU's capability structure.
Define all macros at <cpuid/table_api.h>, and add proper kernel docs.

Beside the model's centralization benefits, this also avoids using the
ugly manual bit-fiddling common in a lot of CPUID call sites.  The late
part of this PQ clearly shows this.  As a start, switch the following
leaves to scanned CPUID access:

    CPUID(0x0)
    CPUID(0x1)
    CPUID(0x2)
    CPUID(0x4)
    CPUID(0x80000000)
    CPUID(0x80000005)
    CPUID(0x80000006)
    CPUID(0x8000001d)

With these converted, the entirety of the x86/cacheinfo code is void of
any direct CPUID queries.

Introduce the debugfs files 'x86/scanned_cpuid/[0-ncpus]' to dump the
cached CPUID table for each CPU.  This should help with tricky bug
reports in the future, if/when the scanned CPUID tables get
(unexpectedly) out of sync with actual hardware state.  Example output
from an Intel Core i5-8250U laptop:

   $ cat /sys/kernel/debug/x86/scanned_cpuid/cpus/1

    Leaf 0x00000000, subleaf 0:
    cached: EAX=0x00000016	EBX=0x756e6547	ECX=0x6c65746e	EDX=0x49656e69
    actual: EAX=0x00000016	EBX=0x756e6547	ECX=0x6c65746e	EDX=0x49656e69

    Leaf 0x00000001, subleaf 0:
    cached: EAX=0x000806ea	EBX=0x02100800	ECX=0x7ffafbbf	EDX=0xbfebfbff
    actual: EAX=0x000806ea	EBX=0x02100800	ECX=0x7ffafbbf	EDX=0xbfebfbff

    Leaf 0x00000002, subleaf 0:
    cached: EAX=0x76036301	EBX=0x00f0b5ff	ECX=0x00000000	EDX=0x00c30000
    actual: EAX=0x76036301	EBX=0x00f0b5ff	ECX=0x00000000	EDX=0x00c30000

    Leaf 0x00000004, subleaf 0:
    cached: EAX=0x1c004121	EBX=0x01c0003f	ECX=0x0000003f	EDX=0x00000000
    actual: EAX=0x1c004121	EBX=0x01c0003f	ECX=0x0000003f	EDX=0x00000000

    Leaf 0x00000004, subleaf 1:
    cached: EAX=0x1c004122	EBX=0x01c0003f	ECX=0x0000003f	EDX=0x00000000
    actual: EAX=0x1c004122	EBX=0x01c0003f	ECX=0x0000003f	EDX=0x00000000

    Leaf 0x00000004, subleaf 2:
    cached: EAX=0x1c004143	EBX=0x00c0003f	ECX=0x000003ff	EDX=0x00000000
    actual: EAX=0x1c004143	EBX=0x00c0003f	ECX=0x000003ff	EDX=0x00000000

    Leaf 0x00000004, subleaf 3:
    cached: EAX=0x1c03c163	EBX=0x02c0003f	ECX=0x00001fff	EDX=0x00000006
    actual: EAX=0x1c03c163	EBX=0x02c0003f	ECX=0x00001fff	EDX=0x00000006

    Leaf 0x80000000, subleaf 0:
    cached: EAX=0x80000008	EBX=0x00000000	ECX=0x00000000	EDX=0x00000000
    actual: EAX=0x80000008	EBX=0x00000000	ECX=0x00000000	EDX=0x00000000

    Leaf 0x80000005, subleaf 0:
    cached: EAX=0x00000000	EBX=0x00000000	ECX=0x00000000	EDX=0x00000000
    actual: EAX=0x00000000	EBX=0x00000000	ECX=0x00000000	EDX=0x00000000

    Leaf 0x80000006, subleaf 0:
    cached: EAX=0x00000000	EBX=0x00000000	ECX=0x01006040	EDX=0x00000000
    actual: EAX=0x00000000	EBX=0x00000000	ECX=0x01006040	EDX=0x00000000

The first patch in the series is an independent bugfix.

Thanks!

[*] https://gitlab.com/x86-cpuid.org/x86-cpuid-db
    https://x86-cpuid.org

8<-----

Ahmed S. Darwish (26):
  tools/x86/kcpuid: Update bitfields to x86-cpuid-db v2.4
  x86/cpu: Sanitize CPUID(0x80000000) output
  x86/cpuid: Introduce <asm/cpuid/leaves.h>
  x86/cpuid: Introduce centralized CPUID data
  x86/cpuid: Introduce CPUID scanner
  x86/cpuid: Scan CPUID(0x80000000)
  x86/cpuid: Introduce debugfs 'x86/scanned_cpuid/[0-ncpus]'
  x86/cpuid: Introduce external CPUID table accessors
  x86/cpu: Use scanned CPUID(0x0)
  x86/cpu: Use scanned CPUID(0x80000001)
  x86/lib: Add CPUID(0x1) CPU family and model calculation
  x86/cpu: Use scanned CPUID(0x1)
  x86/cpuid: Scan CPUID(0x2)
  x86/cpuid: Introduce scanned CPUID(0x2) API
  x86/cpu: Use scanned CPUID(0x2)
  x86/cacheinfo: Use scanned CPUID(0x2)
  x86/cpuid: Remove direct CPUID(0x2) query API
  x86/cpuid: Scan deterministic cache params CPUID leaves
  x86/cacheinfo: Use scanned CPUID(0x4)
  x86/cacheinfo: Use scanned CPUID(0x8000001d)
  x86/cpuid: Scan CPUID(0x80000005) and CPUID(0x80000006)
  x86/cacheinfo: Use auto-generated data types
  x86/cacheinfo: Use scanned CPUID(0x80000005) and CPUID(0x80000006)
  x86/cpuid: scanner: Add CPUID table rescan support
  x86/cpu: Rescan CPUID table after PSN disable
  x86/cpu: Rescan CPUID table after unlocking the full CPUID range

 MAINTAINERS                               |    1 +
 arch/x86/include/asm/cpu.h                |    6 +
 arch/x86/include/asm/cpuid.h              |    1 +
 arch/x86/include/asm/cpuid/internal_api.h |   62 +
 arch/x86/include/asm/cpuid/leaf_0x2_api.h |   57 +-
 arch/x86/include/asm/cpuid/leaves.h       | 2055 +++++++++++++++++++++
 arch/x86/include/asm/cpuid/table_api.h    |  120 ++
 arch/x86/include/asm/cpuid/types.h        |   74 +
 arch/x86/include/asm/processor.h          |    1 +
 arch/x86/kernel/cpu/Makefile              |    2 +
 arch/x86/kernel/cpu/cacheinfo.c           |  280 +--
 arch/x86/kernel/cpu/common.c              |   65 +-
 arch/x86/kernel/cpu/cpuid_debugfs.c       |   98 +
 arch/x86/kernel/cpu/cpuid_scanner.c       |  209 +++
 arch/x86/kernel/cpu/cpuid_scanner.h       |  117 ++
 arch/x86/kernel/cpu/intel.c               |   17 +-
 arch/x86/lib/cpu.c                        |   41 +-
 tools/arch/x86/kcpuid/cpuid.csv           |    4 +-
 18 files changed, 2926 insertions(+), 284 deletions(-)
 create mode 100644 arch/x86/include/asm/cpuid/internal_api.h
 create mode 100644 arch/x86/include/asm/cpuid/leaves.h
 create mode 100644 arch/x86/include/asm/cpuid/table_api.h
 create mode 100644 arch/x86/kernel/cpu/cpuid_debugfs.c
 create mode 100644 arch/x86/kernel/cpu/cpuid_scanner.c
 create mode 100644 arch/x86/kernel/cpu/cpuid_scanner.h

base-commit: 06e09002bc1d46505d6b3bd947ebaf3cec7acab8
-- 
2.49.0


^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2025-05-15 22:13 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-06  5:04 [PATCH v1 00/26] x86: Introduce centralized CPUID model Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 01/26] tools/x86/kcpuid: Update bitfields to x86-cpuid-db v2.4 Ahmed S. Darwish
2025-05-06  8:06   ` [tip: x86/cpu] " tip-bot2 for Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 02/26] x86/cpu: Sanitize CPUID(0x80000000) output Ahmed S. Darwish
2025-05-06  8:15   ` [tip: x86/cpu] " tip-bot2 for Ahmed S. Darwish
2025-05-07  8:50   ` [PATCH v1 02/26] " Andrew Cooper
2025-05-08 20:40     ` H. Peter Anvin
2025-05-08 20:58       ` Andrew Cooper
2025-05-08 22:37         ` H. Peter Anvin
2025-05-09  9:23     ` Ahmed S. Darwish (dev)
2025-05-06  5:04 ` [PATCH v1 03/26] x86/cpuid: Introduce <asm/cpuid/leaves.h> Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 04/26] x86/cpuid: Introduce centralized CPUID data Ahmed S. Darwish
2025-05-14  4:18   ` Sohil Mehta
2025-05-15 21:23     ` Ahmed S. Darwish
2025-05-15 22:12       ` Sohil Mehta
2025-05-06  5:04 ` [PATCH v1 05/26] x86/cpuid: Introduce CPUID scanner Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 06/26] x86/cpuid: Scan CPUID(0x80000000) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 07/26] x86/cpuid: Introduce debugfs 'x86/scanned_cpuid/[0-ncpus]' Ahmed S. Darwish
2025-05-14  2:56   ` Sohil Mehta
2025-05-15 21:04     ` Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 08/26] x86/cpuid: Introduce external CPUID table accessors Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 09/26] x86/cpu: Use scanned CPUID(0x0) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 10/26] x86/cpu: Use scanned CPUID(0x80000001) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 11/26] x86/lib: Add CPUID(0x1) CPU family and model calculation Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 12/26] x86/cpu: Use scanned CPUID(0x1) Ahmed S. Darwish
2025-05-06  8:25   ` Ingo Molnar
2025-05-07  7:36     ` Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 13/26] x86/cpuid: Scan CPUID(0x2) Ahmed S. Darwish
2025-05-06  8:16   ` Ingo Molnar
2025-05-06  8:47     ` Ahmed S. Darwish
2025-05-06 10:39       ` Ingo Molnar
2025-05-06  5:04 ` [PATCH v1 14/26] x86/cpuid: Introduce scanned CPUID(0x2) API Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 15/26] x86/cpu: Use scanned CPUID(0x2) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 16/26] x86/cacheinfo: " Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 17/26] x86/cpuid: Remove direct CPUID(0x2) query API Ahmed S. Darwish
2025-05-06  8:59   ` Ingo Molnar
2025-05-07  9:15     ` Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 18/26] x86/cpuid: Scan deterministic cache params CPUID leaves Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 19/26] x86/cacheinfo: Use scanned CPUID(0x4) Ahmed S. Darwish
2025-05-06  8:10   ` Ingo Molnar
2025-05-06  8:50     ` Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 20/26] x86/cacheinfo: Use scanned CPUID(0x8000001d) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 21/26] x86/cpuid: Scan CPUID(0x80000005) and CPUID(0x80000006) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 22/26] x86/cacheinfo: Use auto-generated data types Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 23/26] x86/cacheinfo: Use scanned CPUID(0x80000005) and CPUID(0x80000006) Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 24/26] x86/cpuid: scanner: Add CPUID table rescan support Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 25/26] x86/cpu: Rescan CPUID table after PSN disable Ahmed S. Darwish
2025-05-06  5:04 ` [PATCH v1 26/26] x86/cpu: Rescan CPUID table after unlocking the full CPUID range Ahmed S. Darwish
2025-05-06  8:23 ` [PATCH v1 00/26] x86: Introduce centralized CPUID model Ingo Molnar
2025-05-06  8:48   ` Ahmed S. Darwish
2025-05-06  9:12 ` Ingo Molnar
2025-05-07  8:35   ` Ahmed S. Darwish
2025-05-07  8:45     ` Ahmed S. Darwish
2025-05-07  9:32   ` Ahmed S. Darwish
2025-05-09  9:28     ` Ahmed S. Darwish (dev)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).