| From 61cf7b214395ac16e32f8b38b83c5765943e5038 Mon Sep 17 00:00:00 2001 |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| Date: Wed, 4 Dec 2019 15:50:27 +0100 |
| Subject: [PATCH] KVM: x86: use CPUID to locate host page table reserved bits |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c |
| index 1df967ff7ac3..59ed4e57b617 100644 |
| --- a/arch/x86/kvm/mmu.c |
| +++ b/arch/x86/kvm/mmu.c |
| @@ -504,16 +504,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) |
| -- |
| 2.7.4 |
| |