xref: /linux/arch/x86/kvm/cpuid.h (revision c7fdfd2bee1cf1448e5244da1a734e680f634b02)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef ARCH_X86_KVM_CPUID_H
3 #define ARCH_X86_KVM_CPUID_H
4 
5 #include "reverse_cpuid.h"
6 #include <asm/cpu.h>
7 #include <asm/processor.h>
8 #include <uapi/asm/kvm_para.h>
9 
10 #include "smm.h"
11 
12 extern u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
13 extern bool kvm_is_configuring_cpu_caps __read_mostly;
14 
15 void kvm_initialize_cpu_caps(void);
16 
17 static inline void kvm_finalize_cpu_caps(void)
18 {
19 	WARN_ON_ONCE(!kvm_is_configuring_cpu_caps);
20 	kvm_is_configuring_cpu_caps = false;
21 }
22 
23 void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu);
24 struct kvm_cpuid_entry2 *kvm_find_cpuid_entry2(struct kvm_cpuid_entry2 *entries,
25 					       int nent, u32 function, u64 index);
26 /*
27  * Magic value used by KVM when querying userspace-provided CPUID entries and
28  * doesn't care about the CPIUD index because the index of the function in
29  * question is not significant.  Note, this magic value must have at least one
30  * bit set in bits[63:32] and must be consumed as a u64 by kvm_find_cpuid_entry2()
31  * to avoid false positives when processing guest CPUID input.
32  *
33  * KVM_CPUID_INDEX_NOT_SIGNIFICANT should never be used directly outside of
34  * kvm_find_cpuid_entry2() and kvm_find_cpuid_entry().
35  */
36 #define KVM_CPUID_INDEX_NOT_SIGNIFICANT -1ull
37 
38 static inline struct kvm_cpuid_entry2 *kvm_find_cpuid_entry_index(struct kvm_vcpu *vcpu,
39 								  u32 function, u32 index)
40 {
41 	return kvm_find_cpuid_entry2(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent,
42 				     function, index);
43 }
44 
45 static inline struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
46 							    u32 function)
47 {
48 	return kvm_find_cpuid_entry2(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent,
49 				     function, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
50 }
51 
52 int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
53 			    struct kvm_cpuid_entry2 __user *entries,
54 			    unsigned int type);
55 int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
56 			     struct kvm_cpuid *cpuid,
57 			     struct kvm_cpuid_entry __user *entries);
58 int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
59 			      struct kvm_cpuid2 *cpuid,
60 			      struct kvm_cpuid_entry2 __user *entries);
61 int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
62 			      struct kvm_cpuid2 *cpuid,
63 			      struct kvm_cpuid_entry2 __user *entries);
64 bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
65 	       u32 *ecx, u32 *edx, bool exact_only);
66 
67 void __init kvm_init_xstate_sizes(void);
68 u32 xstate_required_size(u64 xstate_bv, bool compacted);
69 
70 int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
71 int cpuid_query_maxguestphyaddr(struct kvm_vcpu *vcpu);
72 u64 kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu *vcpu);
73 
74 static inline int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
75 {
76 	return vcpu->arch.maxphyaddr;
77 }
78 
79 static inline bool kvm_vcpu_is_legal_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
80 {
81 	return !(gpa & vcpu->arch.reserved_gpa_bits);
82 }
83 
84 static inline bool kvm_vcpu_is_legal_aligned_gpa(struct kvm_vcpu *vcpu,
85 						 gpa_t gpa, gpa_t alignment)
86 {
87 	return IS_ALIGNED(gpa, alignment) && kvm_vcpu_is_legal_gpa(vcpu, gpa);
88 }
89 
90 static inline bool page_address_valid(struct kvm_vcpu *vcpu, gpa_t gpa)
91 {
92 	return kvm_vcpu_is_legal_aligned_gpa(vcpu, gpa, PAGE_SIZE);
93 }
94 
95 static __always_inline void cpuid_entry_override(struct kvm_cpuid_entry2 *entry,
96 						 unsigned int leaf)
97 {
98 	u32 *reg = cpuid_entry_get_reg(entry, leaf * 32);
99 
100 	BUILD_BUG_ON(leaf >= ARRAY_SIZE(kvm_cpu_caps));
101 	*reg = kvm_cpu_caps[leaf];
102 }
103 
104 static __always_inline bool guest_cpuid_has(struct kvm_vcpu *vcpu,
105 					    unsigned int x86_feature)
106 {
107 	const struct cpuid_reg cpuid = x86_feature_cpuid(x86_feature);
108 	struct kvm_cpuid_entry2 *entry;
109 	u32 *reg;
110 
111 	/*
112 	 * XSAVES is a special snowflake.  Due to lack of a dedicated intercept
113 	 * on SVM, KVM must assume that XSAVES (and thus XRSTORS) is usable by
114 	 * the guest if the host supports XSAVES and *XSAVE* is exposed to the
115 	 * guest.  Because the guest can execute XSAVES and XRSTORS, i.e. can
116 	 * indirectly consume XSS, KVM must ensure XSS is zeroed when running
117 	 * the guest, i.e. must set XSAVES in vCPU capabilities.  But to reject
118 	 * direct XSS reads and writes (to minimize the virtualization hole and
119 	 * honor userspace's CPUID), KVM needs to check the raw guest CPUID,
120 	 * not KVM's view of guest capabilities.
121 	 *
122 	 * For all other features, guest capabilities are accurate.  Expand
123 	 * this allowlist with extreme vigilance.
124 	 */
125 	BUILD_BUG_ON(x86_feature != X86_FEATURE_XSAVES);
126 
127 	entry = kvm_find_cpuid_entry_index(vcpu, cpuid.function, cpuid.index);
128 	if (!entry)
129 		return false;
130 
131 	reg = __cpuid_entry_get_reg(entry, cpuid.reg);
132 	if (!reg)
133 		return false;
134 
135 	return *reg & __feature_bit(x86_feature);
136 }
137 
138 static inline bool guest_cpuid_is_amd_compatible(struct kvm_vcpu *vcpu)
139 {
140 	return vcpu->arch.is_amd_compatible;
141 }
142 
143 static inline bool guest_cpuid_is_intel_compatible(struct kvm_vcpu *vcpu)
144 {
145 	return !guest_cpuid_is_amd_compatible(vcpu);
146 }
147 
148 static inline int guest_cpuid_family(struct kvm_vcpu *vcpu)
149 {
150 	struct kvm_cpuid_entry2 *best;
151 
152 	best = kvm_find_cpuid_entry(vcpu, 0x1);
153 	if (!best)
154 		return -1;
155 
156 	return x86_family(best->eax);
157 }
158 
159 static inline int guest_cpuid_model(struct kvm_vcpu *vcpu)
160 {
161 	struct kvm_cpuid_entry2 *best;
162 
163 	best = kvm_find_cpuid_entry(vcpu, 0x1);
164 	if (!best)
165 		return -1;
166 
167 	return x86_model(best->eax);
168 }
169 
170 static inline bool cpuid_model_is_consistent(struct kvm_vcpu *vcpu)
171 {
172 	return boot_cpu_data.x86_model == guest_cpuid_model(vcpu);
173 }
174 
175 static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
176 {
177 	struct kvm_cpuid_entry2 *best;
178 
179 	best = kvm_find_cpuid_entry(vcpu, 0x1);
180 	if (!best)
181 		return -1;
182 
183 	return x86_stepping(best->eax);
184 }
185 
186 static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
187 {
188 	return (vcpu->arch.msr_misc_features_enables &
189 		MSR_MISC_FEATURES_ENABLES_CPUID_FAULT) ||
190 		(vcpu->arch.msr_hwcr & MSR_K7_HWCR_CPUID_USER_DIS);
191 }
192 
193 static inline bool kvm_is_cpuid_allowed(struct kvm_vcpu *vcpu)
194 {
195 	return !cpuid_fault_enabled(vcpu) || is_smm(vcpu) ||
196 	       !kvm_x86_call(get_cpl)(vcpu);
197 }
198 
199 static __always_inline void kvm_cpu_cap_clear(unsigned int x86_feature)
200 {
201 	unsigned int x86_leaf = __feature_leaf(x86_feature);
202 
203 	WARN_ON_ONCE(!kvm_is_configuring_cpu_caps);
204 	kvm_cpu_caps[x86_leaf] &= ~__feature_bit(x86_feature);
205 }
206 
207 static __always_inline void kvm_cpu_cap_set(unsigned int x86_feature)
208 {
209 	unsigned int x86_leaf = __feature_leaf(x86_feature);
210 
211 	WARN_ON_ONCE(!kvm_is_configuring_cpu_caps);
212 	kvm_cpu_caps[x86_leaf] |= __feature_bit(x86_feature);
213 }
214 
215 static __always_inline u32 kvm_cpu_cap_get(unsigned int x86_feature)
216 {
217 	unsigned int x86_leaf = __feature_leaf(x86_feature);
218 
219 	return kvm_cpu_caps[x86_leaf] & __feature_bit(x86_feature);
220 }
221 
222 static __always_inline bool kvm_cpu_cap_has(unsigned int x86_feature)
223 {
224 	return !!kvm_cpu_cap_get(x86_feature);
225 }
226 
227 static __always_inline void kvm_cpu_cap_check_and_set(unsigned int x86_feature)
228 {
229 	if (boot_cpu_has(x86_feature))
230 		kvm_cpu_cap_set(x86_feature);
231 }
232 
233 static __always_inline bool guest_pv_has(struct kvm_vcpu *vcpu,
234 					 unsigned int kvm_feature)
235 {
236 	if (!vcpu->arch.pv_cpuid.enforce)
237 		return true;
238 
239 	return vcpu->arch.pv_cpuid.features & (1u << kvm_feature);
240 }
241 
242 static __always_inline void guest_cpu_cap_set(struct kvm_vcpu *vcpu,
243 					      unsigned int x86_feature)
244 {
245 	unsigned int x86_leaf = __feature_leaf(x86_feature);
246 
247 	vcpu->arch.cpu_caps[x86_leaf] |= __feature_bit(x86_feature);
248 }
249 
250 static __always_inline void guest_cpu_cap_clear(struct kvm_vcpu *vcpu,
251 						unsigned int x86_feature)
252 {
253 	unsigned int x86_leaf = __feature_leaf(x86_feature);
254 
255 	vcpu->arch.cpu_caps[x86_leaf] &= ~__feature_bit(x86_feature);
256 }
257 
258 static __always_inline void guest_cpu_cap_change(struct kvm_vcpu *vcpu,
259 						 unsigned int x86_feature,
260 						 bool guest_has_cap)
261 {
262 	if (guest_has_cap)
263 		guest_cpu_cap_set(vcpu, x86_feature);
264 	else
265 		guest_cpu_cap_clear(vcpu, x86_feature);
266 }
267 
268 static __always_inline bool guest_cpu_cap_has(struct kvm_vcpu *vcpu,
269 					      unsigned int x86_feature)
270 {
271 	unsigned int x86_leaf = __feature_leaf(x86_feature);
272 
273 	/*
274 	 * Except for MWAIT, querying dynamic feature bits is disallowed, so
275 	 * that KVM can defer runtime updates until the next CPUID emulation.
276 	 */
277 	BUILD_BUG_ON(x86_feature == X86_FEATURE_APIC ||
278 		     x86_feature == X86_FEATURE_OSXSAVE ||
279 		     x86_feature == X86_FEATURE_OSPKE);
280 
281 	return vcpu->arch.cpu_caps[x86_leaf] & __feature_bit(x86_feature);
282 }
283 
284 static inline bool kvm_vcpu_is_legal_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
285 {
286 	if (guest_cpu_cap_has(vcpu, X86_FEATURE_LAM))
287 		cr3 &= ~(X86_CR3_LAM_U48 | X86_CR3_LAM_U57);
288 
289 	return kvm_vcpu_is_legal_gpa(vcpu, cr3);
290 }
291 
292 static inline bool guest_has_spec_ctrl_msr(struct kvm_vcpu *vcpu)
293 {
294 	return (guest_cpu_cap_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
295 		guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_STIBP) ||
296 		guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_IBRS) ||
297 		guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_SSBD));
298 }
299 
300 static inline bool guest_has_pred_cmd_msr(struct kvm_vcpu *vcpu)
301 {
302 	return (guest_cpu_cap_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
303 		guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_IBPB) ||
304 		guest_cpu_cap_has(vcpu, X86_FEATURE_SBPB));
305 }
306 
307 #endif
308