120c8ccb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
200b27a3eSAvi Kivity /*
300b27a3eSAvi Kivity * Kernel-based Virtual Machine driver for Linux
400b27a3eSAvi Kivity * cpuid support routines
500b27a3eSAvi Kivity *
600b27a3eSAvi Kivity * derived from arch/x86/kvm/x86.c
700b27a3eSAvi Kivity *
800b27a3eSAvi Kivity * Copyright 2011 Red Hat, Inc. and/or its affiliates.
900b27a3eSAvi Kivity * Copyright IBM Corporation, 2008
1000b27a3eSAvi Kivity */
118d20bd63SSean Christopherson #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1200b27a3eSAvi Kivity
1300b27a3eSAvi Kivity #include <linux/kvm_host.h>
149717efbeSSean Christopherson #include "linux/lockdep.h"
151767e931SPaul Gortmaker #include <linux/export.h>
16bb5a798aSJan Kiszka #include <linux/vmalloc.h>
17bb5a798aSJan Kiszka #include <linux/uaccess.h>
183905f9adSIngo Molnar #include <linux/sched/stat.h>
193905f9adSIngo Molnar
204504b5c9SLuwei Kang #include <asm/processor.h>
2100b27a3eSAvi Kivity #include <asm/user.h>
22669ebabbSIngo Molnar #include <asm/fpu/xstate.h>
2372add915SSean Christopherson #include <asm/sgx.h>
24b66370dbSMichael Roth #include <asm/cpuid.h>
2500b27a3eSAvi Kivity #include "cpuid.h"
2600b27a3eSAvi Kivity #include "lapic.h"
2700b27a3eSAvi Kivity #include "mmu.h"
2800b27a3eSAvi Kivity #include "trace.h"
29474a5bb9SWei Huang #include "pmu.h"
30f422f853SPaul Durrant #include "xen.h"
3100b27a3eSAvi Kivity
3266a6950fSSean Christopherson /*
3366a6950fSSean Christopherson * Unlike "struct cpuinfo_x86.x86_capability", kvm_cpu_caps doesn't need to be
3466a6950fSSean Christopherson * aligned to sizeof(unsigned long) because it's not accessed via bitops.
3566a6950fSSean Christopherson */
364e66c0cbSSean Christopherson u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
3766a6950fSSean Christopherson EXPORT_SYMBOL_GPL(kvm_cpu_caps);
3866a6950fSSean Christopherson
3965fac86cSSean Christopherson struct cpuid_xstate_sizes {
4065fac86cSSean Christopherson u32 eax;
4165fac86cSSean Christopherson u32 ebx;
4265fac86cSSean Christopherson u32 ecx;
4365fac86cSSean Christopherson };
4465fac86cSSean Christopherson
4565fac86cSSean Christopherson static struct cpuid_xstate_sizes xstate_sizes[XFEATURE_MAX] __ro_after_init;
4665fac86cSSean Christopherson
kvm_init_xstate_sizes(void)4765fac86cSSean Christopherson void __init kvm_init_xstate_sizes(void)
4865fac86cSSean Christopherson {
4965fac86cSSean Christopherson u32 ign;
5065fac86cSSean Christopherson int i;
5165fac86cSSean Christopherson
5265fac86cSSean Christopherson for (i = XFEATURE_YMM; i < ARRAY_SIZE(xstate_sizes); i++) {
5365fac86cSSean Christopherson struct cpuid_xstate_sizes *xs = &xstate_sizes[i];
5465fac86cSSean Christopherson
5565fac86cSSean Christopherson cpuid_count(0xD, i, &xs->eax, &xs->ebx, &xs->ecx, &ign);
5665fac86cSSean Christopherson }
5765fac86cSSean Christopherson }
5865fac86cSSean Christopherson
xstate_required_size(u64 xstate_bv,bool compacted)59be50b206SGuang Zeng u32 xstate_required_size(u64 xstate_bv, bool compacted)
604344ee98SPaolo Bonzini {
614344ee98SPaolo Bonzini int feature_bit = 0;
624344ee98SPaolo Bonzini u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
634344ee98SPaolo Bonzini
64d91cab78SDave Hansen xstate_bv &= XFEATURE_MASK_EXTEND;
654344ee98SPaolo Bonzini while (xstate_bv) {
664344ee98SPaolo Bonzini if (xstate_bv & 0x1) {
6765fac86cSSean Christopherson struct cpuid_xstate_sizes *xs = &xstate_sizes[feature_bit];
6865fac86cSSean Christopherson u32 offset;
6965fac86cSSean Christopherson
70cc04b6a2SJing Liu /* ECX[1]: 64B alignment in compacted form */
71cc04b6a2SJing Liu if (compacted)
7265fac86cSSean Christopherson offset = (xs->ecx & 0x2) ? ALIGN(ret, 64) : ret;
73cc04b6a2SJing Liu else
7465fac86cSSean Christopherson offset = xs->ebx;
7565fac86cSSean Christopherson ret = max(ret, offset + xs->eax);
764344ee98SPaolo Bonzini }
774344ee98SPaolo Bonzini
784344ee98SPaolo Bonzini xstate_bv >>= 1;
794344ee98SPaolo Bonzini feature_bit++;
804344ee98SPaolo Bonzini }
814344ee98SPaolo Bonzini
824344ee98SPaolo Bonzini return ret;
834344ee98SPaolo Bonzini }
844344ee98SPaolo Bonzini
8587382003SSean Christopherson #define F feature_bit
86c4690d01SSean Christopherson
87c4690d01SSean Christopherson /* Scattered Flag - For features that are scattered by cpufeatures.h. */
88c4690d01SSean Christopherson #define SF(name) \
89c4690d01SSean Christopherson ({ \
90c4690d01SSean Christopherson BUILD_BUG_ON(X86_FEATURE_##name >= MAX_CPU_FEATURES); \
91c4690d01SSean Christopherson (boot_cpu_has(X86_FEATURE_##name) ? F(name) : 0); \
92c4690d01SSean Christopherson })
935c404cabSPaolo Bonzini
94277ad7d5SSean Christopherson /*
95277ad7d5SSean Christopherson * Magic value used by KVM when querying userspace-provided CPUID entries and
96277ad7d5SSean Christopherson * doesn't care about the CPIUD index because the index of the function in
97277ad7d5SSean Christopherson * question is not significant. Note, this magic value must have at least one
98277ad7d5SSean Christopherson * bit set in bits[63:32] and must be consumed as a u64 by cpuid_entry2_find()
99277ad7d5SSean Christopherson * to avoid false positives when processing guest CPUID input.
100277ad7d5SSean Christopherson */
101277ad7d5SSean Christopherson #define KVM_CPUID_INDEX_NOT_SIGNIFICANT -1ull
102b73a5432SBabu Moger
cpuid_entry2_find(struct kvm_cpuid_entry2 * entries,int nent,u32 function,u64 index)103f69858fcSVitaly Kuznetsov static inline struct kvm_cpuid_entry2 *cpuid_entry2_find(
104277ad7d5SSean Christopherson struct kvm_cpuid_entry2 *entries, int nent, u32 function, u64 index)
105f69858fcSVitaly Kuznetsov {
106f69858fcSVitaly Kuznetsov struct kvm_cpuid_entry2 *e;
107f69858fcSVitaly Kuznetsov int i;
108f69858fcSVitaly Kuznetsov
1099717efbeSSean Christopherson /*
1109717efbeSSean Christopherson * KVM has a semi-arbitrary rule that querying the guest's CPUID model
1119717efbeSSean Christopherson * with IRQs disabled is disallowed. The CPUID model can legitimately
1129717efbeSSean Christopherson * have over one hundred entries, i.e. the lookup is slow, and IRQs are
1139717efbeSSean Christopherson * typically disabled in KVM only when KVM is in a performance critical
1149717efbeSSean Christopherson * path, e.g. the core VM-Enter/VM-Exit run loop. Nothing will break
1159717efbeSSean Christopherson * if this rule is violated, this assertion is purely to flag potential
1169717efbeSSean Christopherson * performance issues. If this fires, consider moving the lookup out
1179717efbeSSean Christopherson * of the hotpath, e.g. by caching information during CPUID updates.
1189717efbeSSean Christopherson */
1199717efbeSSean Christopherson lockdep_assert_irqs_enabled();
1209717efbeSSean Christopherson
121f69858fcSVitaly Kuznetsov for (i = 0; i < nent; i++) {
122f69858fcSVitaly Kuznetsov e = &entries[i];
123f69858fcSVitaly Kuznetsov
124277ad7d5SSean Christopherson if (e->function != function)
125277ad7d5SSean Christopherson continue;
126277ad7d5SSean Christopherson
127277ad7d5SSean Christopherson /*
128277ad7d5SSean Christopherson * If the index isn't significant, use the first entry with a
129277ad7d5SSean Christopherson * matching function. It's userspace's responsibilty to not
130277ad7d5SSean Christopherson * provide "duplicate" entries in all cases.
131277ad7d5SSean Christopherson */
132277ad7d5SSean Christopherson if (!(e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) || e->index == index)
133f69858fcSVitaly Kuznetsov return e;
134277ad7d5SSean Christopherson
135277ad7d5SSean Christopherson
136277ad7d5SSean Christopherson /*
137277ad7d5SSean Christopherson * Similarly, use the first matching entry if KVM is doing a
138277ad7d5SSean Christopherson * lookup (as opposed to emulating CPUID) for a function that's
139277ad7d5SSean Christopherson * architecturally defined as not having a significant index.
140277ad7d5SSean Christopherson */
141277ad7d5SSean Christopherson if (index == KVM_CPUID_INDEX_NOT_SIGNIFICANT) {
142277ad7d5SSean Christopherson /*
143277ad7d5SSean Christopherson * Direct lookups from KVM should not diverge from what
144277ad7d5SSean Christopherson * KVM defines internally (the architectural behavior).
145277ad7d5SSean Christopherson */
146277ad7d5SSean Christopherson WARN_ON_ONCE(cpuid_function_is_indexed(function));
147277ad7d5SSean Christopherson return e;
148277ad7d5SSean Christopherson }
149f69858fcSVitaly Kuznetsov }
150f69858fcSVitaly Kuznetsov
151f69858fcSVitaly Kuznetsov return NULL;
152f69858fcSVitaly Kuznetsov }
153f69858fcSVitaly Kuznetsov
kvm_check_cpuid(struct kvm_vcpu * vcpu,struct kvm_cpuid_entry2 * entries,int nent)1545ab2f45bSJing Liu static int kvm_check_cpuid(struct kvm_vcpu *vcpu,
1555ab2f45bSJing Liu struct kvm_cpuid_entry2 *entries,
1565ab2f45bSJing Liu int nent)
157a76733a9SXiaoyao Li {
158a76733a9SXiaoyao Li struct kvm_cpuid_entry2 *best;
1595ab2f45bSJing Liu u64 xfeatures;
160a76733a9SXiaoyao Li
161a76733a9SXiaoyao Li /*
162a76733a9SXiaoyao Li * The existing code assumes virtual address is 48-bit or 57-bit in the
163a76733a9SXiaoyao Li * canonical address checks; exit if it is ever changed.
164a76733a9SXiaoyao Li */
165277ad7d5SSean Christopherson best = cpuid_entry2_find(entries, nent, 0x80000008,
166277ad7d5SSean Christopherson KVM_CPUID_INDEX_NOT_SIGNIFICANT);
167a76733a9SXiaoyao Li if (best) {
168a76733a9SXiaoyao Li int vaddr_bits = (best->eax & 0xff00) >> 8;
169a76733a9SXiaoyao Li
170a76733a9SXiaoyao Li if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0)
171a76733a9SXiaoyao Li return -EINVAL;
172a76733a9SXiaoyao Li }
173a76733a9SXiaoyao Li
1745ab2f45bSJing Liu /*
1755ab2f45bSJing Liu * Exposing dynamic xfeatures to the guest requires additional
1765ab2f45bSJing Liu * enabling in the FPU, e.g. to expand the guest XSAVE state size.
1775ab2f45bSJing Liu */
1785ab2f45bSJing Liu best = cpuid_entry2_find(entries, nent, 0xd, 0);
1795ab2f45bSJing Liu if (!best)
180a76733a9SXiaoyao Li return 0;
1815ab2f45bSJing Liu
1825ab2f45bSJing Liu xfeatures = best->eax | ((u64)best->edx << 32);
1835ab2f45bSJing Liu xfeatures &= XFEATURE_MASK_USER_DYNAMIC;
1845ab2f45bSJing Liu if (!xfeatures)
1855ab2f45bSJing Liu return 0;
1865ab2f45bSJing Liu
1875ab2f45bSJing Liu return fpu_enable_guest_xfd_features(&vcpu->arch.guest_fpu, xfeatures);
188a76733a9SXiaoyao Li }
189a76733a9SXiaoyao Li
190c6617c61SVitaly Kuznetsov /* Check whether the supplied CPUID data is equal to what is already set for the vCPU. */
kvm_cpuid_check_equal(struct kvm_vcpu * vcpu,struct kvm_cpuid_entry2 * e2,int nent)191c6617c61SVitaly Kuznetsov static int kvm_cpuid_check_equal(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
192c6617c61SVitaly Kuznetsov int nent)
193c6617c61SVitaly Kuznetsov {
194c6617c61SVitaly Kuznetsov struct kvm_cpuid_entry2 *orig;
195c6617c61SVitaly Kuznetsov int i;
196c6617c61SVitaly Kuznetsov
197c6617c61SVitaly Kuznetsov if (nent != vcpu->arch.cpuid_nent)
198c6617c61SVitaly Kuznetsov return -EINVAL;
199c6617c61SVitaly Kuznetsov
200c6617c61SVitaly Kuznetsov for (i = 0; i < nent; i++) {
201c6617c61SVitaly Kuznetsov orig = &vcpu->arch.cpuid_entries[i];
202c6617c61SVitaly Kuznetsov if (e2[i].function != orig->function ||
203c6617c61SVitaly Kuznetsov e2[i].index != orig->index ||
204033a3ea5SVitaly Kuznetsov e2[i].flags != orig->flags ||
205c6617c61SVitaly Kuznetsov e2[i].eax != orig->eax || e2[i].ebx != orig->ebx ||
206c6617c61SVitaly Kuznetsov e2[i].ecx != orig->ecx || e2[i].edx != orig->edx)
207c6617c61SVitaly Kuznetsov return -EINVAL;
208c6617c61SVitaly Kuznetsov }
209c6617c61SVitaly Kuznetsov
210c6617c61SVitaly Kuznetsov return 0;
211c6617c61SVitaly Kuznetsov }
212c6617c61SVitaly Kuznetsov
kvm_get_hypervisor_cpuid(struct kvm_vcpu * vcpu,const char * sig)21348639df8SPaul Durrant static struct kvm_hypervisor_cpuid kvm_get_hypervisor_cpuid(struct kvm_vcpu *vcpu,
21448639df8SPaul Durrant const char *sig)
215760849b1SPaul Durrant {
21648639df8SPaul Durrant struct kvm_hypervisor_cpuid cpuid = {};
217760849b1SPaul Durrant struct kvm_cpuid_entry2 *entry;
21848639df8SPaul Durrant u32 base;
219760849b1SPaul Durrant
22048639df8SPaul Durrant for_each_possible_hypervisor_cpuid_base(base) {
22148639df8SPaul Durrant entry = kvm_find_cpuid_entry(vcpu, base);
222760849b1SPaul Durrant
223760849b1SPaul Durrant if (entry) {
224760849b1SPaul Durrant u32 signature[3];
225760849b1SPaul Durrant
226760849b1SPaul Durrant signature[0] = entry->ebx;
227760849b1SPaul Durrant signature[1] = entry->ecx;
228760849b1SPaul Durrant signature[2] = entry->edx;
229760849b1SPaul Durrant
23048639df8SPaul Durrant if (!memcmp(signature, sig, sizeof(signature))) {
23148639df8SPaul Durrant cpuid.base = base;
23248639df8SPaul Durrant cpuid.limit = entry->eax;
233760849b1SPaul Durrant break;
234760849b1SPaul Durrant }
235760849b1SPaul Durrant }
236760849b1SPaul Durrant }
23748639df8SPaul Durrant
23848639df8SPaul Durrant return cpuid;
239760849b1SPaul Durrant }
240760849b1SPaul Durrant
__kvm_find_kvm_cpuid_features(struct kvm_vcpu * vcpu,struct kvm_cpuid_entry2 * entries,int nent)241ee3a5f9eSVitaly Kuznetsov static struct kvm_cpuid_entry2 *__kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu,
242ee3a5f9eSVitaly Kuznetsov struct kvm_cpuid_entry2 *entries, int nent)
243760849b1SPaul Durrant {
24448639df8SPaul Durrant u32 base = vcpu->arch.kvm_cpuid.base;
245760849b1SPaul Durrant
246760849b1SPaul Durrant if (!base)
247760849b1SPaul Durrant return NULL;
248760849b1SPaul Durrant
249277ad7d5SSean Christopherson return cpuid_entry2_find(entries, nent, base | KVM_CPUID_FEATURES,
250277ad7d5SSean Christopherson KVM_CPUID_INDEX_NOT_SIGNIFICANT);
251ee3a5f9eSVitaly Kuznetsov }
252ee3a5f9eSVitaly Kuznetsov
kvm_find_kvm_cpuid_features(struct kvm_vcpu * vcpu)253ee3a5f9eSVitaly Kuznetsov static struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
254ee3a5f9eSVitaly Kuznetsov {
255ee3a5f9eSVitaly Kuznetsov return __kvm_find_kvm_cpuid_features(vcpu, vcpu->arch.cpuid_entries,
256ee3a5f9eSVitaly Kuznetsov vcpu->arch.cpuid_nent);
257760849b1SPaul Durrant }
258760849b1SPaul Durrant
kvm_update_pv_runtime(struct kvm_vcpu * vcpu)25901b4f510SOliver Upton void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
26001b4f510SOliver Upton {
261760849b1SPaul Durrant struct kvm_cpuid_entry2 *best = kvm_find_kvm_cpuid_features(vcpu);
26201b4f510SOliver Upton
26301b4f510SOliver Upton /*
26401b4f510SOliver Upton * save the feature bitmap to avoid cpuid lookup for every PV
26501b4f510SOliver Upton * operation
26601b4f510SOliver Upton */
26701b4f510SOliver Upton if (best)
26801b4f510SOliver Upton vcpu->arch.pv_cpuid.features = best->eax;
26901b4f510SOliver Upton }
27001b4f510SOliver Upton
2715c89be1dSVitaly Kuznetsov /*
2725c89be1dSVitaly Kuznetsov * Calculate guest's supported XCR0 taking into account guest CPUID data and
273938c8745SSean Christopherson * KVM's supported XCR0 (comprised of host's XCR0 and KVM_SUPPORTED_XCR0).
2745c89be1dSVitaly Kuznetsov */
cpuid_get_supported_xcr0(struct kvm_cpuid_entry2 * entries,int nent)2755c89be1dSVitaly Kuznetsov static u64 cpuid_get_supported_xcr0(struct kvm_cpuid_entry2 *entries, int nent)
2765c89be1dSVitaly Kuznetsov {
2775c89be1dSVitaly Kuznetsov struct kvm_cpuid_entry2 *best;
2785c89be1dSVitaly Kuznetsov
2795c89be1dSVitaly Kuznetsov best = cpuid_entry2_find(entries, nent, 0xd, 0);
2805c89be1dSVitaly Kuznetsov if (!best)
2815c89be1dSVitaly Kuznetsov return 0;
2825c89be1dSVitaly Kuznetsov
283938c8745SSean Christopherson return (best->eax | ((u64)best->edx << 32)) & kvm_caps.supported_xcr0;
2845c89be1dSVitaly Kuznetsov }
2855c89be1dSVitaly Kuznetsov
__kvm_update_cpuid_runtime(struct kvm_vcpu * vcpu,struct kvm_cpuid_entry2 * entries,int nent)286ee3a5f9eSVitaly Kuznetsov static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *entries,
287ee3a5f9eSVitaly Kuznetsov int nent)
28800b27a3eSAvi Kivity {
28900b27a3eSAvi Kivity struct kvm_cpuid_entry2 *best;
29000b27a3eSAvi Kivity
291277ad7d5SSean Christopherson best = cpuid_entry2_find(entries, nent, 1, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
2920d3b2ba1SXiaoyao Li if (best) {
29300b27a3eSAvi Kivity /* Update OSXSAVE bit */
2940d3b2ba1SXiaoyao Li if (boot_cpu_has(X86_FEATURE_XSAVE))
295b32666b1SSean Christopherson cpuid_entry_change(best, X86_FEATURE_OSXSAVE,
296607475cfSBinbin Wu kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE));
29700b27a3eSAvi Kivity
298b32666b1SSean Christopherson cpuid_entry_change(best, X86_FEATURE_APIC,
299b32666b1SSean Christopherson vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE);
3000d3b2ba1SXiaoyao Li }
301c7dd15b3SJim Mattson
302ee3a5f9eSVitaly Kuznetsov best = cpuid_entry2_find(entries, nent, 7, 0);
303b32666b1SSean Christopherson if (best && boot_cpu_has(X86_FEATURE_PKU) && best->function == 0x7)
304b32666b1SSean Christopherson cpuid_entry_change(best, X86_FEATURE_OSPKE,
305607475cfSBinbin Wu kvm_is_cr4_bit_set(vcpu, X86_CR4_PKE));
306b9baba86SHuaitong Han
307ee3a5f9eSVitaly Kuznetsov best = cpuid_entry2_find(entries, nent, 0xD, 0);
308aedbaf4fSXiaoyao Li if (best)
309a71936abSXiaoyao Li best->ebx = xstate_required_size(vcpu->arch.xcr0, false);
310d7876f1bSPaolo Bonzini
311ee3a5f9eSVitaly Kuznetsov best = cpuid_entry2_find(entries, nent, 0xD, 1);
3124c61534aSSean Christopherson if (best && (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
3134c61534aSSean Christopherson cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
314412a3c41SPaolo Bonzini best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
315412a3c41SPaolo Bonzini
316ee3a5f9eSVitaly Kuznetsov best = __kvm_find_kvm_cpuid_features(vcpu, entries, nent);
317caa057a2SWanpeng Li if (kvm_hlt_in_guest(vcpu->kvm) && best &&
318caa057a2SWanpeng Li (best->eax & (1 << KVM_FEATURE_PV_UNHALT)))
319caa057a2SWanpeng Li best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT);
320caa057a2SWanpeng Li
321511a8556SWanpeng Li if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT)) {
322277ad7d5SSean Christopherson best = cpuid_entry2_find(entries, nent, 0x1, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
323b32666b1SSean Christopherson if (best)
324b32666b1SSean Christopherson cpuid_entry_change(best, X86_FEATURE_MWAIT,
325b32666b1SSean Christopherson vcpu->arch.ia32_misc_enable_msr &
326b32666b1SSean Christopherson MSR_IA32_MISC_ENABLE_MWAIT);
327511a8556SWanpeng Li }
328aedbaf4fSXiaoyao Li }
329ee3a5f9eSVitaly Kuznetsov
kvm_update_cpuid_runtime(struct kvm_vcpu * vcpu)330ee3a5f9eSVitaly Kuznetsov void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
331ee3a5f9eSVitaly Kuznetsov {
332ee3a5f9eSVitaly Kuznetsov __kvm_update_cpuid_runtime(vcpu, vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
333ee3a5f9eSVitaly Kuznetsov }
3342259c17fSJim Mattson EXPORT_SYMBOL_GPL(kvm_update_cpuid_runtime);
335aedbaf4fSXiaoyao Li
kvm_cpuid_has_hyperv(struct kvm_cpuid_entry2 * entries,int nent)3363be29eb7SSean Christopherson static bool kvm_cpuid_has_hyperv(struct kvm_cpuid_entry2 *entries, int nent)
3373be29eb7SSean Christopherson {
3383be29eb7SSean Christopherson struct kvm_cpuid_entry2 *entry;
3393be29eb7SSean Christopherson
3403be29eb7SSean Christopherson entry = cpuid_entry2_find(entries, nent, HYPERV_CPUID_INTERFACE,
3413be29eb7SSean Christopherson KVM_CPUID_INDEX_NOT_SIGNIFICANT);
3423be29eb7SSean Christopherson return entry && entry->eax == HYPERV_CPUID_SIGNATURE_EAX;
3433be29eb7SSean Christopherson }
3443be29eb7SSean Christopherson
kvm_vcpu_after_set_cpuid(struct kvm_vcpu * vcpu)345346ce359SXiaoyao Li static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
346aedbaf4fSXiaoyao Li {
347aedbaf4fSXiaoyao Li struct kvm_lapic *apic = vcpu->arch.apic;
348aedbaf4fSXiaoyao Li struct kvm_cpuid_entry2 *best;
349ccf31d6eSSean Christopherson bool allow_gbpages;
350aedbaf4fSXiaoyao Li
35142764413SSean Christopherson BUILD_BUG_ON(KVM_NR_GOVERNED_FEATURES > KVM_MAX_NR_GOVERNED_FEATURES);
35242764413SSean Christopherson bitmap_zero(vcpu->arch.governed_features.enabled,
35342764413SSean Christopherson KVM_MAX_NR_GOVERNED_FEATURES);
35442764413SSean Christopherson
355ccf31d6eSSean Christopherson /*
356ccf31d6eSSean Christopherson * If TDP is enabled, let the guest use GBPAGES if they're supported in
357ccf31d6eSSean Christopherson * hardware. The hardware page walker doesn't let KVM disable GBPAGES,
358ccf31d6eSSean Christopherson * i.e. won't treat them as reserved, and KVM doesn't redo the GVA->GPA
359ccf31d6eSSean Christopherson * walk for performance and complexity reasons. Not to mention KVM
360ccf31d6eSSean Christopherson * _can't_ solve the problem because GVA->GPA walks aren't visible to
361ccf31d6eSSean Christopherson * KVM once a TDP translation is installed. Mimic hardware behavior so
362ccf31d6eSSean Christopherson * that KVM's is at least consistent, i.e. doesn't randomly inject #PF.
363ccf31d6eSSean Christopherson * If TDP is disabled, honor *only* guest CPUID as KVM has full control
364ccf31d6eSSean Christopherson * and can install smaller shadow pages if the host lacks 1GiB support.
365ccf31d6eSSean Christopherson */
366ccf31d6eSSean Christopherson allow_gbpages = tdp_enabled ? boot_cpu_has(X86_FEATURE_GBPAGES) :
367ccf31d6eSSean Christopherson guest_cpuid_has(vcpu, X86_FEATURE_GBPAGES);
368ccf31d6eSSean Christopherson if (allow_gbpages)
369ccf31d6eSSean Christopherson kvm_governed_feature_set(vcpu, X86_FEATURE_GBPAGES);
370aedbaf4fSXiaoyao Li
371277ad7d5SSean Christopherson best = kvm_find_cpuid_entry(vcpu, 1);
372aedbaf4fSXiaoyao Li if (best && apic) {
373aedbaf4fSXiaoyao Li if (cpuid_entry_has(best, X86_FEATURE_TSC_DEADLINE_TIMER))
374aedbaf4fSXiaoyao Li apic->lapic_timer.timer_mode_mask = 3 << 17;
375aedbaf4fSXiaoyao Li else
376aedbaf4fSXiaoyao Li apic->lapic_timer.timer_mode_mask = 1 << 17;
377aedbaf4fSXiaoyao Li
378aedbaf4fSXiaoyao Li kvm_apic_set_version(vcpu);
379aedbaf4fSXiaoyao Li }
380aedbaf4fSXiaoyao Li
381ee519b3aSSean Christopherson vcpu->arch.guest_supported_xcr0 =
3825c89be1dSVitaly Kuznetsov cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
38372add915SSean Christopherson
38401b4f510SOliver Upton kvm_update_pv_runtime(vcpu);
38501b4f510SOliver Upton
386bdda0c17SSean Christopherson vcpu->arch.is_amd_compatible = guest_cpuid_is_amd_or_hygon(vcpu);
3875a4f55cdSEugene Korenevsky vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
388a8ac864aSSean Christopherson vcpu->arch.reserved_gpa_bits = kvm_vcpu_reserved_gpa_bits_raw(vcpu);
3895a4f55cdSEugene Korenevsky
390c6702c9dSWei Huang kvm_pmu_refresh(vcpu);
391b899c132SKrish Sadhukhan vcpu->arch.cr4_guest_rsvd_bits =
392b899c132SKrish Sadhukhan __cr4_reserved_bits(guest_cpuid_has, vcpu);
393c44d9b34SSean Christopherson
3943be29eb7SSean Christopherson kvm_hv_set_cpuid(vcpu, kvm_cpuid_has_hyperv(vcpu->arch.cpuid_entries,
3953be29eb7SSean Christopherson vcpu->arch.cpuid_nent));
3968f014550SVitaly Kuznetsov
397c44d9b34SSean Christopherson /* Invoke the vendor callback only after the above state is updated. */
398b3646477SJason Baron static_call(kvm_x86_vcpu_after_set_cpuid)(vcpu);
3995b7f575cSSean Christopherson
4005b7f575cSSean Christopherson /*
40149c6f875SSean Christopherson * Except for the MMU, which needs to do its thing any vendor specific
40249c6f875SSean Christopherson * adjustments to the reserved GPA bits.
4035b7f575cSSean Christopherson */
40449c6f875SSean Christopherson kvm_mmu_after_set_cpuid(vcpu);
40500b27a3eSAvi Kivity }
40600b27a3eSAvi Kivity
cpuid_query_maxphyaddr(struct kvm_vcpu * vcpu)4075a4f55cdSEugene Korenevsky int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu)
4085a4f55cdSEugene Korenevsky {
4095a4f55cdSEugene Korenevsky struct kvm_cpuid_entry2 *best;
4105a4f55cdSEugene Korenevsky
411277ad7d5SSean Christopherson best = kvm_find_cpuid_entry(vcpu, 0x80000000);
4125a4f55cdSEugene Korenevsky if (!best || best->eax < 0x80000008)
4135a4f55cdSEugene Korenevsky goto not_found;
414277ad7d5SSean Christopherson best = kvm_find_cpuid_entry(vcpu, 0x80000008);
4155a4f55cdSEugene Korenevsky if (best)
4165a4f55cdSEugene Korenevsky return best->eax & 0xff;
4175a4f55cdSEugene Korenevsky not_found:
4185a4f55cdSEugene Korenevsky return 36;
4195a4f55cdSEugene Korenevsky }
4205a4f55cdSEugene Korenevsky
421a8ac864aSSean Christopherson /*
422a8ac864aSSean Christopherson * This "raw" version returns the reserved GPA bits without any adjustments for
423a8ac864aSSean Christopherson * encryption technologies that usurp bits. The raw mask should be used if and
424a8ac864aSSean Christopherson * only if hardware does _not_ strip the usurped bits, e.g. in virtual MTRRs.
425a8ac864aSSean Christopherson */
kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu * vcpu)426a8ac864aSSean Christopherson u64 kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu *vcpu)
427a8ac864aSSean Christopherson {
428a8ac864aSSean Christopherson return rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
429a8ac864aSSean Christopherson }
430a8ac864aSSean Christopherson
kvm_set_cpuid(struct kvm_vcpu * vcpu,struct kvm_cpuid_entry2 * e2,int nent)4318b44b174SSean Christopherson static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
4328b44b174SSean Christopherson int nent)
4338b44b174SSean Christopherson {
4348b44b174SSean Christopherson int r;
4358b44b174SSean Christopherson
436ee3a5f9eSVitaly Kuznetsov __kvm_update_cpuid_runtime(vcpu, e2, nent);
437ee3a5f9eSVitaly Kuznetsov
438c6617c61SVitaly Kuznetsov /*
439c6617c61SVitaly Kuznetsov * KVM does not correctly handle changing guest CPUID after KVM_RUN, as
440c6617c61SVitaly Kuznetsov * MAXPHYADDR, GBPAGES support, AMD reserved bit behavior, etc.. aren't
441c6617c61SVitaly Kuznetsov * tracked in kvm_mmu_page_role. As a result, KVM may miss guest page
442c6617c61SVitaly Kuznetsov * faults due to reusing SPs/SPTEs. In practice no sane VMM mucks with
443c6617c61SVitaly Kuznetsov * the core vCPU model on the fly. It would've been better to forbid any
444c6617c61SVitaly Kuznetsov * KVM_SET_CPUID{,2} calls after KVM_RUN altogether but unfortunately
445c6617c61SVitaly Kuznetsov * some VMMs (e.g. QEMU) reuse vCPU fds for CPU hotplug/unplug and do
446c6617c61SVitaly Kuznetsov * KVM_SET_CPUID{,2} again. To support this legacy behavior, check
447c6617c61SVitaly Kuznetsov * whether the supplied CPUID data is equal to what's already set.
448c6617c61SVitaly Kuznetsov */
449fb3146b4SSean Christopherson if (kvm_vcpu_has_run(vcpu)) {
450811f95ffSSean Christopherson r = kvm_cpuid_check_equal(vcpu, e2, nent);
451811f95ffSSean Christopherson if (r)
452811f95ffSSean Christopherson return r;
453811f95ffSSean Christopherson
454811f95ffSSean Christopherson kvfree(e2);
455811f95ffSSean Christopherson return 0;
456811f95ffSSean Christopherson }
457c6617c61SVitaly Kuznetsov
4583be29eb7SSean Christopherson if (kvm_cpuid_has_hyperv(e2, nent)) {
4593be29eb7SSean Christopherson r = kvm_hv_vcpu_init(vcpu);
4603be29eb7SSean Christopherson if (r)
4613be29eb7SSean Christopherson return r;
4623be29eb7SSean Christopherson }
4633be29eb7SSean Christopherson
4645ab2f45bSJing Liu r = kvm_check_cpuid(vcpu, e2, nent);
4658b44b174SSean Christopherson if (r)
4668b44b174SSean Christopherson return r;
4678b44b174SSean Christopherson
4688b44b174SSean Christopherson kvfree(vcpu->arch.cpuid_entries);
4698b44b174SSean Christopherson vcpu->arch.cpuid_entries = e2;
4708b44b174SSean Christopherson vcpu->arch.cpuid_nent = nent;
4718b44b174SSean Christopherson
47248639df8SPaul Durrant vcpu->arch.kvm_cpuid = kvm_get_hypervisor_cpuid(vcpu, KVM_SIGNATURE);
473f422f853SPaul Durrant vcpu->arch.xen.cpuid = kvm_get_hypervisor_cpuid(vcpu, XEN_SIGNATURE);
4748b44b174SSean Christopherson kvm_vcpu_after_set_cpuid(vcpu);
4758b44b174SSean Christopherson
4768b44b174SSean Christopherson return 0;
4778b44b174SSean Christopherson }
4788b44b174SSean Christopherson
47900b27a3eSAvi Kivity /* when an old userspace process fills a new kernel module */
kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu * vcpu,struct kvm_cpuid * cpuid,struct kvm_cpuid_entry __user * entries)48000b27a3eSAvi Kivity int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
48100b27a3eSAvi Kivity struct kvm_cpuid *cpuid,
48200b27a3eSAvi Kivity struct kvm_cpuid_entry __user *entries)
48300b27a3eSAvi Kivity {
48400b27a3eSAvi Kivity int r, i;
485255cbecfSVitaly Kuznetsov struct kvm_cpuid_entry *e = NULL;
486255cbecfSVitaly Kuznetsov struct kvm_cpuid_entry2 *e2 = NULL;
48700b27a3eSAvi Kivity
48800b27a3eSAvi Kivity if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
489255cbecfSVitaly Kuznetsov return -E2BIG;
490255cbecfSVitaly Kuznetsov
49183676e92SPaolo Bonzini if (cpuid->nent) {
492255cbecfSVitaly Kuznetsov e = vmemdup_user(entries, array_size(sizeof(*e), cpuid->nent));
493255cbecfSVitaly Kuznetsov if (IS_ERR(e))
494255cbecfSVitaly Kuznetsov return PTR_ERR(e);
495255cbecfSVitaly Kuznetsov
496255cbecfSVitaly Kuznetsov e2 = kvmalloc_array(cpuid->nent, sizeof(*e2), GFP_KERNEL_ACCOUNT);
497255cbecfSVitaly Kuznetsov if (!e2) {
498255cbecfSVitaly Kuznetsov r = -ENOMEM;
499255cbecfSVitaly Kuznetsov goto out_free_cpuid;
5007ec28e26SDenis Efremov }
50183676e92SPaolo Bonzini }
50200b27a3eSAvi Kivity for (i = 0; i < cpuid->nent; i++) {
503255cbecfSVitaly Kuznetsov e2[i].function = e[i].function;
504255cbecfSVitaly Kuznetsov e2[i].eax = e[i].eax;
505255cbecfSVitaly Kuznetsov e2[i].ebx = e[i].ebx;
506255cbecfSVitaly Kuznetsov e2[i].ecx = e[i].ecx;
507255cbecfSVitaly Kuznetsov e2[i].edx = e[i].edx;
508255cbecfSVitaly Kuznetsov e2[i].index = 0;
509255cbecfSVitaly Kuznetsov e2[i].flags = 0;
510255cbecfSVitaly Kuznetsov e2[i].padding[0] = 0;
511255cbecfSVitaly Kuznetsov e2[i].padding[1] = 0;
512255cbecfSVitaly Kuznetsov e2[i].padding[2] = 0;
51300b27a3eSAvi Kivity }
514255cbecfSVitaly Kuznetsov
5158b44b174SSean Christopherson r = kvm_set_cpuid(vcpu, e2, cpuid->nent);
5168b44b174SSean Christopherson if (r)
517255cbecfSVitaly Kuznetsov kvfree(e2);
51800b27a3eSAvi Kivity
519255cbecfSVitaly Kuznetsov out_free_cpuid:
520255cbecfSVitaly Kuznetsov kvfree(e);
521255cbecfSVitaly Kuznetsov
52200b27a3eSAvi Kivity return r;
52300b27a3eSAvi Kivity }
52400b27a3eSAvi Kivity
kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu * vcpu,struct kvm_cpuid2 * cpuid,struct kvm_cpuid_entry2 __user * entries)52500b27a3eSAvi Kivity int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
52600b27a3eSAvi Kivity struct kvm_cpuid2 *cpuid,
52700b27a3eSAvi Kivity struct kvm_cpuid_entry2 __user *entries)
52800b27a3eSAvi Kivity {
529255cbecfSVitaly Kuznetsov struct kvm_cpuid_entry2 *e2 = NULL;
53000b27a3eSAvi Kivity int r;
53100b27a3eSAvi Kivity
53200b27a3eSAvi Kivity if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
533255cbecfSVitaly Kuznetsov return -E2BIG;
534255cbecfSVitaly Kuznetsov
535255cbecfSVitaly Kuznetsov if (cpuid->nent) {
536255cbecfSVitaly Kuznetsov e2 = vmemdup_user(entries, array_size(sizeof(*e2), cpuid->nent));
537255cbecfSVitaly Kuznetsov if (IS_ERR(e2))
538255cbecfSVitaly Kuznetsov return PTR_ERR(e2);
539a76733a9SXiaoyao Li }
540a76733a9SXiaoyao Li
5418b44b174SSean Christopherson r = kvm_set_cpuid(vcpu, e2, cpuid->nent);
5428b44b174SSean Christopherson if (r)
543255cbecfSVitaly Kuznetsov kvfree(e2);
5448b44b174SSean Christopherson
545255cbecfSVitaly Kuznetsov return r;
546255cbecfSVitaly Kuznetsov }
547255cbecfSVitaly Kuznetsov
kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu * vcpu,struct kvm_cpuid2 * cpuid,struct kvm_cpuid_entry2 __user * entries)54800b27a3eSAvi Kivity int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
54900b27a3eSAvi Kivity struct kvm_cpuid2 *cpuid,
55000b27a3eSAvi Kivity struct kvm_cpuid_entry2 __user *entries)
55100b27a3eSAvi Kivity {
55200b27a3eSAvi Kivity if (cpuid->nent < vcpu->arch.cpuid_nent)
553ab322c43SSean Christopherson return -E2BIG;
554ab322c43SSean Christopherson
555181f4948SMichael Roth if (copy_to_user(entries, vcpu->arch.cpuid_entries,
55600b27a3eSAvi Kivity vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
557ab322c43SSean Christopherson return -EFAULT;
55800b27a3eSAvi Kivity
55900b27a3eSAvi Kivity cpuid->nent = vcpu->arch.cpuid_nent;
560ab322c43SSean Christopherson return 0;
56100b27a3eSAvi Kivity }
56200b27a3eSAvi Kivity
5634e66c0cbSSean Christopherson /* Mask kvm_cpu_caps for @leaf with the raw CPUID capabilities of this CPU. */
__kvm_cpu_cap_mask(unsigned int leaf)564462f8ddeSSean Christopherson static __always_inline void __kvm_cpu_cap_mask(unsigned int leaf)
56566a6950fSSean Christopherson {
566d8577a4cSSean Christopherson const struct cpuid_reg cpuid = x86_feature_cpuid(leaf * 32);
567d8577a4cSSean Christopherson struct kvm_cpuid_entry2 entry;
568d8577a4cSSean Christopherson
56966a6950fSSean Christopherson reverse_cpuid_check(leaf);
570d8577a4cSSean Christopherson
571d8577a4cSSean Christopherson cpuid_count(cpuid.function, cpuid.index,
572d8577a4cSSean Christopherson &entry.eax, &entry.ebx, &entry.ecx, &entry.edx);
573d8577a4cSSean Christopherson
574855c7e9bSSean Christopherson kvm_cpu_caps[leaf] &= *__cpuid_entry_get_reg(&entry, cpuid.reg);
57566a6950fSSean Christopherson }
57666a6950fSSean Christopherson
577462f8ddeSSean Christopherson static __always_inline
kvm_cpu_cap_init_kvm_defined(enum kvm_only_cpuid_leafs leaf,u32 mask)578047c7229SSean Christopherson void kvm_cpu_cap_init_kvm_defined(enum kvm_only_cpuid_leafs leaf, u32 mask)
5794e66c0cbSSean Christopherson {
580047c7229SSean Christopherson /* Use kvm_cpu_cap_mask for leafs that aren't KVM-only. */
5814e66c0cbSSean Christopherson BUILD_BUG_ON(leaf < NCAPINTS);
5824e66c0cbSSean Christopherson
5834e66c0cbSSean Christopherson kvm_cpu_caps[leaf] = mask;
5844e66c0cbSSean Christopherson
5854e66c0cbSSean Christopherson __kvm_cpu_cap_mask(leaf);
5864e66c0cbSSean Christopherson }
5874e66c0cbSSean Christopherson
kvm_cpu_cap_mask(enum cpuid_leafs leaf,u32 mask)5884e66c0cbSSean Christopherson static __always_inline void kvm_cpu_cap_mask(enum cpuid_leafs leaf, u32 mask)
5894e66c0cbSSean Christopherson {
590047c7229SSean Christopherson /* Use kvm_cpu_cap_init_kvm_defined for KVM-only leafs. */
5914e66c0cbSSean Christopherson BUILD_BUG_ON(leaf >= NCAPINTS);
5924e66c0cbSSean Christopherson
5934e66c0cbSSean Christopherson kvm_cpu_caps[leaf] &= mask;
5944e66c0cbSSean Christopherson
5954e66c0cbSSean Christopherson __kvm_cpu_cap_mask(leaf);
5964e66c0cbSSean Christopherson }
5974e66c0cbSSean Christopherson
kvm_set_cpu_caps(void)59866a6950fSSean Christopherson void kvm_set_cpu_caps(void)
59966a6950fSSean Christopherson {
60066a6950fSSean Christopherson #ifdef CONFIG_X86_64
60166a6950fSSean Christopherson unsigned int f_gbpages = F(GBPAGES);
60266a6950fSSean Christopherson unsigned int f_lm = F(LM);
603690a757dSJing Liu unsigned int f_xfd = F(XFD);
60466a6950fSSean Christopherson #else
60566a6950fSSean Christopherson unsigned int f_gbpages = 0;
60666a6950fSSean Christopherson unsigned int f_lm = 0;
607690a757dSJing Liu unsigned int f_xfd = 0;
60866a6950fSSean Christopherson #endif
6094e66c0cbSSean Christopherson memset(kvm_cpu_caps, 0, sizeof(kvm_cpu_caps));
61066a6950fSSean Christopherson
6114e66c0cbSSean Christopherson BUILD_BUG_ON(sizeof(kvm_cpu_caps) - (NKVMCAPINTS * sizeof(*kvm_cpu_caps)) >
61266a6950fSSean Christopherson sizeof(boot_cpu_data.x86_capability));
61366a6950fSSean Christopherson
61466a6950fSSean Christopherson memcpy(&kvm_cpu_caps, &boot_cpu_data.x86_capability,
6154e66c0cbSSean Christopherson sizeof(kvm_cpu_caps) - (NKVMCAPINTS * sizeof(*kvm_cpu_caps)));
61666a6950fSSean Christopherson
61766a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_1_ECX,
61866a6950fSSean Christopherson /*
61966a6950fSSean Christopherson * NOTE: MONITOR (and MWAIT) are emulated as NOP, but *not*
62066a6950fSSean Christopherson * advertised to guests via CPUID!
62166a6950fSSean Christopherson */
62266a6950fSSean Christopherson F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ |
62366a6950fSSean Christopherson 0 /* DS-CPL, VMX, SMX, EST */ |
62466a6950fSSean Christopherson 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
62527461da3SLike Xu F(FMA) | F(CX16) | 0 /* xTPR Update */ | F(PDCM) |
62666a6950fSSean Christopherson F(PCID) | 0 /* Reserved, DCA */ | F(XMM4_1) |
62766a6950fSSean Christopherson F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
62866a6950fSSean Christopherson 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
62966a6950fSSean Christopherson F(F16C) | F(RDRAND)
63066a6950fSSean Christopherson );
63193c380e7SSean Christopherson /* KVM emulates x2apic in software irrespective of host support. */
63293c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_X2APIC);
63366a6950fSSean Christopherson
63466a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_1_EDX,
63566a6950fSSean Christopherson F(FPU) | F(VME) | F(DE) | F(PSE) |
63666a6950fSSean Christopherson F(TSC) | F(MSR) | F(PAE) | F(MCE) |
63766a6950fSSean Christopherson F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) |
63866a6950fSSean Christopherson F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
63966a6950fSSean Christopherson F(PAT) | F(PSE36) | 0 /* PSN */ | F(CLFLUSH) |
64066a6950fSSean Christopherson 0 /* Reserved, DS, ACPI */ | F(MMX) |
64166a6950fSSean Christopherson F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) |
64266a6950fSSean Christopherson 0 /* HTT, TM, Reserved, PBE */
64366a6950fSSean Christopherson );
64466a6950fSSean Christopherson
64566a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_7_0_EBX,
646e3bcfda0SJim Mattson F(FSGSBASE) | F(SGX) | F(BMI1) | F(HLE) | F(AVX2) |
647e3bcfda0SJim Mattson F(FDP_EXCPTN_ONLY) | F(SMEP) | F(BMI2) | F(ERMS) | F(INVPCID) |
648e3bcfda0SJim Mattson F(RTM) | F(ZERO_FCS_FDS) | 0 /*MPX*/ | F(AVX512F) |
649e3bcfda0SJim Mattson F(AVX512DQ) | F(RDSEED) | F(ADX) | F(SMAP) | F(AVX512IFMA) |
650e3bcfda0SJim Mattson F(CLFLUSHOPT) | F(CLWB) | 0 /*INTEL_PT*/ | F(AVX512PF) |
651e3bcfda0SJim Mattson F(AVX512ER) | F(AVX512CD) | F(SHA_NI) | F(AVX512BW) |
652e3bcfda0SJim Mattson F(AVX512VL));
65366a6950fSSean Christopherson
65466a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_7_ECX,
655fa44b82eSBabu Moger F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
65666a6950fSSean Christopherson F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
65766a6950fSSean Christopherson F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
65872add915SSean Christopherson F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/ |
65976ea438bSPaolo Bonzini F(SGX_LC) | F(BUS_LOCK_DETECT)
66066a6950fSSean Christopherson );
66166a6950fSSean Christopherson /* Set LA57 based on hardware capability. */
66266a6950fSSean Christopherson if (cpuid_ecx(7) & F(LA57))
66366a6950fSSean Christopherson kvm_cpu_cap_set(X86_FEATURE_LA57);
66466a6950fSSean Christopherson
665fa44b82eSBabu Moger /*
666fa44b82eSBabu Moger * PKU not yet implemented for shadow paging and requires OSPKE
667fa44b82eSBabu Moger * to be set on the host. Clear it if that is not the case
668fa44b82eSBabu Moger */
669fa44b82eSBabu Moger if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE))
670fa44b82eSBabu Moger kvm_cpu_cap_clear(X86_FEATURE_PKU);
671fa44b82eSBabu Moger
67266a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_7_EDX,
67366a6950fSSean Christopherson F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) |
67466a6950fSSean Christopherson F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES) | F(INTEL_STIBP) |
67543bd9ef4SPaolo Bonzini F(MD_CLEAR) | F(AVX512_VP2INTERSECT) | F(FSRM) |
676690a757dSJing Liu F(SERIALIZE) | F(TSXLDTRK) | F(AVX512_FP16) |
67745cf86f2SEmanuele Giuseppe Esposito F(AMX_TILE) | F(AMX_INT8) | F(AMX_BF16) | F(FLUSH_L1D)
67866a6950fSSean Christopherson );
67966a6950fSSean Christopherson
68093c380e7SSean Christopherson /* TSC_ADJUST and ARCH_CAPABILITIES are emulated in software. */
68193c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_TSC_ADJUST);
68293c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_ARCH_CAPABILITIES);
68393c380e7SSean Christopherson
68493c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_IBPB) && boot_cpu_has(X86_FEATURE_IBRS))
68593c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_SPEC_CTRL);
68693c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_STIBP))
68793c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_INTEL_STIBP);
68893c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_AMD_SSBD))
68993c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_SPEC_CTRL_SSBD);
69093c380e7SSean Christopherson
69166a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_7_1_EAX,
6922a4209d6SJim Mattson F(AVX_VNNI) | F(AVX512_BF16) | F(CMPCCXADD) |
6932a4209d6SJim Mattson F(FZRM) | F(FSRS) | F(FSRC) |
6942a4209d6SJim Mattson F(AMX_FP16) | F(AVX_IFMA)
69566a6950fSSean Christopherson );
69666a6950fSSean Christopherson
69724d74b9fSJiaxi Chen kvm_cpu_cap_init_kvm_defined(CPUID_7_1_EDX,
69899b66854STao Su F(AVX_VNNI_INT8) | F(AVX_NE_CONVERT) | F(PREFETCHITI) |
69999b66854STao Su F(AMX_COMPLEX)
70066a6950fSSean Christopherson );
70166a6950fSSean Christopherson
702688313fbSJim Mattson kvm_cpu_cap_init_kvm_defined(CPUID_7_2_EDX,
703688313fbSJim Mattson F(INTEL_PSFD) | F(IPRED_CTRL) | F(RRSBA_CTRL) | F(DDPD_U) |
704688313fbSJim Mattson F(BHI_CTRL) | F(MCDT_NO)
705688313fbSJim Mattson );
706688313fbSJim Mattson
70766a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_D_1_EAX,
708690a757dSJing Liu F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | F(XSAVES) | f_xfd
70966a6950fSSean Christopherson );
71066a6950fSSean Christopherson
711047c7229SSean Christopherson kvm_cpu_cap_init_kvm_defined(CPUID_12_EAX,
71216a7fe37SKai Huang SF(SGX1) | SF(SGX2) | SF(SGX_EDECCSSA)
71372add915SSean Christopherson );
71472add915SSean Christopherson
71566a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_8000_0001_ECX,
71666a6950fSSean Christopherson F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ |
71766a6950fSSean Christopherson F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) |
71866a6950fSSean Christopherson F(3DNOWPREFETCH) | F(OSVW) | 0 /* IBS */ | F(XOP) |
71966a6950fSSean Christopherson 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM) |
720b1d66dadSLike Xu F(TOPOEXT) | 0 /* PERFCTR_CORE */
72166a6950fSSean Christopherson );
72266a6950fSSean Christopherson
72366a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_8000_0001_EDX,
72466a6950fSSean Christopherson F(FPU) | F(VME) | F(DE) | F(PSE) |
72566a6950fSSean Christopherson F(TSC) | F(MSR) | F(PAE) | F(MCE) |
72666a6950fSSean Christopherson F(CX8) | F(APIC) | 0 /* Reserved */ | F(SYSCALL) |
72766a6950fSSean Christopherson F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
72866a6950fSSean Christopherson F(PAT) | F(PSE36) | 0 /* Reserved */ |
7291383279cSSean Christopherson F(NX) | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
73066a6950fSSean Christopherson F(FXSR) | F(FXSR_OPT) | f_gbpages | F(RDTSCP) |
73166a6950fSSean Christopherson 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW)
73266a6950fSSean Christopherson );
73366a6950fSSean Christopherson
73466a6950fSSean Christopherson if (!tdp_enabled && IS_ENABLED(CONFIG_X86_64))
73566a6950fSSean Christopherson kvm_cpu_cap_set(X86_FEATURE_GBPAGES);
73666a6950fSSean Christopherson
7370fcf86f0SVitaly Kuznetsov kvm_cpu_cap_init_kvm_defined(CPUID_8000_0007_EDX,
7380fcf86f0SVitaly Kuznetsov SF(CONSTANT_TSC)
7390fcf86f0SVitaly Kuznetsov );
7400fcf86f0SVitaly Kuznetsov
74166a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_8000_0008_EBX,
74266a6950fSSean Christopherson F(CLZERO) | F(XSAVEERPTR) |
74366a6950fSSean Christopherson F(WBNOINVD) | F(AMD_IBPB) | F(AMD_IBRS) | F(AMD_SSBD) | F(VIRT_SSBD) |
744b73a5432SBabu Moger F(AMD_SSB_NO) | F(AMD_STIBP) | F(AMD_STIBP_ALWAYS_ON) |
7453d8f61bfSSean Christopherson F(AMD_PSFD)
74666a6950fSSean Christopherson );
74766a6950fSSean Christopherson
7489b58b985SSean Christopherson /*
74993c380e7SSean Christopherson * AMD has separate bits for each SPEC_CTRL bit.
75093c380e7SSean Christopherson * arch/x86/kernel/cpu/bugs.c is kind enough to
75193c380e7SSean Christopherson * record that in cpufeatures so use them.
75293c380e7SSean Christopherson */
75393c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_IBPB))
75493c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_AMD_IBPB);
75593c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_IBRS))
75693c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_AMD_IBRS);
75793c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_STIBP))
75893c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_AMD_STIBP);
75993c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD))
76093c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_AMD_SSBD);
76193c380e7SSean Christopherson if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS))
76293c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_AMD_SSB_NO);
76393c380e7SSean Christopherson /*
76493c380e7SSean Christopherson * The preference is to use SPEC CTRL MSR instead of the
76593c380e7SSean Christopherson * VIRT_SPEC MSR.
76693c380e7SSean Christopherson */
76793c380e7SSean Christopherson if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD) &&
76893c380e7SSean Christopherson !boot_cpu_has(X86_FEATURE_AMD_SSBD))
76993c380e7SSean Christopherson kvm_cpu_cap_set(X86_FEATURE_VIRT_SSBD);
77093c380e7SSean Christopherson
77193c380e7SSean Christopherson /*
7729b58b985SSean Christopherson * Hide all SVM features by default, SVM will set the cap bits for
7739b58b985SSean Christopherson * features it emulates and/or exposes for L1.
7749b58b985SSean Christopherson */
7759b58b985SSean Christopherson kvm_cpu_cap_mask(CPUID_8000_000A_EDX, 0);
7769b58b985SSean Christopherson
777d9db0fd6SPaolo Bonzini kvm_cpu_cap_mask(CPUID_8000_001F_EAX,
778d9db0fd6SPaolo Bonzini 0 /* SME */ | F(SEV) | 0 /* VM_PAGE_FLUSH */ | F(SEV_ES) |
779d9db0fd6SPaolo Bonzini F(SME_COHERENT));
780d9db0fd6SPaolo Bonzini
781c35ac8c4SKim Phillips kvm_cpu_cap_mask(CPUID_8000_0021_EAX,
78284168ae7SKim Phillips F(NO_NESTED_DATA_BP) | F(LFENCE_RDTSC) | 0 /* SmmPgCfgLock */ |
7838c19b6f2SKim Phillips F(NULL_SEL_CLR_BASE) | F(AUTOIBRS) | 0 /* PrefetchCtlMsr */
784c35ac8c4SKim Phillips );
78584168ae7SKim Phillips
7861b5277c0SBorislav Petkov (AMD) if (cpu_feature_enabled(X86_FEATURE_SRSO_NO))
7871b5277c0SBorislav Petkov (AMD) kvm_cpu_cap_set(X86_FEATURE_SRSO_NO);
7881b5277c0SBorislav Petkov (AMD)
78994cdeebdSLike Xu kvm_cpu_cap_init_kvm_defined(CPUID_8000_0022_EAX,
79094cdeebdSLike Xu F(PERFMON_V2)
79194cdeebdSLike Xu );
79294cdeebdSLike Xu
79384168ae7SKim Phillips /*
79484168ae7SKim Phillips * Synthesize "LFENCE is serializing" into the AMD-defined entry in
79584168ae7SKim Phillips * KVM's supported CPUID if the feature is reported as supported by the
79684168ae7SKim Phillips * kernel. LFENCE_RDTSC was a Linux-defined synthetic feature long
79784168ae7SKim Phillips * before AMD joined the bandwagon, e.g. LFENCE is serializing on most
79884168ae7SKim Phillips * CPUs that support SSE2. On CPUs that don't support AMD's leaf,
79984168ae7SKim Phillips * kvm_cpu_cap_mask() will unfortunately drop the flag due to ANDing
80084168ae7SKim Phillips * the mask with the raw host CPUID, and reporting support in AMD's
80184168ae7SKim Phillips * leaf can make it easier for userspace to detect the feature.
80284168ae7SKim Phillips */
803c35ac8c4SKim Phillips if (cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC))
80484168ae7SKim Phillips kvm_cpu_cap_set(X86_FEATURE_LFENCE_RDTSC);
805c35ac8c4SKim Phillips if (!static_cpu_has_bug(X86_BUG_NULL_SEG))
8065b909d4aSKim Phillips kvm_cpu_cap_set(X86_FEATURE_NULL_SEL_CLR_BASE);
807faabfcb1SKim Phillips kvm_cpu_cap_set(X86_FEATURE_NO_SMM_CTL_MSR);
808c35ac8c4SKim Phillips
80966a6950fSSean Christopherson kvm_cpu_cap_mask(CPUID_C000_0001_EDX,
81066a6950fSSean Christopherson F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
81166a6950fSSean Christopherson F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) |
81266a6950fSSean Christopherson F(PMM) | F(PMM_EN)
81366a6950fSSean Christopherson );
81478bba966SSean Christopherson
81578bba966SSean Christopherson /*
81678bba966SSean Christopherson * Hide RDTSCP and RDPID if either feature is reported as supported but
81778bba966SSean Christopherson * probing MSR_TSC_AUX failed. This is purely a sanity check and
81878bba966SSean Christopherson * should never happen, but the guest will likely crash if RDTSCP or
81978bba966SSean Christopherson * RDPID is misreported, and KVM has botched MSR_TSC_AUX emulation in
82078bba966SSean Christopherson * the past. For example, the sanity check may fire if this instance of
82178bba966SSean Christopherson * KVM is running as L1 on top of an older, broken KVM.
82278bba966SSean Christopherson */
82378bba966SSean Christopherson if (WARN_ON((kvm_cpu_cap_has(X86_FEATURE_RDTSCP) ||
82478bba966SSean Christopherson kvm_cpu_cap_has(X86_FEATURE_RDPID)) &&
82578bba966SSean Christopherson !kvm_is_supported_user_return_msr(MSR_TSC_AUX))) {
82678bba966SSean Christopherson kvm_cpu_cap_clear(X86_FEATURE_RDTSCP);
82778bba966SSean Christopherson kvm_cpu_cap_clear(X86_FEATURE_RDPID);
82878bba966SSean Christopherson }
82966a6950fSSean Christopherson }
83066a6950fSSean Christopherson EXPORT_SYMBOL_GPL(kvm_set_cpu_caps);
83166a6950fSSean Christopherson
832e53c95e8SSean Christopherson struct kvm_cpuid_array {
833e53c95e8SSean Christopherson struct kvm_cpuid_entry2 *entries;
83465b18914SXiaoyao Li int maxnent;
835e53c95e8SSean Christopherson int nent;
836e53c95e8SSean Christopherson };
837e53c95e8SSean Christopherson
get_next_cpuid(struct kvm_cpuid_array * array)83845e966fcSPaolo Bonzini static struct kvm_cpuid_entry2 *get_next_cpuid(struct kvm_cpuid_array *array)
83900b27a3eSAvi Kivity {
840e53c95e8SSean Christopherson if (array->nent >= array->maxnent)
841aa10a7dcSSean Christopherson return NULL;
842e53c95e8SSean Christopherson
84345e966fcSPaolo Bonzini return &array->entries[array->nent++];
84445e966fcSPaolo Bonzini }
84545e966fcSPaolo Bonzini
do_host_cpuid(struct kvm_cpuid_array * array,u32 function,u32 index)84645e966fcSPaolo Bonzini static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
84745e966fcSPaolo Bonzini u32 function, u32 index)
84845e966fcSPaolo Bonzini {
84945e966fcSPaolo Bonzini struct kvm_cpuid_entry2 *entry = get_next_cpuid(array);
85045e966fcSPaolo Bonzini
85145e966fcSPaolo Bonzini if (!entry)
85245e966fcSPaolo Bonzini return NULL;
853aa10a7dcSSean Christopherson
8542746a6b7SPaolo Bonzini memset(entry, 0, sizeof(*entry));
85500b27a3eSAvi Kivity entry->function = function;
85600b27a3eSAvi Kivity entry->index = index;
8572746a6b7SPaolo Bonzini switch (function & 0xC0000000) {
8582746a6b7SPaolo Bonzini case 0x40000000:
8592746a6b7SPaolo Bonzini /* Hypervisor leaves are always synthesized by __do_cpuid_func. */
8602746a6b7SPaolo Bonzini return entry;
8612746a6b7SPaolo Bonzini
862f144c49eSPaolo Bonzini case 0x80000000:
863f144c49eSPaolo Bonzini /*
864f144c49eSPaolo Bonzini * 0x80000021 is sometimes synthesized by __do_cpuid_func, which
865f144c49eSPaolo Bonzini * would result in out-of-bounds calls to do_host_cpuid.
866f144c49eSPaolo Bonzini */
867f144c49eSPaolo Bonzini {
868f144c49eSPaolo Bonzini static int max_cpuid_80000000;
869f144c49eSPaolo Bonzini if (!READ_ONCE(max_cpuid_80000000))
870f144c49eSPaolo Bonzini WRITE_ONCE(max_cpuid_80000000, cpuid_eax(0x80000000));
871f144c49eSPaolo Bonzini if (function > READ_ONCE(max_cpuid_80000000))
872f144c49eSPaolo Bonzini return entry;
873f144c49eSPaolo Bonzini }
87407ea4ab1SNathan Chancellor break;
875f144c49eSPaolo Bonzini
8762746a6b7SPaolo Bonzini default:
8772746a6b7SPaolo Bonzini break;
8782746a6b7SPaolo Bonzini }
879ab8bcf64SPaolo Bonzini
88000b27a3eSAvi Kivity cpuid_count(entry->function, entry->index,
88100b27a3eSAvi Kivity &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
882d9aadaf6SPaolo Bonzini
883b66370dbSMichael Roth if (cpuid_function_is_indexed(function))
884d9aadaf6SPaolo Bonzini entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
885aa10a7dcSSean Christopherson
886aa10a7dcSSean Christopherson return entry;
88700b27a3eSAvi Kivity }
88800b27a3eSAvi Kivity
__do_cpuid_func_emulated(struct kvm_cpuid_array * array,u32 func)889e53c95e8SSean Christopherson static int __do_cpuid_func_emulated(struct kvm_cpuid_array *array, u32 func)
8909c15bb1dSBorislav Petkov {
8917c7f9548SSean Christopherson struct kvm_cpuid_entry2 *entry;
892e53c95e8SSean Christopherson
8937c7f9548SSean Christopherson if (array->nent >= array->maxnent)
8947c7f9548SSean Christopherson return -E2BIG;
8957c7f9548SSean Christopherson
8967c7f9548SSean Christopherson entry = &array->entries[array->nent];
897ab8bcf64SPaolo Bonzini entry->function = func;
898ab8bcf64SPaolo Bonzini entry->index = 0;
899ab8bcf64SPaolo Bonzini entry->flags = 0;
900ab8bcf64SPaolo Bonzini
90184cffe49SBorislav Petkov switch (func) {
90284cffe49SBorislav Petkov case 0:
903fb6d4d34SPaolo Bonzini entry->eax = 7;
904e53c95e8SSean Christopherson ++array->nent;
90584cffe49SBorislav Petkov break;
90684cffe49SBorislav Petkov case 1:
90784cffe49SBorislav Petkov entry->ecx = F(MOVBE);
908e53c95e8SSean Christopherson ++array->nent;
90984cffe49SBorislav Petkov break;
910fb6d4d34SPaolo Bonzini case 7:
911fb6d4d34SPaolo Bonzini entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
912ab8bcf64SPaolo Bonzini entry->eax = 0;
91385d00112SSean Christopherson if (kvm_cpu_cap_has(X86_FEATURE_RDTSCP))
914fb6d4d34SPaolo Bonzini entry->ecx = F(RDPID);
915e53c95e8SSean Christopherson ++array->nent;
916551912d2SGustavo A. R. Silva break;
91784cffe49SBorislav Petkov default:
91884cffe49SBorislav Petkov break;
91984cffe49SBorislav Petkov }
92084cffe49SBorislav Petkov
9219c15bb1dSBorislav Petkov return 0;
9229c15bb1dSBorislav Petkov }
9239c15bb1dSBorislav Petkov
__do_cpuid_func(struct kvm_cpuid_array * array,u32 function)924e53c95e8SSean Christopherson static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
92500b27a3eSAvi Kivity {
926e53c95e8SSean Christopherson struct kvm_cpuid_entry2 *entry;
92774fa0bc7SSean Christopherson int r, i, max_idx;
92800b27a3eSAvi Kivity
92900b27a3eSAvi Kivity /* all calls to cpuid_count() should be made on the same cpu */
93000b27a3eSAvi Kivity get_cpu();
931831bf664SSasha Levin
932831bf664SSasha Levin r = -E2BIG;
933831bf664SSasha Levin
934e53c95e8SSean Christopherson entry = do_host_cpuid(array, function, 0);
9357c7f9548SSean Christopherson if (!entry)
936831bf664SSasha Levin goto out;
937831bf664SSasha Levin
93800b27a3eSAvi Kivity switch (function) {
93900b27a3eSAvi Kivity case 0:
940a87f2d3aSLike Xu /* Limited to the highest leaf implemented in KVM. */
941a87f2d3aSLike Xu entry->eax = min(entry->eax, 0x1fU);
94200b27a3eSAvi Kivity break;
94300b27a3eSAvi Kivity case 1:
944bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_1_EDX);
945bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_1_ECX);
94600b27a3eSAvi Kivity break;
94774fa0bc7SSean Christopherson case 2:
948c571a144SSean Christopherson /*
949c571a144SSean Christopherson * On ancient CPUs, function 2 entries are STATEFUL. That is,
950c571a144SSean Christopherson * CPUID(function=2, index=0) may return different results each
951c571a144SSean Christopherson * time, with the least-significant byte in EAX enumerating the
952c571a144SSean Christopherson * number of times software should do CPUID(2, 0).
953c571a144SSean Christopherson *
9547ff6c035SSean Christopherson * Modern CPUs, i.e. every CPU KVM has *ever* run on are less
9557ff6c035SSean Christopherson * idiotic. Intel's SDM states that EAX & 0xff "will always
9567ff6c035SSean Christopherson * return 01H. Software should ignore this value and not
957c571a144SSean Christopherson * interpret it as an informational descriptor", while AMD's
958c571a144SSean Christopherson * APM states that CPUID(2) is reserved.
9597ff6c035SSean Christopherson *
9607ff6c035SSean Christopherson * WARN if a frankenstein CPU that supports virtualization and
9617ff6c035SSean Christopherson * a stateful CPUID.0x2 is encountered.
962c571a144SSean Christopherson */
9637ff6c035SSean Christopherson WARN_ON_ONCE((entry->eax & 0xff) > 1);
96400b27a3eSAvi Kivity break;
96532a243dfSJim Mattson /* functions 4 and 0x8000001d have additional index. */
96632a243dfSJim Mattson case 4:
967c8629039SSean Christopherson case 0x8000001d:
968c8629039SSean Christopherson /*
969c8629039SSean Christopherson * Read entries until the cache type in the previous entry is
970c8629039SSean Christopherson * zero, i.e. indicates an invalid entry.
971c8629039SSean Christopherson */
972e53c95e8SSean Christopherson for (i = 1; entry->eax & 0x1f; ++i) {
973e53c95e8SSean Christopherson entry = do_host_cpuid(array, function, i);
974e53c95e8SSean Christopherson if (!entry)
9750fc62671SSean Christopherson goto out;
97600b27a3eSAvi Kivity }
97700b27a3eSAvi Kivity break;
978e453aa0fSJan Kiszka case 6: /* Thermal management */
979e453aa0fSJan Kiszka entry->eax = 0x4; /* allow ARAT */
980e453aa0fSJan Kiszka entry->ebx = 0;
981e453aa0fSJan Kiszka entry->ecx = 0;
982e453aa0fSJan Kiszka entry->edx = 0;
983e453aa0fSJan Kiszka break;
98454d360d4SPaolo Bonzini /* function 7 has additional index. */
98574fa0bc7SSean Christopherson case 7:
986688313fbSJim Mattson max_idx = entry->eax = min(entry->eax, 2u);
987bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_7_0_EBX);
988bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_7_ECX);
989bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_7_EDX);
99009f628a0SSean Christopherson
991688313fbSJim Mattson /* KVM only supports up to 0x7.2, capped above via min(). */
992688313fbSJim Mattson if (max_idx >= 1) {
993bcf600caSSean Christopherson entry = do_host_cpuid(array, function, 1);
994e53c95e8SSean Christopherson if (!entry)
99554d360d4SPaolo Bonzini goto out;
99654d360d4SPaolo Bonzini
997bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_7_1_EAX);
99824d74b9fSJiaxi Chen cpuid_entry_override(entry, CPUID_7_1_EDX);
99909f628a0SSean Christopherson entry->ebx = 0;
100009f628a0SSean Christopherson entry->ecx = 0;
100154d360d4SPaolo Bonzini }
1002688313fbSJim Mattson if (max_idx >= 2) {
1003688313fbSJim Mattson entry = do_host_cpuid(array, function, 2);
1004688313fbSJim Mattson if (!entry)
1005688313fbSJim Mattson goto out;
1006688313fbSJim Mattson
1007688313fbSJim Mattson cpuid_entry_override(entry, CPUID_7_2_EDX);
1008688313fbSJim Mattson entry->ecx = 0;
1009688313fbSJim Mattson entry->ebx = 0;
1010688313fbSJim Mattson entry->eax = 0;
1011688313fbSJim Mattson }
101200b27a3eSAvi Kivity break;
1013a6c06ed1SGleb Natapov case 0xa: { /* Architectural Performance Monitoring */
1014a6c06ed1SGleb Natapov union cpuid10_eax eax;
1015a6c06ed1SGleb Natapov union cpuid10_edx edx;
1016a6c06ed1SGleb Natapov
10176593039dSLike Xu if (!enable_pmu || !static_cpu_has(X86_FEATURE_ARCH_PERFMON)) {
10185a1bde46SSandipan Das entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
10195a1bde46SSandipan Das break;
10205a1bde46SSandipan Das }
10215a1bde46SSandipan Das
1022968635abSLike Xu eax.split.version_id = kvm_pmu_cap.version;
1023968635abSLike Xu eax.split.num_counters = kvm_pmu_cap.num_counters_gp;
1024968635abSLike Xu eax.split.bit_width = kvm_pmu_cap.bit_width_gp;
1025968635abSLike Xu eax.split.mask_length = kvm_pmu_cap.events_mask_len;
1026968635abSLike Xu edx.split.num_counters_fixed = kvm_pmu_cap.num_counters_fixed;
1027968635abSLike Xu edx.split.bit_width_fixed = kvm_pmu_cap.bit_width_fixed;
1028a6c06ed1SGleb Natapov
1029968635abSLike Xu if (kvm_pmu_cap.version)
1030cadbaa03SStephane Eranian edx.split.anythread_deprecated = 1;
1031cadbaa03SStephane Eranian edx.split.reserved1 = 0;
1032cadbaa03SStephane Eranian edx.split.reserved2 = 0;
1033a6c06ed1SGleb Natapov
1034a6c06ed1SGleb Natapov entry->eax = eax.full;
1035968635abSLike Xu entry->ebx = kvm_pmu_cap.events_mask;
1036a6c06ed1SGleb Natapov entry->ecx = 0;
1037a6c06ed1SGleb Natapov entry->edx = edx.full;
1038a6c06ed1SGleb Natapov break;
1039a6c06ed1SGleb Natapov }
1040a87f2d3aSLike Xu case 0x1f:
104174fa0bc7SSean Christopherson case 0xb:
1042a1a640b8SJim Mattson /*
104345e966fcSPaolo Bonzini * No topology; a valid topology is indicated by the presence
104445e966fcSPaolo Bonzini * of subleaf 1.
1045a1a640b8SJim Mattson */
104645e966fcSPaolo Bonzini entry->eax = entry->ebx = entry->ecx = 0;
104700b27a3eSAvi Kivity break;
1048445ecdf7SJing Liu case 0xd: {
10496be3ae45SAaron Lewis u64 permitted_xcr0 = kvm_get_filtered_xcr0();
1050938c8745SSean Christopherson u64 permitted_xss = kvm_caps.supported_xss;
1051445ecdf7SJing Liu
10521ffce092SLike Xu entry->eax &= permitted_xcr0;
10531ffce092SLike Xu entry->ebx = xstate_required_size(permitted_xcr0, false);
1054e08e8336SRadim Krčmář entry->ecx = entry->ebx;
10551ffce092SLike Xu entry->edx &= permitted_xcr0 >> 32;
10561ffce092SLike Xu if (!permitted_xcr0)
1057b65d6e17SPaolo Bonzini break;
1058b65d6e17SPaolo Bonzini
1059e53c95e8SSean Christopherson entry = do_host_cpuid(array, function, 1);
1060e53c95e8SSean Christopherson if (!entry)
10613dc4a9cfSSean Christopherson goto out;
10623dc4a9cfSSean Christopherson
1063bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_D_1_EAX);
1064e53c95e8SSean Christopherson if (entry->eax & (F(XSAVES)|F(XSAVEC)))
10651ffce092SLike Xu entry->ebx = xstate_required_size(permitted_xcr0 | permitted_xss,
1066408e9a31SPaolo Bonzini true);
1067408e9a31SPaolo Bonzini else {
10681ffce092SLike Xu WARN_ON_ONCE(permitted_xss != 0);
1069e53c95e8SSean Christopherson entry->ebx = 0;
1070408e9a31SPaolo Bonzini }
10711ffce092SLike Xu entry->ecx &= permitted_xss;
10721ffce092SLike Xu entry->edx &= permitted_xss >> 32;
10733dc4a9cfSSean Christopherson
10740eee8f9dSSean Christopherson for (i = 2; i < 64; ++i) {
1075408e9a31SPaolo Bonzini bool s_state;
10761ffce092SLike Xu if (permitted_xcr0 & BIT_ULL(i))
1077408e9a31SPaolo Bonzini s_state = false;
10781ffce092SLike Xu else if (permitted_xss & BIT_ULL(i))
1079408e9a31SPaolo Bonzini s_state = true;
1080408e9a31SPaolo Bonzini else
10811893c941SSean Christopherson continue;
10823dc4a9cfSSean Christopherson
10830eee8f9dSSean Christopherson entry = do_host_cpuid(array, function, i);
1084e53c95e8SSean Christopherson if (!entry)
1085831bf664SSasha Levin goto out;
1086831bf664SSasha Levin
108791001d40SSean Christopherson /*
1088cfc48181SSean Christopherson * The supported check above should have filtered out
1089408e9a31SPaolo Bonzini * invalid sub-leafs. Only valid sub-leafs should
109091001d40SSean Christopherson * reach this point, and they should have a non-zero
1091408e9a31SPaolo Bonzini * save state size. Furthermore, check whether the
10921ffce092SLike Xu * processor agrees with permitted_xcr0/permitted_xss
1093408e9a31SPaolo Bonzini * on whether this is an XCR0- or IA32_XSS-managed area.
109491001d40SSean Christopherson */
1095408e9a31SPaolo Bonzini if (WARN_ON_ONCE(!entry->eax || (entry->ecx & 0x1) != s_state)) {
1096e53c95e8SSean Christopherson --array->nent;
109700b27a3eSAvi Kivity continue;
10988b2fc445SSean Christopherson }
1099e9737468SLike Xu
1100e9737468SLike Xu if (!kvm_cpu_cap_has(X86_FEATURE_XFD))
1101e9737468SLike Xu entry->ecx &= ~BIT_ULL(2);
1102e53c95e8SSean Christopherson entry->edx = 0;
110300b27a3eSAvi Kivity }
110400b27a3eSAvi Kivity break;
1105445ecdf7SJing Liu }
110672add915SSean Christopherson case 0x12:
110772add915SSean Christopherson /* Intel SGX */
110872add915SSean Christopherson if (!kvm_cpu_cap_has(X86_FEATURE_SGX)) {
110972add915SSean Christopherson entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
111072add915SSean Christopherson break;
111172add915SSean Christopherson }
111272add915SSean Christopherson
111372add915SSean Christopherson /*
111472add915SSean Christopherson * Index 0: Sub-features, MISCSELECT (a.k.a extended features)
111572add915SSean Christopherson * and max enclave sizes. The SGX sub-features and MISCSELECT
111672add915SSean Christopherson * are restricted by kernel and KVM capabilities (like most
111772add915SSean Christopherson * feature flags), while enclave size is unrestricted.
111872add915SSean Christopherson */
111972add915SSean Christopherson cpuid_entry_override(entry, CPUID_12_EAX);
112072add915SSean Christopherson entry->ebx &= SGX_MISC_EXINFO;
112172add915SSean Christopherson
112272add915SSean Christopherson entry = do_host_cpuid(array, function, 1);
112372add915SSean Christopherson if (!entry)
112472add915SSean Christopherson goto out;
112572add915SSean Christopherson
112672add915SSean Christopherson /*
112772add915SSean Christopherson * Index 1: SECS.ATTRIBUTES. ATTRIBUTES are restricted a la
112872add915SSean Christopherson * feature flags. Advertise all supported flags, including
112972add915SSean Christopherson * privileged attributes that require explicit opt-in from
113072add915SSean Christopherson * userspace. ATTRIBUTES.XFRM is not adjusted as userspace is
113172add915SSean Christopherson * expected to derive it from supported XCR0.
113272add915SSean Christopherson */
1133370839c2SDave Hansen entry->eax &= SGX_ATTR_PRIV_MASK | SGX_ATTR_UNPRIV_MASK;
113472add915SSean Christopherson entry->ebx &= 0;
113572add915SSean Christopherson break;
113686f5201dSChao Peng /* Intel PT */
113774fa0bc7SSean Christopherson case 0x14:
1138dd69cc25SSean Christopherson if (!kvm_cpu_cap_has(X86_FEATURE_INTEL_PT)) {
11397392079cSSean Christopherson entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
114086f5201dSChao Peng break;
11417392079cSSean Christopherson }
114286f5201dSChao Peng
114374fa0bc7SSean Christopherson for (i = 1, max_idx = entry->eax; i <= max_idx; ++i) {
1144e53c95e8SSean Christopherson if (!do_host_cpuid(array, function, i))
114586f5201dSChao Peng goto out;
114686f5201dSChao Peng }
114786f5201dSChao Peng break;
1148690a757dSJing Liu /* Intel AMX TILE */
1149690a757dSJing Liu case 0x1d:
1150690a757dSJing Liu if (!kvm_cpu_cap_has(X86_FEATURE_AMX_TILE)) {
1151690a757dSJing Liu entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
1152690a757dSJing Liu break;
1153690a757dSJing Liu }
1154690a757dSJing Liu
1155690a757dSJing Liu for (i = 1, max_idx = entry->eax; i <= max_idx; ++i) {
1156690a757dSJing Liu if (!do_host_cpuid(array, function, i))
1157690a757dSJing Liu goto out;
1158690a757dSJing Liu }
1159690a757dSJing Liu break;
1160690a757dSJing Liu case 0x1e: /* TMUL information */
1161690a757dSJing Liu if (!kvm_cpu_cap_has(X86_FEATURE_AMX_TILE)) {
1162690a757dSJing Liu entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
1163690a757dSJing Liu break;
1164690a757dSJing Liu }
1165690a757dSJing Liu break;
116600b27a3eSAvi Kivity case KVM_CPUID_SIGNATURE: {
1167760849b1SPaul Durrant const u32 *sigptr = (const u32 *)KVM_SIGNATURE;
116857c22e5fSMichael S. Tsirkin entry->eax = KVM_CPUID_FEATURES;
116900b27a3eSAvi Kivity entry->ebx = sigptr[0];
117000b27a3eSAvi Kivity entry->ecx = sigptr[1];
117100b27a3eSAvi Kivity entry->edx = sigptr[2];
117200b27a3eSAvi Kivity break;
117300b27a3eSAvi Kivity }
117400b27a3eSAvi Kivity case KVM_CPUID_FEATURES:
117500b27a3eSAvi Kivity entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) |
117600b27a3eSAvi Kivity (1 << KVM_FEATURE_NOP_IO_DELAY) |
117700b27a3eSAvi Kivity (1 << KVM_FEATURE_CLOCKSOURCE2) |
117800b27a3eSAvi Kivity (1 << KVM_FEATURE_ASYNC_PF) |
1179ae7a2a3fSMichael S. Tsirkin (1 << KVM_FEATURE_PV_EOI) |
11806aef266cSSrivatsa Vaddagiri (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
1181f38a7b75SWanpeng Li (1 << KVM_FEATURE_PV_UNHALT) |
1182fe2a3027SRadim Krčmář (1 << KVM_FEATURE_PV_TLB_FLUSH) |
11834180bf1bSWanpeng Li (1 << KVM_FEATURE_ASYNC_PF_VMEXIT) |
11842d5ba19bSMarcelo Tosatti (1 << KVM_FEATURE_PV_SEND_IPI) |
118532b72eccSWanpeng Li (1 << KVM_FEATURE_POLL_CONTROL) |
118672de5fa4SVitaly Kuznetsov (1 << KVM_FEATURE_PV_SCHED_YIELD) |
118772de5fa4SVitaly Kuznetsov (1 << KVM_FEATURE_ASYNC_PF_INT);
118800b27a3eSAvi Kivity
118900b27a3eSAvi Kivity if (sched_info_on())
119000b27a3eSAvi Kivity entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
119100b27a3eSAvi Kivity
119200b27a3eSAvi Kivity entry->ebx = 0;
119300b27a3eSAvi Kivity entry->ecx = 0;
119400b27a3eSAvi Kivity entry->edx = 0;
119500b27a3eSAvi Kivity break;
119600b27a3eSAvi Kivity case 0x80000000:
119794cdeebdSLike Xu entry->eax = min(entry->eax, 0x80000022);
1198f144c49eSPaolo Bonzini /*
1199f751d8eaSPaolo Bonzini * Serializing LFENCE is reported in a multitude of ways, and
1200f751d8eaSPaolo Bonzini * NullSegClearsBase is not reported in CPUID on Zen2; help
1201f751d8eaSPaolo Bonzini * userspace by providing the CPUID leaf ourselves.
1202f751d8eaSPaolo Bonzini *
1203f751d8eaSPaolo Bonzini * However, only do it if the host has CPUID leaf 0x8000001d.
1204f751d8eaSPaolo Bonzini * QEMU thinks that it can query the host blindly for that
1205f751d8eaSPaolo Bonzini * CPUID leaf if KVM reports that it supports 0x8000001d or
1206f751d8eaSPaolo Bonzini * above. The processor merrily returns values from the
1207f751d8eaSPaolo Bonzini * highest Intel leaf which QEMU tries to use as the guest's
1208f751d8eaSPaolo Bonzini * 0x8000001d. Even worse, this can result in an infinite
1209f751d8eaSPaolo Bonzini * loop if said highest leaf has no subleaves indexed by ECX.
1210f144c49eSPaolo Bonzini */
1211f751d8eaSPaolo Bonzini if (entry->eax >= 0x8000001d &&
1212f751d8eaSPaolo Bonzini (static_cpu_has(X86_FEATURE_LFENCE_RDTSC)
1213f751d8eaSPaolo Bonzini || !static_cpu_has_bug(X86_BUG_NULL_SEG)))
1214f144c49eSPaolo Bonzini entry->eax = max(entry->eax, 0x80000021);
121500b27a3eSAvi Kivity break;
121600b27a3eSAvi Kivity case 0x80000001:
12170469e56aSJim Mattson entry->ebx &= ~GENMASK(27, 16);
1218bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_8000_0001_EDX);
1219bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_8000_0001_ECX);
122000b27a3eSAvi Kivity break;
1221af8e2ccfSTakahiro Itazuri case 0x80000005:
1222af8e2ccfSTakahiro Itazuri /* Pass host L1 cache and TLB info. */
1223af8e2ccfSTakahiro Itazuri break;
122443d05de2SEric Northup case 0x80000006:
1225eeb69eabSJim Mattson /* Drop reserved bits, pass host L2 cache and TLB info. */
1226eeb69eabSJim Mattson entry->edx &= ~GENMASK(17, 16);
122743d05de2SEric Northup break;
1228e4c9a5a1SMarcelo Tosatti case 0x80000007: /* Advanced power management */
12290fcf86f0SVitaly Kuznetsov cpuid_entry_override(entry, CPUID_8000_0007_EDX);
12300fcf86f0SVitaly Kuznetsov
1231e4c9a5a1SMarcelo Tosatti /* mask against host */
1232e4c9a5a1SMarcelo Tosatti entry->edx &= boot_cpu_data.x86_power;
1233e4c9a5a1SMarcelo Tosatti entry->eax = entry->ebx = entry->ecx = 0;
1234e4c9a5a1SMarcelo Tosatti break;
123500b27a3eSAvi Kivity case 0x80000008: {
123666c92af8SGerd Hoffmann unsigned int virt_as = max((entry->eax >> 8) & 0xff, 48U);
123766c92af8SGerd Hoffmann unsigned int phys_as;
123800b27a3eSAvi Kivity
12394bf48e3cSSean Christopherson /*
1240e39f00f6SSean Christopherson * If TDP (NPT) is disabled use the adjusted host MAXPHYADDR as
1241e39f00f6SSean Christopherson * the guest operates in the same PA space as the host, i.e.
1242e39f00f6SSean Christopherson * reductions in MAXPHYADDR for memory encryption affect shadow
1243e39f00f6SSean Christopherson * paging, too.
1244e39f00f6SSean Christopherson *
124566c92af8SGerd Hoffmann * If TDP is enabled, use the raw bare metal MAXPHYADDR as
124666c92af8SGerd Hoffmann * reductions to the HPAs do not affect GPAs.
12474bf48e3cSSean Christopherson */
124866c92af8SGerd Hoffmann if (!tdp_enabled) {
124966c92af8SGerd Hoffmann phys_as = boot_cpu_data.x86_phys_bits;
125066c92af8SGerd Hoffmann } else {
125166c92af8SGerd Hoffmann phys_as = entry->eax & 0xff;
125266c92af8SGerd Hoffmann }
12534bf48e3cSSean Christopherson
125466c92af8SGerd Hoffmann entry->eax = phys_as | (virt_as << 8);
12557030d853SJim Mattson entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
125615d45071SAshok Raj entry->edx = 0;
1257bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_8000_0008_EBX);
125800b27a3eSAvi Kivity break;
125900b27a3eSAvi Kivity }
126025703874SSean Christopherson case 0x8000000A:
126125703874SSean Christopherson if (!kvm_cpu_cap_has(X86_FEATURE_SVM)) {
126225703874SSean Christopherson entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
126325703874SSean Christopherson break;
126425703874SSean Christopherson }
126525703874SSean Christopherson entry->eax = 1; /* SVM revision 1 */
126625703874SSean Christopherson entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper
126725703874SSean Christopherson ASID emulation to nested SVM */
126825703874SSean Christopherson entry->ecx = 0; /* Reserved */
126925703874SSean Christopherson cpuid_entry_override(entry, CPUID_8000_000A_EDX);
127025703874SSean Christopherson break;
127100b27a3eSAvi Kivity case 0x80000019:
127200b27a3eSAvi Kivity entry->ecx = entry->edx = 0;
127300b27a3eSAvi Kivity break;
127400b27a3eSAvi Kivity case 0x8000001a:
1275079f6889SJim Mattson entry->eax &= GENMASK(2, 0);
1276079f6889SJim Mattson entry->ebx = entry->ecx = entry->edx = 0;
1277079f6889SJim Mattson break;
1278382409b4SJim Mattson case 0x8000001e:
127945e966fcSPaolo Bonzini /* Do not return host topology information. */
128045e966fcSPaolo Bonzini entry->eax = entry->ebx = entry->ecx = 0;
128145e966fcSPaolo Bonzini entry->edx = 0; /* reserved */
128200b27a3eSAvi Kivity break;
1283c1de0f25SPeter Gonda case 0x8000001F:
1284e39f00f6SSean Christopherson if (!kvm_cpu_cap_has(X86_FEATURE_SEV)) {
1285c1de0f25SPeter Gonda entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
1286e39f00f6SSean Christopherson } else {
1287d9db0fd6SPaolo Bonzini cpuid_entry_override(entry, CPUID_8000_001F_EAX);
128886c4f0d5SJim Mattson /* Clear NumVMPL since KVM does not support VMPL. */
128986c4f0d5SJim Mattson entry->ebx &= ~GENMASK(31, 12);
1290e39f00f6SSean Christopherson /*
1291e39f00f6SSean Christopherson * Enumerate '0' for "PA bits reduction", the adjusted
1292e39f00f6SSean Christopherson * MAXPHYADDR is enumerated directly (see 0x80000008).
1293e39f00f6SSean Christopherson */
1294e39f00f6SSean Christopherson entry->ebx &= ~GENMASK(11, 6);
1295e39f00f6SSean Christopherson }
1296c1de0f25SPeter Gonda break;
129758b3d12cSPaolo Bonzini case 0x80000020:
129858b3d12cSPaolo Bonzini entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
129958b3d12cSPaolo Bonzini break;
130058b3d12cSPaolo Bonzini case 0x80000021:
130158b3d12cSPaolo Bonzini entry->ebx = entry->ecx = entry->edx = 0;
1302c35ac8c4SKim Phillips cpuid_entry_override(entry, CPUID_8000_0021_EAX);
130358b3d12cSPaolo Bonzini break;
130494cdeebdSLike Xu /* AMD Extended Performance Monitoring and Debug */
130594cdeebdSLike Xu case 0x80000022: {
130694cdeebdSLike Xu union cpuid_0x80000022_ebx ebx;
130794cdeebdSLike Xu
130894cdeebdSLike Xu entry->ecx = entry->edx = 0;
130994cdeebdSLike Xu if (!enable_pmu || !kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2)) {
1310*4f1ca393SXiaoyao Li entry->eax = entry->ebx = 0;
131194cdeebdSLike Xu break;
131294cdeebdSLike Xu }
131394cdeebdSLike Xu
131494cdeebdSLike Xu cpuid_entry_override(entry, CPUID_8000_0022_EAX);
131594cdeebdSLike Xu
131694cdeebdSLike Xu if (kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2))
131794cdeebdSLike Xu ebx.split.num_core_pmc = kvm_pmu_cap.num_counters_gp;
131894cdeebdSLike Xu else if (kvm_cpu_cap_has(X86_FEATURE_PERFCTR_CORE))
131994cdeebdSLike Xu ebx.split.num_core_pmc = AMD64_NUM_COUNTERS_CORE;
132094cdeebdSLike Xu else
132194cdeebdSLike Xu ebx.split.num_core_pmc = AMD64_NUM_COUNTERS;
132294cdeebdSLike Xu
132394cdeebdSLike Xu entry->ebx = ebx.full;
132494cdeebdSLike Xu break;
132594cdeebdSLike Xu }
132600b27a3eSAvi Kivity /*Add support for Centaur's CPUID instruction*/
132700b27a3eSAvi Kivity case 0xC0000000:
132800b27a3eSAvi Kivity /*Just support up to 0xC0000004 now*/
132900b27a3eSAvi Kivity entry->eax = min(entry->eax, 0xC0000004);
133000b27a3eSAvi Kivity break;
133100b27a3eSAvi Kivity case 0xC0000001:
1332bd791999SSean Christopherson cpuid_entry_override(entry, CPUID_C000_0001_EDX);
133300b27a3eSAvi Kivity break;
133400b27a3eSAvi Kivity case 3: /* Processor serial number */
133500b27a3eSAvi Kivity case 5: /* MONITOR/MWAIT */
133600b27a3eSAvi Kivity case 0xC0000002:
133700b27a3eSAvi Kivity case 0xC0000003:
133800b27a3eSAvi Kivity case 0xC0000004:
133900b27a3eSAvi Kivity default:
134000b27a3eSAvi Kivity entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
134100b27a3eSAvi Kivity break;
134200b27a3eSAvi Kivity }
134300b27a3eSAvi Kivity
1344831bf664SSasha Levin r = 0;
1345831bf664SSasha Levin
1346831bf664SSasha Levin out:
134700b27a3eSAvi Kivity put_cpu();
1348831bf664SSasha Levin
1349831bf664SSasha Levin return r;
135000b27a3eSAvi Kivity }
135100b27a3eSAvi Kivity
do_cpuid_func(struct kvm_cpuid_array * array,u32 func,unsigned int type)1352e53c95e8SSean Christopherson static int do_cpuid_func(struct kvm_cpuid_array *array, u32 func,
1353e53c95e8SSean Christopherson unsigned int type)
13549c15bb1dSBorislav Petkov {
13559c15bb1dSBorislav Petkov if (type == KVM_GET_EMULATED_CPUID)
1356e53c95e8SSean Christopherson return __do_cpuid_func_emulated(array, func);
13579c15bb1dSBorislav Petkov
1358e53c95e8SSean Christopherson return __do_cpuid_func(array, func);
13599c15bb1dSBorislav Petkov }
13609c15bb1dSBorislav Petkov
13618b86079cSSean Christopherson #define CENTAUR_CPUID_SIGNATURE 0xC0000000
1362831bf664SSasha Levin
get_cpuid_func(struct kvm_cpuid_array * array,u32 func,unsigned int type)1363e53c95e8SSean Christopherson static int get_cpuid_func(struct kvm_cpuid_array *array, u32 func,
1364e53c95e8SSean Christopherson unsigned int type)
1365619a17f1SSean Christopherson {
1366619a17f1SSean Christopherson u32 limit;
1367619a17f1SSean Christopherson int r;
1368619a17f1SSean Christopherson
13698b86079cSSean Christopherson if (func == CENTAUR_CPUID_SIGNATURE &&
13708b86079cSSean Christopherson boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR)
13718b86079cSSean Christopherson return 0;
13728b86079cSSean Christopherson
1373e53c95e8SSean Christopherson r = do_cpuid_func(array, func, type);
1374619a17f1SSean Christopherson if (r)
1375619a17f1SSean Christopherson return r;
1376619a17f1SSean Christopherson
1377e53c95e8SSean Christopherson limit = array->entries[array->nent - 1].eax;
1378619a17f1SSean Christopherson for (func = func + 1; func <= limit; ++func) {
1379e53c95e8SSean Christopherson r = do_cpuid_func(array, func, type);
1380619a17f1SSean Christopherson if (r)
1381619a17f1SSean Christopherson break;
1382619a17f1SSean Christopherson }
1383619a17f1SSean Christopherson
1384619a17f1SSean Christopherson return r;
1385619a17f1SSean Christopherson }
1386619a17f1SSean Christopherson
sanity_check_entries(struct kvm_cpuid_entry2 __user * entries,__u32 num_entries,unsigned int ioctl_type)13879c15bb1dSBorislav Petkov static bool sanity_check_entries(struct kvm_cpuid_entry2 __user *entries,
13889c15bb1dSBorislav Petkov __u32 num_entries, unsigned int ioctl_type)
13899c15bb1dSBorislav Petkov {
13909c15bb1dSBorislav Petkov int i;
13911b2ca422SBorislav Petkov __u32 pad[3];
13929c15bb1dSBorislav Petkov
13939c15bb1dSBorislav Petkov if (ioctl_type != KVM_GET_EMULATED_CPUID)
13949c15bb1dSBorislav Petkov return false;
13959c15bb1dSBorislav Petkov
13969c15bb1dSBorislav Petkov /*
13979c15bb1dSBorislav Petkov * We want to make sure that ->padding is being passed clean from
13989c15bb1dSBorislav Petkov * userspace in case we want to use it for something in the future.
13999c15bb1dSBorislav Petkov *
14009c15bb1dSBorislav Petkov * Sadly, this wasn't enforced for KVM_GET_SUPPORTED_CPUID and so we
14019c15bb1dSBorislav Petkov * have to give ourselves satisfied only with the emulated side. /me
14029c15bb1dSBorislav Petkov * sheds a tear.
14039c15bb1dSBorislav Petkov */
14049c15bb1dSBorislav Petkov for (i = 0; i < num_entries; i++) {
14051b2ca422SBorislav Petkov if (copy_from_user(pad, entries[i].padding, sizeof(pad)))
14061b2ca422SBorislav Petkov return true;
14071b2ca422SBorislav Petkov
14081b2ca422SBorislav Petkov if (pad[0] || pad[1] || pad[2])
14099c15bb1dSBorislav Petkov return true;
14109c15bb1dSBorislav Petkov }
14119c15bb1dSBorislav Petkov return false;
14129c15bb1dSBorislav Petkov }
14139c15bb1dSBorislav Petkov
kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 * cpuid,struct kvm_cpuid_entry2 __user * entries,unsigned int type)14149c15bb1dSBorislav Petkov int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
14159c15bb1dSBorislav Petkov struct kvm_cpuid_entry2 __user *entries,
14169c15bb1dSBorislav Petkov unsigned int type)
141700b27a3eSAvi Kivity {
14188b86079cSSean Christopherson static const u32 funcs[] = {
14198b86079cSSean Christopherson 0, 0x80000000, CENTAUR_CPUID_SIGNATURE, KVM_CPUID_SIGNATURE,
1420831bf664SSasha Levin };
142100b27a3eSAvi Kivity
1422e53c95e8SSean Christopherson struct kvm_cpuid_array array = {
1423e53c95e8SSean Christopherson .nent = 0,
1424e53c95e8SSean Christopherson };
1425e53c95e8SSean Christopherson int r, i;
1426d5a661d1SSean Christopherson
142700b27a3eSAvi Kivity if (cpuid->nent < 1)
1428d5a661d1SSean Christopherson return -E2BIG;
142900b27a3eSAvi Kivity if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
143000b27a3eSAvi Kivity cpuid->nent = KVM_MAX_CPUID_ENTRIES;
14319c15bb1dSBorislav Petkov
14329c15bb1dSBorislav Petkov if (sanity_check_entries(entries, cpuid->nent, type))
14339c15bb1dSBorislav Petkov return -EINVAL;
14349c15bb1dSBorislav Petkov
14358670866bSLiao Chang array.entries = kvcalloc(cpuid->nent, sizeof(struct kvm_cpuid_entry2), GFP_KERNEL);
1436e53c95e8SSean Christopherson if (!array.entries)
1437d5a661d1SSean Christopherson return -ENOMEM;
143800b27a3eSAvi Kivity
143965b18914SXiaoyao Li array.maxnent = cpuid->nent;
144065b18914SXiaoyao Li
14418b86079cSSean Christopherson for (i = 0; i < ARRAY_SIZE(funcs); i++) {
1442e53c95e8SSean Christopherson r = get_cpuid_func(&array, funcs[i], type);
1443831bf664SSasha Levin if (r)
144400b27a3eSAvi Kivity goto out_free;
144500b27a3eSAvi Kivity }
1446e53c95e8SSean Christopherson cpuid->nent = array.nent;
144700b27a3eSAvi Kivity
1448e53c95e8SSean Christopherson if (copy_to_user(entries, array.entries,
1449e53c95e8SSean Christopherson array.nent * sizeof(struct kvm_cpuid_entry2)))
1450d5a661d1SSean Christopherson r = -EFAULT;
145100b27a3eSAvi Kivity
145200b27a3eSAvi Kivity out_free:
1453c9b8fecdSPaolo Bonzini kvfree(array.entries);
145400b27a3eSAvi Kivity return r;
145500b27a3eSAvi Kivity }
145600b27a3eSAvi Kivity
kvm_find_cpuid_entry_index(struct kvm_vcpu * vcpu,u32 function,u32 index)1457277ad7d5SSean Christopherson struct kvm_cpuid_entry2 *kvm_find_cpuid_entry_index(struct kvm_vcpu *vcpu,
145800b27a3eSAvi Kivity u32 function, u32 index)
145900b27a3eSAvi Kivity {
1460f69858fcSVitaly Kuznetsov return cpuid_entry2_find(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent,
1461f69858fcSVitaly Kuznetsov function, index);
146200b27a3eSAvi Kivity }
1463277ad7d5SSean Christopherson EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry_index);
1464277ad7d5SSean Christopherson
kvm_find_cpuid_entry(struct kvm_vcpu * vcpu,u32 function)1465277ad7d5SSean Christopherson struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
1466277ad7d5SSean Christopherson u32 function)
1467277ad7d5SSean Christopherson {
1468277ad7d5SSean Christopherson return cpuid_entry2_find(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent,
1469277ad7d5SSean Christopherson function, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
1470277ad7d5SSean Christopherson }
147100b27a3eSAvi Kivity EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
147200b27a3eSAvi Kivity
147300b27a3eSAvi Kivity /*
14748d892311SSean Christopherson * Intel CPUID semantics treats any query for an out-of-range leaf as if the
14758d892311SSean Christopherson * highest basic leaf (i.e. CPUID.0H:EAX) were requested. AMD CPUID semantics
14768d892311SSean Christopherson * returns all zeroes for any undefined leaf, whether or not the leaf is in
14778d892311SSean Christopherson * range. Centaur/VIA follows Intel semantics.
14788d892311SSean Christopherson *
14798d892311SSean Christopherson * A leaf is considered out-of-range if its function is higher than the maximum
14808d892311SSean Christopherson * supported leaf of its associated class or if its associated class does not
14818d892311SSean Christopherson * exist.
14828d892311SSean Christopherson *
14838d892311SSean Christopherson * There are three primary classes to be considered, with their respective
14848d892311SSean Christopherson * ranges described as "<base> - <top>[,<base2> - <top2>] inclusive. A primary
14858d892311SSean Christopherson * class exists if a guest CPUID entry for its <base> leaf exists. For a given
14868d892311SSean Christopherson * class, CPUID.<base>.EAX contains the max supported leaf for the class.
14878d892311SSean Christopherson *
14888d892311SSean Christopherson * - Basic: 0x00000000 - 0x3fffffff, 0x50000000 - 0x7fffffff
14898d892311SSean Christopherson * - Hypervisor: 0x40000000 - 0x4fffffff
14908d892311SSean Christopherson * - Extended: 0x80000000 - 0xbfffffff
14918d892311SSean Christopherson * - Centaur: 0xc0000000 - 0xcfffffff
14928d892311SSean Christopherson *
14938d892311SSean Christopherson * The Hypervisor class is further subdivided into sub-classes that each act as
1494d9f6e12fSIngo Molnar * their own independent class associated with a 0x100 byte range. E.g. if Qemu
14958d892311SSean Christopherson * is advertising support for both HyperV and KVM, the resulting Hypervisor
14968d892311SSean Christopherson * CPUID sub-classes are:
14978d892311SSean Christopherson *
14988d892311SSean Christopherson * - HyperV: 0x40000000 - 0x400000ff
14998d892311SSean Christopherson * - KVM: 0x40000100 - 0x400001ff
150000b27a3eSAvi Kivity */
150109c7431eSSean Christopherson static struct kvm_cpuid_entry2 *
get_out_of_range_cpuid_entry(struct kvm_vcpu * vcpu,u32 * fn_ptr,u32 index)150209c7431eSSean Christopherson get_out_of_range_cpuid_entry(struct kvm_vcpu *vcpu, u32 *fn_ptr, u32 index)
150300b27a3eSAvi Kivity {
15048d892311SSean Christopherson struct kvm_cpuid_entry2 *basic, *class;
150509c7431eSSean Christopherson u32 function = *fn_ptr;
150600b27a3eSAvi Kivity
1507277ad7d5SSean Christopherson basic = kvm_find_cpuid_entry(vcpu, 0);
15088d892311SSean Christopherson if (!basic)
150909c7431eSSean Christopherson return NULL;
151009c7431eSSean Christopherson
151109c7431eSSean Christopherson if (is_guest_vendor_amd(basic->ebx, basic->ecx, basic->edx) ||
151209c7431eSSean Christopherson is_guest_vendor_hygon(basic->ebx, basic->ecx, basic->edx))
151309c7431eSSean Christopherson return NULL;
15148d892311SSean Christopherson
15158d892311SSean Christopherson if (function >= 0x40000000 && function <= 0x4fffffff)
1516277ad7d5SSean Christopherson class = kvm_find_cpuid_entry(vcpu, function & 0xffffff00);
15178d892311SSean Christopherson else if (function >= 0xc0000000)
1518277ad7d5SSean Christopherson class = kvm_find_cpuid_entry(vcpu, 0xc0000000);
15198d892311SSean Christopherson else
1520277ad7d5SSean Christopherson class = kvm_find_cpuid_entry(vcpu, function & 0x80000000);
15218d892311SSean Christopherson
152209c7431eSSean Christopherson if (class && function <= class->eax)
152309c7431eSSean Christopherson return NULL;
152409c7431eSSean Christopherson
152509c7431eSSean Christopherson /*
152609c7431eSSean Christopherson * Leaf specific adjustments are also applied when redirecting to the
152709c7431eSSean Christopherson * max basic entry, e.g. if the max basic leaf is 0xb but there is no
152809c7431eSSean Christopherson * entry for CPUID.0xb.index (see below), then the output value for EDX
152909c7431eSSean Christopherson * needs to be pulled from CPUID.0xb.1.
153009c7431eSSean Christopherson */
153109c7431eSSean Christopherson *fn_ptr = basic->eax;
153209c7431eSSean Christopherson
153309c7431eSSean Christopherson /*
153409c7431eSSean Christopherson * The class does not exist or the requested function is out of range;
153509c7431eSSean Christopherson * the effective CPUID entry is the max basic leaf. Note, the index of
153609c7431eSSean Christopherson * the original requested leaf is observed!
153709c7431eSSean Christopherson */
1538277ad7d5SSean Christopherson return kvm_find_cpuid_entry_index(vcpu, basic->eax, index);
153900b27a3eSAvi Kivity }
154000b27a3eSAvi Kivity
kvm_cpuid(struct kvm_vcpu * vcpu,u32 * eax,u32 * ebx,u32 * ecx,u32 * edx,bool exact_only)1541e911eb3bSYu Zhang bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
1542f91af517SSean Christopherson u32 *ecx, u32 *edx, bool exact_only)
154300b27a3eSAvi Kivity {
1544b7fb8488SJan Kiszka u32 orig_function = *eax, function = *eax, index = *ecx;
154543561123SJim Mattson struct kvm_cpuid_entry2 *entry;
15462b110b61SSean Christopherson bool exact, used_max_basic = false;
154700b27a3eSAvi Kivity
1548277ad7d5SSean Christopherson entry = kvm_find_cpuid_entry_index(vcpu, function, index);
1549f91af517SSean Christopherson exact = !!entry;
155009c7431eSSean Christopherson
15512b110b61SSean Christopherson if (!entry && !exact_only) {
155209c7431eSSean Christopherson entry = get_out_of_range_cpuid_entry(vcpu, &function, index);
15532b110b61SSean Christopherson used_max_basic = !!entry;
15542b110b61SSean Christopherson }
155509c7431eSSean Christopherson
155643561123SJim Mattson if (entry) {
155743561123SJim Mattson *eax = entry->eax;
155843561123SJim Mattson *ebx = entry->ebx;
155943561123SJim Mattson *ecx = entry->ecx;
156043561123SJim Mattson *edx = entry->edx;
1561edef5c36SPaolo Bonzini if (function == 7 && index == 0) {
1562edef5c36SPaolo Bonzini u64 data;
1563edef5c36SPaolo Bonzini if (!__kvm_get_msr(vcpu, MSR_IA32_TSX_CTRL, &data, true) &&
1564edef5c36SPaolo Bonzini (data & TSX_CTRL_CPUID_CLEAR))
1565edef5c36SPaolo Bonzini *ebx &= ~(F(RTM) | F(HLE));
15662be1bd3aSVitaly Kuznetsov } else if (function == 0x80000007) {
15672be1bd3aSVitaly Kuznetsov if (kvm_hv_invtsc_suppressed(vcpu))
15682be1bd3aSVitaly Kuznetsov *edx &= ~SF(CONSTANT_TSC);
1569edef5c36SPaolo Bonzini }
157043561123SJim Mattson } else {
157162046e5aSAvi Kivity *eax = *ebx = *ecx = *edx = 0;
157243561123SJim Mattson /*
157343561123SJim Mattson * When leaf 0BH or 1FH is defined, CL is pass-through
157443561123SJim Mattson * and EDX is always the x2APIC ID, even for undefined
157543561123SJim Mattson * subleaves. Index 1 will exist iff the leaf is
157643561123SJim Mattson * implemented, so we pass through CL iff leaf 1
157743561123SJim Mattson * exists. EDX can be copied from any existing index.
157843561123SJim Mattson */
157943561123SJim Mattson if (function == 0xb || function == 0x1f) {
1580277ad7d5SSean Christopherson entry = kvm_find_cpuid_entry_index(vcpu, function, 1);
158143561123SJim Mattson if (entry) {
158243561123SJim Mattson *ecx = index & 0xff;
158343561123SJim Mattson *edx = entry->edx;
158443561123SJim Mattson }
158543561123SJim Mattson }
158643561123SJim Mattson }
15872b110b61SSean Christopherson trace_kvm_cpuid(orig_function, index, *eax, *ebx, *ecx, *edx, exact,
15882b110b61SSean Christopherson used_max_basic);
1589f91af517SSean Christopherson return exact;
159000b27a3eSAvi Kivity }
159166f7b72eSJulian Stecklina EXPORT_SYMBOL_GPL(kvm_cpuid);
159262046e5aSAvi Kivity
kvm_emulate_cpuid(struct kvm_vcpu * vcpu)15936a908b62SKyle Huey int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
159462046e5aSAvi Kivity {
15951e13175bSJiang Biao u32 eax, ebx, ecx, edx;
159662046e5aSAvi Kivity
1597db2336a8SKyle Huey if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
1598db2336a8SKyle Huey return 1;
1599db2336a8SKyle Huey
1600de3cd117SSean Christopherson eax = kvm_rax_read(vcpu);
1601de3cd117SSean Christopherson ecx = kvm_rcx_read(vcpu);
1602f91af517SSean Christopherson kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, false);
1603de3cd117SSean Christopherson kvm_rax_write(vcpu, eax);
1604de3cd117SSean Christopherson kvm_rbx_write(vcpu, ebx);
1605de3cd117SSean Christopherson kvm_rcx_write(vcpu, ecx);
1606de3cd117SSean Christopherson kvm_rdx_write(vcpu, edx);
16076affcbedSKyle Huey return kvm_skip_emulated_instruction(vcpu);
160800b27a3eSAvi Kivity }
160900b27a3eSAvi Kivity EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
1610