Select the appropriate CPUID overlay based on the VM type or/and hardware vendor rather than using CPUID_OL_DEFAULT. When the KVM CPU capabilities are queried and modified, a CPUID overlay is used according to the VM type and/or the hardware platform. For ALIASED_1_EDX_F() use CPUID_OL_SVM instead of CPUID_OL_DEFAULT, since the aliased 0x8000_0001.EDX features are AMD-defined duplicates of 0x1.EDX and are only meaningful for SVM guests. Drop the now-unnecessary CPUID_OL_DEFAULT alias. Return 0 for emulated CPUIDs when the overlay is TDX, as KVM cannot emulate the related instruction for TDX guests. Signed-off-by: Binbin Wu --- arch/x86/kvm/cpuid.c | 19 ++++++++++++------- arch/x86/kvm/cpuid.h | 9 ++++----- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 20ea483ddc7a..2c4e64aa14c4 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -374,6 +374,7 @@ static int cpuid_func_emulated(struct kvm *kvm, struct kvm_cpuid_entry2 *entry, void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) { + u8 cpuid_overlay = get_cpuid_overlay(vcpu->kvm); struct kvm_lapic *apic = vcpu->arch.apic; struct kvm_cpuid_entry2 *best; struct kvm_cpuid_entry2 *entry; @@ -404,7 +405,7 @@ void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) * in guest CPUID. Note, this includes features that are * supported by KVM but aren't advertised to userspace! */ - vcpu->arch.cpu_caps[i] = kvm_cpu_caps[CPUID_OL_DEFAULT][i]; + vcpu->arch.cpu_caps[i] = kvm_cpu_caps[cpuid_overlay][i]; if (!cpuid.index) { cpuid_func_emulated(vcpu->kvm, &emulated, cpuid.function, true); vcpu->arch.cpu_caps[i] |= cpuid_get_reg_unsafe(&emulated, cpuid.reg); @@ -806,12 +807,12 @@ do { \ * Aliased Features - For features in 0x8000_0001.EDX that are duplicates of * identical 0x1.EDX features, and thus are aliased from 0x1 to 0x8000_0001. */ -#define ALIASED_1_EDX_F(name) \ -({ \ - BUILD_BUG_ON(__feature_leaf(X86_FEATURE_##name) != CPUID_1_EDX); \ - BUILD_BUG_ON(kvm_cpu_cap_init_in_progress != CPUID_8000_0001_EDX); \ - kvm_cpu_cap_features |= feature_bit(name); \ - kvm_cpu_caps[CPUID_OL_DEFAULT][CPUID_8000_0001_EDX] |= feature_bit(name); \ +#define ALIASED_1_EDX_F(name) \ +({ \ + BUILD_BUG_ON(__feature_leaf(X86_FEATURE_##name) != CPUID_1_EDX); \ + BUILD_BUG_ON(kvm_cpu_cap_init_in_progress != CPUID_8000_0001_EDX); \ + kvm_cpu_cap_features |= feature_bit(name); \ + kvm_cpu_caps[CPUID_OL_SVM][CPUID_8000_0001_EDX] |= feature_bit(name); \ }) /* @@ -1414,6 +1415,10 @@ static int cpuid_func_emulated(struct kvm *kvm, struct kvm_cpuid_entry2 *entry, entry->index = 0; entry->flags = 0; + /* KVM can't do the following emulations for TDX guests. */ + if (get_cpuid_overlay(kvm) == CPUID_OL_TDX) + return 0; + switch (func) { case 0: entry->eax = 7; diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index eae46f37d30f..c3f2417c7980 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -14,9 +14,6 @@ enum kvm_cpuid_overlay { NR_CPUID_OL }; -/* Temporarily use VMX overlay as the default one */ -#define CPUID_OL_DEFAULT CPUID_OL_VMX - #define F_CPUID_VMX BIT(CPUID_OL_VMX) #define F_CPUID_SVM BIT(CPUID_OL_SVM) #define F_CPUID_TDX BIT(CPUID_OL_TDX) @@ -122,9 +119,10 @@ static __always_inline void cpuid_entry_override(struct kvm *kvm, unsigned int leaf) { u32 *reg = cpuid_entry_get_reg(entry, leaf * 32); + u8 cpuid_overlay = get_cpuid_overlay(kvm); BUILD_BUG_ON(leaf >= ARRAY_SIZE(kvm_cpu_caps[0])); - *reg = kvm_cpu_caps[CPUID_OL_DEFAULT][leaf]; + *reg = kvm_cpu_caps[cpuid_overlay][leaf]; } static __always_inline bool guest_cpuid_has(struct kvm_vcpu *vcpu, @@ -245,8 +243,9 @@ static __always_inline void kvm_cpu_cap_set(unsigned int x86_feature, u32 overla static __always_inline u32 kvm_cpu_cap_get(struct kvm *kvm, unsigned int x86_feature) { unsigned int x86_leaf = __feature_leaf(x86_feature); + u8 cpuid_overlay = get_cpuid_overlay(kvm); - return kvm_cpu_caps[CPUID_OL_DEFAULT][x86_leaf] & __feature_bit(x86_feature); + return kvm_cpu_caps[cpuid_overlay][x86_leaf] & __feature_bit(x86_feature); } static __always_inline bool kvm_cpu_cap_has(struct kvm *kvm, unsigned int x86_feature) -- 2.46.0