summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Christopherson <sean.j.christopherson@intel.com>2019-02-05 13:01:13 -0800
committerBen Hutchings <ben@decadent.org.uk>2019-07-09 22:04:04 +0100
commit2cf024c9e0237be92e74580823ac214c1f423e12 (patch)
treee5873c6f9cd66e7c2faed06c0e6446146ba9b7f6
parent6710f8cd35bb655f59b1127ad5e0ce766b6a06f4 (diff)
downloadlinux-stable-2cf024c9e0237be92e74580823ac214c1f423e12.tar.gz
linux-stable-2cf024c9e0237be92e74580823ac214c1f423e12.tar.bz2
linux-stable-2cf024c9e0237be92e74580823ac214c1f423e12.zip
KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux
commit ddfd1730fd829743e41213e32ccc8b4aa6dc8325 upstream. When installing new memslots, KVM sets bit 0 of the generation number to indicate that an update is in-progress. Until the update is complete, there are no guarantees as to whether a vCPU will see the old or the new memslots. Explicity prevent caching MMIO accesses so as to avoid using an access cached from the old memslots after the new memslots have been installed. Note that it is unclear whether or not disabling caching during the update window is strictly necessary as there is no definitive documentation as to what ordering guarantees KVM provides with respect to updating memslots. That being said, the MMIO spte code does not allow reusing sptes created while an update is in-progress, and the associated documentation explicitly states: We do not want to use an MMIO sptes created with an odd generation number, ... If KVM is unlucky and creates an MMIO spte while the low bit is 1, the next access to the spte will always be a cache miss. At the very least, disabling the per-vCPU MMIO cache during updates will make its behavior consistent with the MMIO spte behavior and documentation. Fixes: 56f17dd3fbc4 ("kvm: x86: fix stale mmio cache bug") Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> [ Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--arch/x86/kvm/x86.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 6453f936540a..30a3ebd06f6c 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -75,10 +75,15 @@ static inline u32 bit(int bitno)
static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
gva_t gva, gfn_t gfn, unsigned access)
{
+ u64 gen = kvm_memslots(vcpu->kvm)->generation;
+
+ if (unlikely(gen & 1))
+ return;
+
vcpu->arch.mmio_gva = gva & PAGE_MASK;
vcpu->arch.access = access;
vcpu->arch.mmio_gfn = gfn;
- vcpu->arch.mmio_gen = kvm_memslots(vcpu->kvm)->generation;
+ vcpu->arch.mmio_gen = gen;
}
static inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)