All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.