Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM/MMU: Flush tlb directly in the kvm_zap_gfn_range()

Originally, flush tlb is done by slot_handle_level_range(). This patch
moves the flush directly to kvm_zap_gfn_range() when range flush is
available, so that only the requested range can be flushed.

Signed-off-by: Lan Tianyu <Tianyu.Lan@microsoft.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Lan Tianyu and committed by
Paolo Bonzini
71883a62 3cc5ea94

+13 -3
+13 -3
arch/x86/kvm/mmu.c
··· 5624 5624 { 5625 5625 struct kvm_memslots *slots; 5626 5626 struct kvm_memory_slot *memslot; 5627 + bool flush_tlb = true; 5628 + bool flush = false; 5627 5629 int i; 5630 + 5631 + if (kvm_available_flush_tlb_with_range()) 5632 + flush_tlb = false; 5628 5633 5629 5634 spin_lock(&kvm->mmu_lock); 5630 5635 for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { ··· 5642 5637 if (start >= end) 5643 5638 continue; 5644 5639 5645 - slot_handle_level_range(kvm, memslot, kvm_zap_rmapp, 5646 - PT_PAGE_TABLE_LEVEL, PT_MAX_HUGEPAGE_LEVEL, 5647 - start, end - 1, true); 5640 + flush |= slot_handle_level_range(kvm, memslot, 5641 + kvm_zap_rmapp, PT_PAGE_TABLE_LEVEL, 5642 + PT_MAX_HUGEPAGE_LEVEL, start, 5643 + end - 1, flush_tlb); 5648 5644 } 5649 5645 } 5646 + 5647 + if (flush) 5648 + kvm_flush_remote_tlbs_with_address(kvm, gfn_start, 5649 + gfn_end - gfn_start + 1); 5650 5650 5651 5651 spin_unlock(&kvm->mmu_lock); 5652 5652 }