1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef ARCH_X86_KVM_CPUID_H
3 #define ARCH_X86_KVM_CPUID_H
7 #include <asm/processor.h>
9 int kvm_update_cpuid(struct kvm_vcpu
*vcpu
);
10 bool kvm_mpx_supported(void);
11 struct kvm_cpuid_entry2
*kvm_find_cpuid_entry(struct kvm_vcpu
*vcpu
,
12 u32 function
, u32 index
);
13 int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2
*cpuid
,
14 struct kvm_cpuid_entry2 __user
*entries
,
16 int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu
*vcpu
,
17 struct kvm_cpuid
*cpuid
,
18 struct kvm_cpuid_entry __user
*entries
);
19 int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu
*vcpu
,
20 struct kvm_cpuid2
*cpuid
,
21 struct kvm_cpuid_entry2 __user
*entries
);
22 int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu
*vcpu
,
23 struct kvm_cpuid2
*cpuid
,
24 struct kvm_cpuid_entry2 __user
*entries
);
25 bool kvm_cpuid(struct kvm_vcpu
*vcpu
, u32
*eax
, u32
*ebx
,
26 u32
*ecx
, u32
*edx
, bool check_limit
);
28 int cpuid_query_maxphyaddr(struct kvm_vcpu
*vcpu
);
30 static inline int cpuid_maxphyaddr(struct kvm_vcpu
*vcpu
)
32 return vcpu
->arch
.maxphyaddr
;
41 static const struct cpuid_reg reverse_cpuid
[] = {
42 [CPUID_1_EDX
] = { 1, 0, CPUID_EDX
},
43 [CPUID_8000_0001_EDX
] = {0x80000001, 0, CPUID_EDX
},
44 [CPUID_8086_0001_EDX
] = {0x80860001, 0, CPUID_EDX
},
45 [CPUID_1_ECX
] = { 1, 0, CPUID_ECX
},
46 [CPUID_C000_0001_EDX
] = {0xc0000001, 0, CPUID_EDX
},
47 [CPUID_8000_0001_ECX
] = {0x80000001, 0, CPUID_ECX
},
48 [CPUID_7_0_EBX
] = { 7, 0, CPUID_EBX
},
49 [CPUID_D_1_EAX
] = { 0xd, 1, CPUID_EAX
},
50 [CPUID_8000_0008_EBX
] = {0x80000008, 0, CPUID_EBX
},
51 [CPUID_6_EAX
] = { 6, 0, CPUID_EAX
},
52 [CPUID_8000_000A_EDX
] = {0x8000000a, 0, CPUID_EDX
},
53 [CPUID_7_ECX
] = { 7, 0, CPUID_ECX
},
54 [CPUID_8000_0007_EBX
] = {0x80000007, 0, CPUID_EBX
},
55 [CPUID_7_EDX
] = { 7, 0, CPUID_EDX
},
56 [CPUID_7_1_EAX
] = { 7, 1, CPUID_EAX
},
60 * Reverse CPUID and its derivatives can only be used for hardware-defined
61 * feature words, i.e. words whose bits directly correspond to a CPUID leaf.
62 * Retrieving a feature bit or masking guest CPUID from a Linux-defined word
63 * is nonsensical as the bit number/mask is an arbitrary software-defined value
64 * and can't be used by KVM to query/control guest capabilities. And obviously
65 * the leaf being queried must have an entry in the lookup table.
67 static __always_inline
void reverse_cpuid_check(unsigned x86_leaf
)
69 BUILD_BUG_ON(x86_leaf
== CPUID_LNX_1
);
70 BUILD_BUG_ON(x86_leaf
== CPUID_LNX_2
);
71 BUILD_BUG_ON(x86_leaf
== CPUID_LNX_3
);
72 BUILD_BUG_ON(x86_leaf
== CPUID_LNX_4
);
73 BUILD_BUG_ON(x86_leaf
>= ARRAY_SIZE(reverse_cpuid
));
74 BUILD_BUG_ON(reverse_cpuid
[x86_leaf
].function
== 0);
78 * Retrieve the bit mask from an X86_FEATURE_* definition. Features contain
79 * the hardware defined bit number (stored in bits 4:0) and a software defined
80 * "word" (stored in bits 31:5). The word is used to index into arrays of
81 * bit masks that hold the per-cpu feature capabilities, e.g. this_cpu_has().
83 static __always_inline u32
__feature_bit(int x86_feature
)
85 reverse_cpuid_check(x86_feature
/ 32);
86 return 1 << (x86_feature
& 31);
89 #define feature_bit(name) __feature_bit(X86_FEATURE_##name)
91 static __always_inline
struct cpuid_reg
x86_feature_cpuid(unsigned x86_feature
)
93 unsigned x86_leaf
= x86_feature
/ 32;
95 reverse_cpuid_check(x86_leaf
);
96 return reverse_cpuid
[x86_leaf
];
99 static __always_inline
int *guest_cpuid_get_register(struct kvm_vcpu
*vcpu
, unsigned x86_feature
)
101 struct kvm_cpuid_entry2
*entry
;
102 const struct cpuid_reg cpuid
= x86_feature_cpuid(x86_feature
);
104 entry
= kvm_find_cpuid_entry(vcpu
, cpuid
.function
, cpuid
.index
);
123 static __always_inline
bool guest_cpuid_has(struct kvm_vcpu
*vcpu
, unsigned x86_feature
)
127 reg
= guest_cpuid_get_register(vcpu
, x86_feature
);
131 return *reg
& __feature_bit(x86_feature
);
134 static __always_inline
void guest_cpuid_clear(struct kvm_vcpu
*vcpu
, unsigned x86_feature
)
138 reg
= guest_cpuid_get_register(vcpu
, x86_feature
);
140 *reg
&= ~__feature_bit(x86_feature
);
143 static inline bool guest_cpuid_is_amd(struct kvm_vcpu
*vcpu
)
145 struct kvm_cpuid_entry2
*best
;
147 best
= kvm_find_cpuid_entry(vcpu
, 0, 0);
148 return best
&& best
->ebx
== X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx
;
151 static inline int guest_cpuid_family(struct kvm_vcpu
*vcpu
)
153 struct kvm_cpuid_entry2
*best
;
155 best
= kvm_find_cpuid_entry(vcpu
, 0x1, 0);
159 return x86_family(best
->eax
);
162 static inline int guest_cpuid_model(struct kvm_vcpu
*vcpu
)
164 struct kvm_cpuid_entry2
*best
;
166 best
= kvm_find_cpuid_entry(vcpu
, 0x1, 0);
170 return x86_model(best
->eax
);
173 static inline int guest_cpuid_stepping(struct kvm_vcpu
*vcpu
)
175 struct kvm_cpuid_entry2
*best
;
177 best
= kvm_find_cpuid_entry(vcpu
, 0x1, 0);
181 return x86_stepping(best
->eax
);
184 static inline bool supports_cpuid_fault(struct kvm_vcpu
*vcpu
)
186 return vcpu
->arch
.msr_platform_info
& MSR_PLATFORM_INFO_CPUID_FAULT
;
189 static inline bool cpuid_fault_enabled(struct kvm_vcpu
*vcpu
)
191 return vcpu
->arch
.msr_misc_features_enables
&
192 MSR_MISC_FEATURES_ENABLES_CPUID_FAULT
;