From: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx> When kvm->tlbs_dirty > 0, some rmaps might have been deleted without flushing tlb remotely after kvm_sync_page(). If @gfn was writable before and it's rmaps was deleted in kvm_sync_page(), we need to flush tlb too even if __rmap_write_protect() doesn't request it. Fixes: 4731d4c7a077 ("KVM: MMU: out of sync shadow core") Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx> --- arch/x86/kvm/mmu/mmu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 4853c033e6ce..313918df1a10 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -1420,6 +1420,14 @@ bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, rmap_head = gfn_to_rmap(gfn, i, slot); write_protected |= __rmap_write_protect(kvm, rmap_head, true); } + /* + * When kvm->tlbs_dirty > 0, some rmaps might have been deleted + * without flushing tlb remotely after kvm_sync_page(). If @gfn + * was writable before and it's rmaps was deleted in kvm_sync_page(), + * we need to flush tlb too. + */ + if (min_level == PG_LEVEL_4K && kvm->tlbs_dirty) + write_protected = true; } if (is_tdp_mmu_enabled(kvm)) @@ -5733,6 +5741,14 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, flush = slot_handle_level(kvm, memslot, slot_rmap_write_protect, start_level, KVM_MAX_HUGEPAGE_LEVEL, false); + /* + * When kvm->tlbs_dirty > 0, some rmaps might have been deleted + * without flushing tlb remotely after kvm_sync_page(). If @gfn + * was writable before and it's rmaps was deleted in kvm_sync_page(), + * we need to flush tlb too. + */ + if (start_level == PG_LEVEL_4K && kvm->tlbs_dirty) + flush = true; write_unlock(&kvm->mmu_lock); } -- 2.19.1.6.gb485710b