KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active

This commit is contained in:
Salvatore Bonaccorso 2019-11-07 17:10:09 +01:00
parent 537ad2315a
commit cd92ab49c4
3 changed files with 70 additions and 0 deletions

1
debian/changelog vendored
View File

@ -10,6 +10,7 @@ linux (4.19.67-2+deb10u2) UNRELEASED; urgency=medium
- KVM: x86: change kvm_mmu_page_get_gfn BUG_ON to WARN_ON
- KVM: x86: add tracepoints around __direct_map and FNAME(fetch)
- kvm: x86, powerpc: do not allow clearing largepages debugfs entry
- KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active
- x86: Add ITLB_MULTIHIT bug infrastructure
- kvm: mmu: ITLB_MULTIHIT mitigation
- kvm: Add helper function for creating VM worker threads

View File

@ -0,0 +1,68 @@
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Sun, 27 Oct 2019 16:23:23 +0100
Subject: KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is
active
Origin: https://git.kernel.org/linus/9167ab79936206118cc60e47dcb926c3489f3bd5
VMX already does so if the host has SMEP, in order to support the combination of
CR0.WP=1 and CR4.SMEP=1. However, it is perfectly safe to always do so, and in
fact VMX already ends up running with EFER.NXE=1 on old processors that lack the
"load EFER" controls, because it may help avoiding a slow MSR write. Removing
all the conditionals simplifies the code.
SVM does not have similar code, but it should since recent AMD processors do
support SMEP. So this patch also makes the code for the two vendors more similar
while fixing NPT=0, CR0.WP=1 and CR4.SMEP=1 on AMD processors.
Cc: stable@vger.kernel.org
Cc: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[Salvatore Bonaccorso: Backport to 4.19: Adjust context, filename change back
to arch/x86/kvm/vmx.c]
---
arch/x86/kvm/svm.c | 10 ++++++++--
arch/x86/kvm/vmx.c | 14 +++-----------
2 files changed, 11 insertions(+), 13 deletions(-)
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -736,8 +736,14 @@ static int get_npt_level(struct kvm_vcpu
static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
{
vcpu->arch.efer = efer;
- if (!npt_enabled && !(efer & EFER_LMA))
- efer &= ~EFER_LME;
+
+ if (!npt_enabled) {
+ /* Shadow paging assumes NX to be available. */
+ efer |= EFER_NX;
+
+ if (!(efer & EFER_LMA))
+ efer &= ~EFER_LME;
+ }
to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR);
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2785,17 +2785,9 @@ static bool update_transition_efer(struc
u64 guest_efer = vmx->vcpu.arch.efer;
u64 ignore_bits = 0;
- if (!enable_ept) {
- /*
- * NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing
- * host CPUID is more efficient than testing guest CPUID
- * or CR4. Host SMEP is anyway a requirement for guest SMEP.
- */
- if (boot_cpu_has(X86_FEATURE_SMEP))
- guest_efer |= EFER_NX;
- else if (!(guest_efer & EFER_NX))
- ignore_bits |= EFER_NX;
- }
+ /* Shadow paging assumes NX to be available. */
+ if (!enable_ept)
+ guest_efer |= EFER_NX;
/*
* LMA and LME handled by hardware; SCE meaningless outside long mode.

View File

@ -266,6 +266,7 @@ bugfix/x86/itlb_multihit/0005-KVM-x86-remove-now-unneeded-hugepage-gfn-adjustmen
bugfix/x86/itlb_multihit/0006-KVM-x86-change-kvm_mmu_page_get_gfn-BUG_ON-to-WARN_O.patch
bugfix/x86/itlb_multihit/0007-KVM-x86-add-tracepoints-around-__direct_map-and-FNAM.patch
bugfix/x86/itlb_multihit/0008-kvm-x86-powerpc-do-not-allow-clearing-largepages-deb.patch
bugfix/x86/itlb_multihit/0009-KVM-vmx-svm-always-run-with-EFER.NXE-1-when-shadow-p.patch
bugfix/x86/itlb_multihit/0009-x86-Add-ITLB_MULTIHIT-bug-infrastructure.patch
bugfix/x86/itlb_multihit/0010-kvm-mmu-ITLB_MULTIHIT-mitigation.patch
bugfix/x86/itlb_multihit/0011-kvm-Add-helper-function-for-creating-VM-worker.patch