| From 7adacf5eb2d2048045d9fd8fdab861fd9e7e2e96 Mon Sep 17 00:00:00 2001 |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| Date: Wed, 4 Dec 2019 15:50:27 +0100 |
| Subject: KVM: x86: use CPUID to locate host page table reserved bits |
| |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| |
| commit 7adacf5eb2d2048045d9fd8fdab861fd9e7e2e96 upstream. |
| |
| The comment in kvm_get_shadow_phys_bits refers to MKTME, but the same is actually |
| true of SME and SEV. Just use CPUID[0x8000_0008].EAX[7:0] unconditionally if |
| available, it is simplest and works even if memory is not encrypted. |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: Tom Lendacky <thomas.lendacky@amd.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/mmu/mmu.c | 20 ++++++++++++-------- |
| 1 file changed, 12 insertions(+), 8 deletions(-) |
| |
| --- a/arch/x86/kvm/mmu/mmu.c |
| +++ b/arch/x86/kvm/mmu/mmu.c |
| @@ -538,16 +538,20 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes) |
| static u8 kvm_get_shadow_phys_bits(void) |
| { |
| /* |
| - * boot_cpu_data.x86_phys_bits is reduced when MKTME is detected |
| - * in CPU detection code, but MKTME treats those reduced bits as |
| - * 'keyID' thus they are not reserved bits. Therefore for MKTME |
| - * we should still return physical address bits reported by CPUID. |
| + * boot_cpu_data.x86_phys_bits is reduced when MKTME or SME are detected |
| + * in CPU detection code, but the processor treats those reduced bits as |
| + * 'keyID' thus they are not reserved bits. Therefore KVM needs to look at |
| + * the physical address bits reported by CPUID. |
| */ |
| - if (!boot_cpu_has(X86_FEATURE_TME) || |
| - WARN_ON_ONCE(boot_cpu_data.extended_cpuid_level < 0x80000008)) |
| - return boot_cpu_data.x86_phys_bits; |
| + if (likely(boot_cpu_data.extended_cpuid_level >= 0x80000008)) |
| + return cpuid_eax(0x80000008) & 0xff; |
| |
| - return cpuid_eax(0x80000008) & 0xff; |
| + /* |
| + * Quite weird to have VMX or SVM but not MAXPHYADDR; probably a VM with |
| + * custom CPUID. Proceed with whatever the kernel found since these features |
| + * aren't virtualizable (SME/SEV also require CPUIDs higher than 0x80000008). |
| + */ |
| + return boot_cpu_data.x86_phys_bits; |
| } |
| |
| static void kvm_mmu_reset_all_pte_masks(void) |