On Wed, Feb 2, 2022 at 5:02 PM David Matlack <dmatlack@xxxxxxxxxx> wrote: > > Currently KVM only zaps collapsible 4KiB SPTEs in the shadow MMU (i.e. > in the rmap). This leads to correct behavior because KVM never creates > intermediate huge pages during dirty logging. For example, a 1GiB page > is never partially split to a 2MiB page. > > However this behavior will stop being correct once the shadow MMU > participates in eager page splitting, which can in fact leave behind > partially split huge pages. In preparation for that change, change the > shadow MMU to iterate over all levels when zapping collapsible SPTEs. > > No functional change intended. > Reviewed-by: Ben Gardon <bgardon@xxxxxxxxxx> > Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx> > --- > arch/x86/kvm/mmu/mmu.c | 21 ++++++++++++++------- > 1 file changed, 14 insertions(+), 7 deletions(-) > > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index e2306a39526a..99ad7cc8683f 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -6038,18 +6038,25 @@ static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, > return need_tlb_flush; > } > > +static void kvm_rmap_zap_collapsible_sptes(struct kvm *kvm, > + const struct kvm_memory_slot *slot) > +{ > + bool flush; > + > + flush = slot_handle_level(kvm, slot, kvm_mmu_zap_collapsible_spte, > + PG_LEVEL_4K, KVM_MAX_HUGEPAGE_LEVEL, true); The max level here only needs to be 2M since 1G page wouldn't be split. I think the upper limit can be lowered to KVM_MAX_HUGEPAGE_LEVEL - 1. Not a significant performance difference though. > + > + if (flush) > + kvm_arch_flush_remote_tlbs_memslot(kvm, slot); > + > +} > + > void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, > const struct kvm_memory_slot *slot) > { > if (kvm_memslots_have_rmaps(kvm)) { > write_lock(&kvm->mmu_lock); > - /* > - * Zap only 4k SPTEs since the legacy MMU only supports dirty > - * logging at a 4k granularity and never creates collapsible > - * 2m SPTEs during dirty logging. > - */ > - if (slot_handle_level_4k(kvm, slot, kvm_mmu_zap_collapsible_spte, true)) > - kvm_arch_flush_remote_tlbs_memslot(kvm, slot); > + kvm_rmap_zap_collapsible_sptes(kvm, slot); > write_unlock(&kvm->mmu_lock); > } > > -- > 2.35.0.rc2.247.g8bbb082509-goog >