diff options
author | Xiao Guangrong <guangrong.xiao@linux.intel.com> | 2015-05-13 14:42:27 +0800 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-19 20:52:42 +0200 |
commit | efdfe536d8c643391e19d5726b072f82964bfbdb (patch) | |
tree | 050f927bab93b172f01f5d872762eacd811560be /arch/x86/kvm/mmu.c | |
parent | d69afbc6b1b5d0579f13d1a6339d952c4f60a9f4 (diff) | |
download | lwn-efdfe536d8c643391e19d5726b072f82964bfbdb.tar.gz lwn-efdfe536d8c643391e19d5726b072f82964bfbdb.zip |
KVM: MMU: fix MTRR update
Currently, whenever guest MTRR registers are changed
kvm_mmu_reset_context is called to switch to the new root shadow page
table, however, it's useless since:
1) the cache type is not cached into shadow page's attribute so that
the original root shadow page will be reused
2) the cache type is set on the last spte, that means we should sync
the last sptes when MTRR is changed
This patch fixs this issue by drop all the spte in the gfn range which
is being updated by MTRR
Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/mmu.c')
-rw-r--r-- | arch/x86/kvm/mmu.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index e718c76609f9..5bebec1191f1 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -4525,6 +4525,30 @@ slot_handle_leaf(struct kvm *kvm, struct kvm_memory_slot *memslot, PT_PAGE_TABLE_LEVEL, lock_flush_tlb); } +void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) +{ + struct kvm_memslots *slots; + struct kvm_memory_slot *memslot; + + slots = kvm_memslots(kvm); + + spin_lock(&kvm->mmu_lock); + kvm_for_each_memslot(memslot, slots) { + gfn_t start, end; + + start = max(gfn_start, memslot->base_gfn); + end = min(gfn_end, memslot->base_gfn + memslot->npages); + if (start >= end) + continue; + + slot_handle_level_range(kvm, memslot, kvm_zap_rmapp, + PT_PAGE_TABLE_LEVEL, PT_MAX_HUGEPAGE_LEVEL, + start, end - 1, true); + } + + spin_unlock(&kvm->mmu_lock); +} + static bool slot_rmap_write_protect(struct kvm *kvm, unsigned long *rmapp) { return __rmap_write_protect(kvm, rmapp, false); |