lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250506050437.10264-1-darwi@linutronix.de>
Date: Tue,  6 May 2025 07:04:11 +0200
From: "Ahmed S. Darwish" <darwi@...utronix.de>
To: Ingo Molnar <mingo@...hat.com>,
	Borislav Petkov <bp@...en8.de>,
	Dave Hansen <dave.hansen@...ux.intel.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
	Andrew Cooper <andrew.cooper3@...rix.com>,
	"H. Peter Anvin" <hpa@...or.com>,
	John Ogness <john.ogness@...utronix.de>,
	x86@...nel.org,
	x86-cpuid@...ts.linux.dev,
	LKML <linux-kernel@...r.kernel.org>,
	"Ahmed S. Darwish" <darwi@...utronix.de>
Subject: [PATCH v1 00/26] x86: Introduce centralized CPUID model

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


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ