1 /* SPDX-License-Identifier: GPL-2.0 */
3 * CPUID-related helpers/definitions
6 #ifndef _ASM_X86_CPUID_H
7 #define _ASM_X86_CPUID_H
9 #include <asm/string.h>
12 u32 eax, ebx, ecx, edx;
23 extern int have_cpuid_p(void);
25 static inline int have_cpuid_p(void)
30 static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
31 unsigned int *ecx, unsigned int *edx)
33 /* ecx is often an input as well as an output. */
39 : "0" (*eax), "2" (*ecx)
43 #define native_cpuid_reg(reg) \
44 static inline unsigned int native_cpuid_##reg(unsigned int op) \
46 unsigned int eax = op, ebx, ecx = 0, edx; \
48 native_cpuid(&eax, &ebx, &ecx, &edx); \
54 * Native CPUID functions returning a single datum.
61 #ifdef CONFIG_PARAVIRT_XXL
62 #include <asm/paravirt.h>
64 #define __cpuid native_cpuid
68 * Generic CPUID function
69 * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
70 * resulting in stale register contents being returned.
72 static inline void cpuid(unsigned int op,
73 unsigned int *eax, unsigned int *ebx,
74 unsigned int *ecx, unsigned int *edx)
78 __cpuid(eax, ebx, ecx, edx);
81 /* Some CPUID calls want 'count' to be placed in ecx */
82 static inline void cpuid_count(unsigned int op, int count,
83 unsigned int *eax, unsigned int *ebx,
84 unsigned int *ecx, unsigned int *edx)
88 __cpuid(eax, ebx, ecx, edx);
92 * CPUID functions returning a single datum
94 static inline unsigned int cpuid_eax(unsigned int op)
96 unsigned int eax, ebx, ecx, edx;
98 cpuid(op, &eax, &ebx, &ecx, &edx);
103 static inline unsigned int cpuid_ebx(unsigned int op)
105 unsigned int eax, ebx, ecx, edx;
107 cpuid(op, &eax, &ebx, &ecx, &edx);
112 static inline unsigned int cpuid_ecx(unsigned int op)
114 unsigned int eax, ebx, ecx, edx;
116 cpuid(op, &eax, &ebx, &ecx, &edx);
121 static inline unsigned int cpuid_edx(unsigned int op)
123 unsigned int eax, ebx, ecx, edx;
125 cpuid(op, &eax, &ebx, &ecx, &edx);
130 static __always_inline bool cpuid_function_is_indexed(u32 function)
153 #define for_each_possible_hypervisor_cpuid_base(function) \
154 for (function = 0x40000000; function < 0x40010000; function += 0x100)
156 static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
158 uint32_t base, eax, signature[3];
160 for_each_possible_hypervisor_cpuid_base(base) {
161 cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
163 if (!memcmp(sig, signature, 12) &&
164 (leaves == 0 || ((eax - base) >= leaves)))
171 #endif /* _ASM_X86_CPUID_H */