File Index
Files and directories
Sign in
FILE

cpuid.h

File preview with syntax highlighting.

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