kvm: x86: fix stale mmio cache bug
[pandora-kernel.git] / arch / x86 / kvm / x86.h
index d36fe23..6c3c94f 100644 (file)
@@ -81,15 +81,23 @@ static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
        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;
+}
+
+static inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.mmio_gen == kvm_memslots(vcpu->kvm)->generation;
 }
 
 /*
- * Clear the mmio cache info for the given gva,
- * specially, if gva is ~0ul, we clear all mmio cache info.
+ * Clear the mmio cache info for the given gva. If gva is MMIO_GVA_ANY, we
+ * clear all mmio cache info.
  */
+#define MMIO_GVA_ANY (~(gva_t)0)
+
 static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva)
 {
-       if (gva != (~0ul) && vcpu->arch.mmio_gva != (gva & PAGE_MASK))
+       if (gva != MMIO_GVA_ANY && vcpu->arch.mmio_gva != (gva & PAGE_MASK))
                return;
 
        vcpu->arch.mmio_gva = 0;
@@ -97,7 +105,8 @@ static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva)
 
 static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva)
 {
-       if (vcpu->arch.mmio_gva && vcpu->arch.mmio_gva == (gva & PAGE_MASK))
+       if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gva &&
+             vcpu->arch.mmio_gva == (gva & PAGE_MASK))
                return true;
 
        return false;
@@ -105,7 +114,8 @@ static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva)
 
 static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
 {
-       if (vcpu->arch.mmio_gfn && vcpu->arch.mmio_gfn == gpa >> PAGE_SHIFT)
+       if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gfn &&
+             vcpu->arch.mmio_gfn == gpa >> PAGE_SHIFT)
                return true;
 
        return false;
@@ -125,4 +135,6 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
        gva_t addr, void *val, unsigned int bytes,
        struct x86_exception *exception);
 
+extern unsigned int min_timer_period_us;
+
 #endif