On Thu, 2025-04-24 at 11:08 +0800, Yan Zhao wrote: > +static int kvm_gmem_invalidate_begin(struct kvm_gmem *gmem, pgoff_t start, > + pgoff_t end, bool need_split) > { > bool flush = false, found_memslot = false; > struct kvm_memory_slot *slot; > struct kvm *kvm = gmem->kvm; > unsigned long index; > + int ret = 0; > > xa_for_each_range(&gmem->bindings, index, slot, start, end - 1) { > pgoff_t pgoff = slot->gmem.pgoff; > @@ -319,14 +320,23 @@ static void kvm_gmem_invalidate_begin(struct kvm_gmem *gmem, pgoff_t start, > kvm_mmu_invalidate_begin(kvm); > } > > + if (need_split) { > + ret = kvm_split_boundary_leafs(kvm, &gfn_range); What is the effect for other guestmemfd users? SEV doesn't need this, right? Oh I see, down in tdp_mmu_split_boundary_leafs() it bails on non-mirror roots. I don't like the naming then. It sounds deterministic, but it's really only necessary splits for certain VM types. I guess it all depends on how well teaching kvm_mmu_unmap_gfn_range() to fail goes. But otherwise, we should call it like kvm_prepare_zap_range() or something. And have it make it clearly do nothing for non-TDX high up where it's easy to see. > + if (ret < 0) > + goto out; > + > + flush |= ret; > + } > flush |= kvm_mmu_unmap_gfn_range(kvm, &gfn_range); > } > > +out: > if (flush) > kvm_flush_remote_tlbs(kvm); > > if (found_memslot) > KVM_MMU_UNLOCK(kvm); > +