Skip to content

Commit d800169

Browse files
committed
x86/cpuid: Carve out all CPUID functionality
Carve it out into a special header, where it belongs. No functional changes. Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 6007878 commit d800169

File tree

2 files changed

+140
-134
lines changed

2 files changed

+140
-134
lines changed

arch/x86/include/asm/cpuid.h

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,132 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/*
33
* CPUID-related helpers/definitions
4-
*
5-
* Derived from arch/x86/kvm/cpuid.c
64
*/
75

86
#ifndef _ASM_X86_CPUID_H
97
#define _ASM_X86_CPUID_H
108

9+
#include <asm/string.h>
10+
11+
struct cpuid_regs {
12+
u32 eax, ebx, ecx, edx;
13+
};
14+
15+
enum cpuid_regs_idx {
16+
CPUID_EAX = 0,
17+
CPUID_EBX,
18+
CPUID_ECX,
19+
CPUID_EDX,
20+
};
21+
22+
#ifdef CONFIG_X86_32
23+
extern int have_cpuid_p(void);
24+
#else
25+
static inline int have_cpuid_p(void)
26+
{
27+
return 1;
28+
}
29+
#endif
30+
static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
31+
unsigned int *ecx, unsigned int *edx)
32+
{
33+
/* ecx is often an input as well as an output. */
34+
asm volatile("cpuid"
35+
: "=a" (*eax),
36+
"=b" (*ebx),
37+
"=c" (*ecx),
38+
"=d" (*edx)
39+
: "0" (*eax), "2" (*ecx)
40+
: "memory");
41+
}
42+
43+
#define native_cpuid_reg(reg) \
44+
static inline unsigned int native_cpuid_##reg(unsigned int op) \
45+
{ \
46+
unsigned int eax = op, ebx, ecx = 0, edx; \
47+
\
48+
native_cpuid(&eax, &ebx, &ecx, &edx); \
49+
\
50+
return reg; \
51+
}
52+
53+
/*
54+
* Native CPUID functions returning a single datum.
55+
*/
56+
native_cpuid_reg(eax)
57+
native_cpuid_reg(ebx)
58+
native_cpuid_reg(ecx)
59+
native_cpuid_reg(edx)
60+
61+
#ifdef CONFIG_PARAVIRT_XXL
62+
#include <asm/paravirt.h>
63+
#else
64+
#define __cpuid native_cpuid
65+
#endif
66+
67+
/*
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.
71+
*/
72+
static inline void cpuid(unsigned int op,
73+
unsigned int *eax, unsigned int *ebx,
74+
unsigned int *ecx, unsigned int *edx)
75+
{
76+
*eax = op;
77+
*ecx = 0;
78+
__cpuid(eax, ebx, ecx, edx);
79+
}
80+
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)
85+
{
86+
*eax = op;
87+
*ecx = count;
88+
__cpuid(eax, ebx, ecx, edx);
89+
}
90+
91+
/*
92+
* CPUID functions returning a single datum
93+
*/
94+
static inline unsigned int cpuid_eax(unsigned int op)
95+
{
96+
unsigned int eax, ebx, ecx, edx;
97+
98+
cpuid(op, &eax, &ebx, &ecx, &edx);
99+
100+
return eax;
101+
}
102+
103+
static inline unsigned int cpuid_ebx(unsigned int op)
104+
{
105+
unsigned int eax, ebx, ecx, edx;
106+
107+
cpuid(op, &eax, &ebx, &ecx, &edx);
108+
109+
return ebx;
110+
}
111+
112+
static inline unsigned int cpuid_ecx(unsigned int op)
113+
{
114+
unsigned int eax, ebx, ecx, edx;
115+
116+
cpuid(op, &eax, &ebx, &ecx, &edx);
117+
118+
return ecx;
119+
}
120+
121+
static inline unsigned int cpuid_edx(unsigned int op)
122+
{
123+
unsigned int eax, ebx, ecx, edx;
124+
125+
cpuid(op, &eax, &ebx, &ecx, &edx);
126+
127+
return edx;
128+
}
129+
11130
static __always_inline bool cpuid_function_is_indexed(u32 function)
12131
{
13132
switch (function) {
@@ -31,4 +150,22 @@ static __always_inline bool cpuid_function_is_indexed(u32 function)
31150
return false;
32151
}
33152

153+
#define for_each_possible_hypervisor_cpuid_base(function) \
154+
for (function = 0x40000000; function < 0x40010000; function += 0x100)
155+
156+
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
157+
{
158+
uint32_t base, eax, signature[3];
159+
160+
for_each_possible_hypervisor_cpuid_base(base) {
161+
cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
162+
163+
if (!memcmp(sig, signature, 12) &&
164+
(leaves == 0 || ((eax - base) >= leaves)))
165+
return base;
166+
}
167+
168+
return 0;
169+
}
170+
34171
#endif /* _ASM_X86_CPUID_H */

arch/x86/include/asm/processor.h

Lines changed: 1 addition & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct vm86;
1616
#include <uapi/asm/sigcontext.h>
1717
#include <asm/current.h>
1818
#include <asm/cpufeatures.h>
19+
#include <asm/cpuid.h>
1920
#include <asm/page.h>
2021
#include <asm/pgtable_types.h>
2122
#include <asm/percpu.h>
@@ -146,17 +147,6 @@ struct cpuinfo_x86 {
146147
unsigned initialized : 1;
147148
} __randomize_layout;
148149

149-
struct cpuid_regs {
150-
u32 eax, ebx, ecx, edx;
151-
};
152-
153-
enum cpuid_regs_idx {
154-
CPUID_EAX = 0,
155-
CPUID_EBX,
156-
CPUID_ECX,
157-
CPUID_EDX,
158-
};
159-
160150
#define X86_VENDOR_INTEL 0
161151
#define X86_VENDOR_CYRIX 1
162152
#define X86_VENDOR_AMD 2
@@ -205,45 +195,6 @@ extern void identify_secondary_cpu(struct cpuinfo_x86 *);
205195
extern void print_cpu_info(struct cpuinfo_x86 *);
206196
void print_cpu_msr(struct cpuinfo_x86 *);
207197

208-
#ifdef CONFIG_X86_32
209-
extern int have_cpuid_p(void);
210-
#else
211-
static inline int have_cpuid_p(void)
212-
{
213-
return 1;
214-
}
215-
#endif
216-
static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
217-
unsigned int *ecx, unsigned int *edx)
218-
{
219-
/* ecx is often an input as well as an output. */
220-
asm volatile("cpuid"
221-
: "=a" (*eax),
222-
"=b" (*ebx),
223-
"=c" (*ecx),
224-
"=d" (*edx)
225-
: "0" (*eax), "2" (*ecx)
226-
: "memory");
227-
}
228-
229-
#define native_cpuid_reg(reg) \
230-
static inline unsigned int native_cpuid_##reg(unsigned int op) \
231-
{ \
232-
unsigned int eax = op, ebx, ecx = 0, edx; \
233-
\
234-
native_cpuid(&eax, &ebx, &ecx, &edx); \
235-
\
236-
return reg; \
237-
}
238-
239-
/*
240-
* Native CPUID functions returning a single datum.
241-
*/
242-
native_cpuid_reg(eax)
243-
native_cpuid_reg(ebx)
244-
native_cpuid_reg(ecx)
245-
native_cpuid_reg(edx)
246-
247198
/*
248199
* Friendlier CR3 helpers.
249200
*/
@@ -578,7 +529,6 @@ static __always_inline bool on_thread_stack(void)
578529
#ifdef CONFIG_PARAVIRT_XXL
579530
#include <asm/paravirt.h>
580531
#else
581-
#define __cpuid native_cpuid
582532

583533
static inline void load_sp0(unsigned long sp0)
584534
{
@@ -589,69 +539,6 @@ static inline void load_sp0(unsigned long sp0)
589539

590540
unsigned long __get_wchan(struct task_struct *p);
591541

592-
/*
593-
* Generic CPUID function
594-
* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
595-
* resulting in stale register contents being returned.
596-
*/
597-
static inline void cpuid(unsigned int op,
598-
unsigned int *eax, unsigned int *ebx,
599-
unsigned int *ecx, unsigned int *edx)
600-
{
601-
*eax = op;
602-
*ecx = 0;
603-
__cpuid(eax, ebx, ecx, edx);
604-
}
605-
606-
/* Some CPUID calls want 'count' to be placed in ecx */
607-
static inline void cpuid_count(unsigned int op, int count,
608-
unsigned int *eax, unsigned int *ebx,
609-
unsigned int *ecx, unsigned int *edx)
610-
{
611-
*eax = op;
612-
*ecx = count;
613-
__cpuid(eax, ebx, ecx, edx);
614-
}
615-
616-
/*
617-
* CPUID functions returning a single datum
618-
*/
619-
static inline unsigned int cpuid_eax(unsigned int op)
620-
{
621-
unsigned int eax, ebx, ecx, edx;
622-
623-
cpuid(op, &eax, &ebx, &ecx, &edx);
624-
625-
return eax;
626-
}
627-
628-
static inline unsigned int cpuid_ebx(unsigned int op)
629-
{
630-
unsigned int eax, ebx, ecx, edx;
631-
632-
cpuid(op, &eax, &ebx, &ecx, &edx);
633-
634-
return ebx;
635-
}
636-
637-
static inline unsigned int cpuid_ecx(unsigned int op)
638-
{
639-
unsigned int eax, ebx, ecx, edx;
640-
641-
cpuid(op, &eax, &ebx, &ecx, &edx);
642-
643-
return ecx;
644-
}
645-
646-
static inline unsigned int cpuid_edx(unsigned int op)
647-
{
648-
unsigned int eax, ebx, ecx, edx;
649-
650-
cpuid(op, &eax, &ebx, &ecx, &edx);
651-
652-
return edx;
653-
}
654-
655542
extern void select_idle_routine(const struct cpuinfo_x86 *c);
656543
extern void amd_e400_c1e_apic_setup(void);
657544

@@ -805,24 +692,6 @@ static inline u32 amd_get_nodes_per_socket(void) { return 0; }
805692
static inline u32 amd_get_highest_perf(void) { return 0; }
806693
#endif
807694

808-
#define for_each_possible_hypervisor_cpuid_base(function) \
809-
for (function = 0x40000000; function < 0x40010000; function += 0x100)
810-
811-
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
812-
{
813-
uint32_t base, eax, signature[3];
814-
815-
for_each_possible_hypervisor_cpuid_base(base) {
816-
cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
817-
818-
if (!memcmp(sig, signature, 12) &&
819-
(leaves == 0 || ((eax - base) >= leaves)))
820-
return base;
821-
}
822-
823-
return 0;
824-
}
825-
826695
extern unsigned long arch_align_stack(unsigned long sp);
827696
void free_init_pages(const char *what, unsigned long begin, unsigned long end);
828697
extern void free_kernel_image_pages(const char *what, void *begin, void *end);

0 commit comments

Comments
 (0)