Provide a few helper functions to read CPUID leafs or individual registers into a data structure without requiring unions. Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> --- arch/x86/include/asm/cpuid.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) --- a/arch/x86/include/asm/cpuid.h +++ b/arch/x86/include/asm/cpuid.h @@ -127,6 +127,38 @@ static inline unsigned int cpuid_edx(uns return edx; } +static inline void __cpuid_read(unsigned int leaf, unsigned int subleaf, u32 *regs) +{ + regs[CPUID_EAX] = leaf; + regs[CPUID_ECX] = subleaf; + __cpuid(regs, regs + 1, regs + 2, regs + 3); +} + +#define cpuid_subleaf(leaf, subleaf, regs) \ + BUILD_BUG_ON(sizeof(*(regs)) != 16); \ + __cpuid_read(leaf, subleaf, (u32 *)(regs)) + +#define cpuid_leaf(leaf, regs) \ + BUILD_BUG_ON(sizeof(*(regs)) != 16); \ + __cpuid_read(leaf, 0, (u32 *)(regs)) + +static inline void __cpuid_read_reg(unsigned int leaf, unsigned int subleaf, + enum cpuid_regs_idx regidx, u32 *reg) +{ + u32 regs[4]; + + __cpuid_read(leaf, subleaf, regs); + *reg = regs[regidx]; +} + +#define cpuid_subleaf_reg(leaf, subleaf, regidx, reg) \ + BUILD_BUG_ON(sizeof(*(reg)) != 4); \ + __cpuid_read_reg(leaf, subleaf, regidx, (u32 *)(reg)) + +#define cpuid_leaf_reg(leaf, regidx, reg) \ + BUILD_BUG_ON(sizeof(*(reg)) != 4); \ + __cpuid_read_reg(leaf, 0, regidx, (u32 *)(reg)) + static __always_inline bool cpuid_function_is_indexed(u32 function) { switch (function) {