diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.h | 20 |
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 | |||
94 | static 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 | |||
97 | static inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva) | 105 | static 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 | ||
105 | static inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva) | 113 | static 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 | ||
113 | static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) | 122 | static 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; |