Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/cpuid: Move CPUID(0x2) APIs into <cpuid/api.h>

Move all of the CPUID(0x2) APIs at <cpuid/leaf_0x2_api.h> into
<cpuid/api.h>, in order centralize all CPUID APIs into the latter.

While at it, separate the different CPUID leaf parsing APIs using
header comments like "CPUID(0xN) parsing: ".

Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: John Ogness <john.ogness@linutronix.de>
Cc: x86-cpuid@lists.linux.dev
Link: https://lore.kernel.org/r/20250508150240.172915-2-darwi@linutronix.de

authored by

Ahmed S. Darwish and committed by
Ingo Molnar
cdc8be31 baad9190

+75 -77
-1
arch/x86/include/asm/cpuid.h
··· 4 4 #define _ASM_X86_CPUID_H 5 5 6 6 #include <asm/cpuid/api.h> 7 - #include <asm/cpuid/leaf_0x2_api.h> 8 7 9 8 #endif /* _ASM_X86_CPUID_H */
+74 -1
arch/x86/include/asm/cpuid/api.h
··· 160 160 __cpuid_read_reg(leaf, 0, regidx, (u32 *)(reg)); \ 161 161 } 162 162 163 + /* 164 + * Hypervisor-related APIs: 165 + */ 166 + 163 167 static __always_inline bool cpuid_function_is_indexed(u32 function) 164 168 { 165 169 switch (function) { ··· 212 208 } 213 209 214 210 /* 215 - * CPUID(0x80000006) parsing helpers 211 + * CPUID(0x2) parsing: 212 + */ 213 + 214 + /** 215 + * cpuid_get_leaf_0x2_regs() - Return sanitized leaf 0x2 register output 216 + * @regs: Output parameter 217 + * 218 + * Query CPUID leaf 0x2 and store its output in @regs. Force set any 219 + * invalid 1-byte descriptor returned by the hardware to zero (the NULL 220 + * cache/TLB descriptor) before returning it to the caller. 221 + * 222 + * Use for_each_leaf_0x2_entry() to iterate over the register output in 223 + * parsed form. 224 + */ 225 + static inline void cpuid_get_leaf_0x2_regs(union leaf_0x2_regs *regs) 226 + { 227 + cpuid_leaf(0x2, regs); 228 + 229 + /* 230 + * All Intel CPUs must report an iteration count of 1. In case 231 + * of bogus hardware, treat all returned descriptors as NULL. 232 + */ 233 + if (regs->desc[0] != 0x01) { 234 + for (int i = 0; i < 4; i++) 235 + regs->regv[i] = 0; 236 + return; 237 + } 238 + 239 + /* 240 + * The most significant bit (MSB) of each register must be clear. 241 + * If a register is invalid, replace its descriptors with NULL. 242 + */ 243 + for (int i = 0; i < 4; i++) { 244 + if (regs->reg[i].invalid) 245 + regs->regv[i] = 0; 246 + } 247 + } 248 + 249 + /** 250 + * for_each_leaf_0x2_entry() - Iterator for parsed leaf 0x2 descriptors 251 + * @regs: Leaf 0x2 register output, returned by cpuid_get_leaf_0x2_regs() 252 + * @__ptr: u8 pointer, for macro internal use only 253 + * @entry: Pointer to parsed descriptor information at each iteration 254 + * 255 + * Loop over the 1-byte descriptors in the passed leaf 0x2 output registers 256 + * @regs. Provide the parsed information for each descriptor through @entry. 257 + * 258 + * To handle cache-specific descriptors, switch on @entry->c_type. For TLB 259 + * descriptors, switch on @entry->t_type. 260 + * 261 + * Example usage for cache descriptors:: 262 + * 263 + * const struct leaf_0x2_table *entry; 264 + * union leaf_0x2_regs regs; 265 + * u8 *ptr; 266 + * 267 + * cpuid_get_leaf_0x2_regs(&regs); 268 + * for_each_leaf_0x2_entry(regs, ptr, entry) { 269 + * switch (entry->c_type) { 270 + * ... 271 + * } 272 + * } 273 + */ 274 + #define for_each_leaf_0x2_entry(regs, __ptr, entry) \ 275 + for (__ptr = &(regs).desc[1]; \ 276 + __ptr < &(regs).desc[16] && (entry = &cpuid_0x2_table[*__ptr]); \ 277 + __ptr++) 278 + 279 + /* 280 + * CPUID(0x80000006) parsing: 216 281 */ 217 282 218 283 static inline bool cpuid_amd_hygon_has_l3_cache(void)
-73
arch/x86/include/asm/cpuid/leaf_0x2_api.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _ASM_X86_CPUID_LEAF_0x2_API_H 3 - #define _ASM_X86_CPUID_LEAF_0x2_API_H 4 - 5 - #include <asm/cpuid/api.h> 6 - #include <asm/cpuid/types.h> 7 - 8 - /** 9 - * cpuid_get_leaf_0x2_regs() - Return sanitized leaf 0x2 register output 10 - * @regs: Output parameter 11 - * 12 - * Query CPUID leaf 0x2 and store its output in @regs. Force set any 13 - * invalid 1-byte descriptor returned by the hardware to zero (the NULL 14 - * cache/TLB descriptor) before returning it to the caller. 15 - * 16 - * Use for_each_leaf_0x2_entry() to iterate over the register output in 17 - * parsed form. 18 - */ 19 - static inline void cpuid_get_leaf_0x2_regs(union leaf_0x2_regs *regs) 20 - { 21 - cpuid_leaf(0x2, regs); 22 - 23 - /* 24 - * All Intel CPUs must report an iteration count of 1. In case 25 - * of bogus hardware, treat all returned descriptors as NULL. 26 - */ 27 - if (regs->desc[0] != 0x01) { 28 - for (int i = 0; i < 4; i++) 29 - regs->regv[i] = 0; 30 - return; 31 - } 32 - 33 - /* 34 - * The most significant bit (MSB) of each register must be clear. 35 - * If a register is invalid, replace its descriptors with NULL. 36 - */ 37 - for (int i = 0; i < 4; i++) { 38 - if (regs->reg[i].invalid) 39 - regs->regv[i] = 0; 40 - } 41 - } 42 - 43 - /** 44 - * for_each_leaf_0x2_entry() - Iterator for parsed leaf 0x2 descriptors 45 - * @regs: Leaf 0x2 register output, returned by cpuid_get_leaf_0x2_regs() 46 - * @__ptr: u8 pointer, for macro internal use only 47 - * @entry: Pointer to parsed descriptor information at each iteration 48 - * 49 - * Loop over the 1-byte descriptors in the passed leaf 0x2 output registers 50 - * @regs. Provide the parsed information for each descriptor through @entry. 51 - * 52 - * To handle cache-specific descriptors, switch on @entry->c_type. For TLB 53 - * descriptors, switch on @entry->t_type. 54 - * 55 - * Example usage for cache descriptors:: 56 - * 57 - * const struct leaf_0x2_table *entry; 58 - * union leaf_0x2_regs regs; 59 - * u8 *ptr; 60 - * 61 - * cpuid_get_leaf_0x2_regs(&regs); 62 - * for_each_leaf_0x2_entry(regs, ptr, entry) { 63 - * switch (entry->c_type) { 64 - * ... 65 - * } 66 - * } 67 - */ 68 - #define for_each_leaf_0x2_entry(regs, __ptr, entry) \ 69 - for (__ptr = &(regs).desc[1]; \ 70 - __ptr < &(regs).desc[16] && (entry = &cpuid_0x2_table[*__ptr]); \ 71 - __ptr++) 72 - 73 - #endif /* _ASM_X86_CPUID_LEAF_0x2_API_H */
+1 -2
arch/x86/include/asm/cpuid/types.h
··· 31 31 #define CPUID_LEAF_TILE 0x1d 32 32 33 33 /* 34 - * Types for CPUID(0x2) parsing 35 - * Check <asm/cpuid/leaf_0x2_api.h> 34 + * Types for CPUID(0x2) parsing: 36 35 */ 37 36 38 37 struct leaf_0x2_reg {