aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/mmu.c2
-rw-r--r--arch/x86/kvm/x86.h20
3 files changed, 17 insertions, 6 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 73e4149eda33..08cc299ec6f4 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -477,6 +477,7 @@ struct kvm_vcpu_arch {
477 u64 mmio_gva; 477 u64 mmio_gva;
478 unsigned access; 478 unsigned access;
479 gfn_t mmio_gfn; 479 gfn_t mmio_gfn;
480 u64 mmio_gen;
480 481
481 struct kvm_pmu pmu; 482 struct kvm_pmu pmu;
482 483
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 96515957ba82..1cd2a5fbde07 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -3162,7 +3162,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
3162 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) 3162 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
3163 return; 3163 return;
3164 3164
3165 vcpu_clear_mmio_info(vcpu, ~0ul); 3165 vcpu_clear_mmio_info(vcpu, MMIO_GVA_ANY);
3166 kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC); 3166 kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC);
3167 if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) { 3167 if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
3168 hpa_t root = vcpu->arch.mmu.root_hpa; 3168 hpa_t root = vcpu->arch.mmu.root_hpa;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 306a1b77581f..985fb2c006fa 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -88,15 +88,23 @@ static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
88 vcpu->arch.mmio_gva = gva & PAGE_MASK; 88 vcpu->arch.mmio_gva = gva & PAGE_MASK;
89 vcpu->arch.access = access; 89 vcpu->arch.access = access;
90 vcpu->arch.mmio_gfn = gfn; 90 vcpu->arch.mmio_gfn = gfn;
91 vcpu->arch.mmio_gen = kvm_memslots(vcpu->kvm)->generation;
92}
93
94static inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)
95{
96 return vcpu->arch.mmio_gen == kvm_memslots(vcpu->kvm)->generation;
91} 97}
92 98
93/* 99/*
94 * Clear the mmio cache info for the given gva, 100 * Clear the mmio cache info for the given gva. If gva is MMIO_GVA_ANY, we
95 * specially, if gva is ~0ul, we clear all mmio cache info. 101 * clear all mmio cache info.
96 */ 102 */
103#define MMIO_GVA_ANY (~(gva_t)0)
104
97static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva) 105static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva)
98{ 106{
99 if (gva != (~0ul) && vcpu->arch.mmio_gva != (gva & PAGE_MASK)) 107 if (gva != MMIO_GVA_ANY && vcpu->arch.mmio_gva != (gva & PAGE_MASK))
100 return; 108 return;
101 109
102 vcpu->arch.mmio_gva = 0; 110 vcpu->arch.mmio_gva = 0;
@@ -104,7 +112,8 @@ static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva)
104 112
105static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva) 113static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva)
106{ 114{
107 if (vcpu->arch.mmio_gva && vcpu->arch.mmio_gva == (gva & PAGE_MASK)) 115 if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gva &&
116 vcpu->arch.mmio_gva == (gva & PAGE_MASK))
108 return true; 117 return true;
109 118
110 return false; 119 return false;
@@ -112,7 +121,8 @@ static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva)
112 121
113static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) 122static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
114{ 123{
115 if (vcpu->arch.mmio_gfn && vcpu->arch.mmio_gfn == gpa >> PAGE_SHIFT) 124 if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gfn &&
125 vcpu->arch.mmio_gfn == gpa >> PAGE_SHIFT)
116 return true; 126 return true;
117 127
118 return false; 128 return false;