Re: [PATCH v4 28/34] x86/cacheinfo: Use parsed CPUID(0x80000005) and CPUID(0x80000006)

"Ahmed S. Darwish" <[email protected]> Mon, 18 Aug 2025 19:00:03 +0200
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <aKNcE7D_s9D7spvR@lx-t490>
Hi!

On Mon, 18 Aug 2025, David Woodhouse wrote:
>
> How about automatically building the cast into the macro invocation...
>
> #define cpuid_leaf(c, l) ((struct cpuid_leaf_ ## l *)__cpuid_leaf(c, l)
> #define cpuid_lead_index(c, l, i) ((struct cpuid_leaf_ ## l ## _ ## i) __cpuid_leaf_index(c, l, i)
>

There are zero casts needed by this model.  From patch 07/34 ("x86/cpuid:
Introduce a centralized CPUID data model"), the access CPUID parser APIs
just dissolve into:

    const struct leaf_0x7_0 *l7_0;
    const struct leaf_0x7_1 *l7_1;

    l7_0 = cpuid_subleaf(c, 0x7, 0);
                         |   |   └────────┐
                         |   └─────────┐  |
                         *             *  *
                        &c.cpuid.leaf_0x7_0[0]

    l7_1 = cpuid_subleaf(c, 0x7, 1);
                         |   |   └────────┐
                         |   └─────────┐  |
                         *             *  *
                        &c.cpuid.leaf_0x7_1[0]

where, for example, the data type of 'c.cpuid.leaf_0x7_0[0]' is native
'struct leaf_0x7_0', and so on.

The per-CPU CPUID table(s) are built in a /fully-typed/ form:

    struct leaf_0x0_0		leaf_0x0_0[1];
    struct leaf_0x1_0		leaf_0x1_0[1];
    struct leaf_0x2_0		leaf_0x2_0[1];
    struct leaf_0x4_0		leaf_0x4_0[8];
    struct leaf_0x16_0		leaf_0x16_0[1];
    struct leaf_0x80000000_0	leaf_0x80000000_0[1];
    struct leaf_0x80000005_0	leaf_0x80000005_0[1];
    struct leaf_0x80000006_0	leaf_0x80000006_0[1];
    struct leaf_0x8000001d_0	leaf_0x8000001d_0[8];

Then, the exported CPUID parser APIs do some CPP tokenization magic to
access such fully-typed data -- no casting needed.

The only exception is raw EAX->EDX register access:

    /**
     * cpuid_leaf_regs() - Access parsed CPUID data in raw format
     * @_cpuinfo:	CPU capability structure reference ('struct cpuinfo_x86')
     * @_leaf:		CPUID leaf, in compile-time 0xN format
     *
     * Similar to cpuid_leaf(), but returns a raw 'struct cpuid_regs' pointer to
     * the parsed CPUID data instead of a "typed" <cpuid/leaf_types.h> pointer.
     */
    #define cpuid_leaf_regs(_cpuinfo, _leaf)				\
	((struct cpuid_regs *)(cpuid_leaf(_cpuinfo, _leaf)))

But the usage of this raw-access API is very limited.  This is by design,
as one of the purpose of this work was to ensure type safety and avoid
call-site bit fiddling.

Thanks!

--
Ahmed S. Darwish
Linutronix GmbH