diff options
-rw-r--r-- | arch/x86/kvm/cpuid.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 88ab264b4280..67514cb4e000 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -631,12 +631,14 @@ static __always_inline u32 raw_cpuid_get(struct cpuid_reg cpuid) do { \ const struct cpuid_reg cpuid = x86_feature_cpuid(leaf * 32); \ const u32 __maybe_unused kvm_cpu_cap_init_in_progress = leaf; \ + u32 kvm_cpu_cap_passthrough = 0; \ \ if (leaf < NCAPINTS) \ kvm_cpu_caps[leaf] &= (mask); \ else \ kvm_cpu_caps[leaf] = (mask); \ \ + kvm_cpu_caps[leaf] |= kvm_cpu_cap_passthrough; \ kvm_cpu_caps[leaf] &= raw_cpuid_get(cpuid); \ } while (0) @@ -674,6 +676,18 @@ do { \ }) /* + * Passthrough Feature - For features that KVM supports based purely on raw + * hardware CPUID, i.e. that KVM virtualizes even if the host kernel doesn't + * use the feature. Simply force set the feature in KVM's capabilities, raw + * CPUID support will be factored in by kvm_cpu_cap_mask(). + */ +#define PASSTHROUGH_F(name) \ +({ \ + kvm_cpu_cap_passthrough |= F(name); \ + F(name); \ +}) + +/* * 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. */ @@ -798,7 +812,7 @@ void kvm_set_cpu_caps(void) kvm_cpu_cap_init(CPUID_7_ECX, F(AVX512VBMI) | - F(LA57) | + PASSTHROUGH_F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) | @@ -817,9 +831,6 @@ void kvm_set_cpu_caps(void) F(SGX_LC) | F(BUS_LOCK_DETECT) ); - /* Set LA57 based on hardware capability. */ - if (cpuid_ecx(7) & feature_bit(LA57)) - kvm_cpu_cap_set(X86_FEATURE_LA57); /* * PKU not yet implemented for shadow paging and requires OSPKE @@ -1097,6 +1108,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cpu_caps); #undef F #undef SF #undef X86_64_F +#undef PASSTHROUGH_F #undef ALIASED_1_EDX_F struct kvm_cpuid_array { |