Skip to content

Commit c61baea

Browse files
bysuisean-jc
authored andcommitted
KVM: x86/mmu: Fix wrong gfn range of tlb flushing in kvm_set_pte_rmapp()
When the spte of hupe page is dropped in kvm_set_pte_rmapp(), the whole gfn range covered by the spte should be flushed. However, rmap_walk_init_level() doesn't align down the gfn for new level like tdp iterator does, then the gfn used in kvm_set_pte_rmapp() is not the base gfn of huge page. And the size of gfn range is wrong too for huge page. Use the base gfn of huge page and the size of huge page for flushing tlbs for huge page. Also introduce a helper function to flush the given page (huge or not) of guest memory, which would help prevent future buggy use of kvm_flush_remote_tlbs_with_address() in such case. Fixes: c3134ce ("KVM: Replace old tlb flush function with new one to flush a specified range.") Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com> Link: https://lore.kernel.org/r/0ce24d7078fa5f1f8d64b0c59826c50f32f8065e.1665214747.git.houwenlong.hwl@antgroup.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent bb05964 commit c61baea

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

arch/x86/kvm/mmu/mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1469,7 +1469,7 @@ static bool kvm_set_pte_rmap(struct kvm *kvm, struct kvm_rmap_head *rmap_head,
14691469
}
14701470

14711471
if (need_flush && kvm_available_flush_tlb_with_range()) {
1472-
kvm_flush_remote_tlbs_with_address(kvm, gfn, 1);
1472+
kvm_flush_remote_tlbs_gfn(kvm, gfn, level);
14731473
return false;
14741474
}
14751475

arch/x86/kvm/mmu/mmu_internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,17 @@ void kvm_mmu_gfn_allow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn);
169169
bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
170170
struct kvm_memory_slot *slot, u64 gfn,
171171
int min_level);
172+
172173
void kvm_flush_remote_tlbs_with_address(struct kvm *kvm,
173174
u64 start_gfn, u64 pages);
175+
176+
/* Flush the given page (huge or not) of guest memory. */
177+
static inline void kvm_flush_remote_tlbs_gfn(struct kvm *kvm, gfn_t gfn, int level)
178+
{
179+
kvm_flush_remote_tlbs_with_address(kvm, gfn_round_for_level(gfn, level),
180+
KVM_PAGES_PER_HPAGE(level));
181+
}
182+
174183
unsigned int pte_list_count(struct kvm_rmap_head *rmap_head);
175184

176185
extern int nx_huge_pages;

0 commit comments

Comments
 (0)