Re: [PATCH v10 09/41] KVM: guest_memfd: Filter both shared and private when invalidating
Sean Christopherson <[email protected]>
| Newsgroups | org.kernel.vger.kvm,dev.linux.lists.linux-coco,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-trace-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Aug 25, 2026, Xiaoyao Li wrote:
> On 8/20/2026 9:32 AM, Sean Christopherson wrote:
> > On Mon, Aug 10, 2026, Ackerley Tng wrote:
> > > Sean, do you know if looking up attributes in gmem to feed the KVM MMU
> > > the smallest set of pages to zap will improve performance significantly?
> > > Or if there's any other reason to do this lookup (more complexity in
> > > gmem)?
> >
> > While working through this with Ackerley, I realized this patch is buggy. When
> > in-place conversion is NOT supported, then as evidenced by the current code,
> > invalidations are guaranteed to only affect one of SHARED vs. PRIVATE. And if
> > we change that to zap both, we risk overzapping. I.e. it's not just the cost of
> > the extra MMU walk, it could also be a functional bug.
> >
> > Specifically, if KVM zaps both when SHARED vs. PRIVATE is tracked per-VM, then a
> > PUNCH_HOLE operation on a PRIVATE guest_memfd will incorrectly zap SHARED mappings
> > that have nothing to do with that gmem instance (because they're mapped via a VMA,
> > not a gmem fd). And vice versa, a PUNCH_HOLE on a SHARED gmem (if userspace is
> > using an INIT_SHARED gmem for the shared branch of a memslot) could invalidate the
> > PRIVATE mappings (of a different gmem instance).
> >
> > That latter case in particular would be a functional bug, as spuriously zapping
> > PRIVATE SPTEs is fatal to TDX (destroys the memory contents).
...
> > Opportunistically rename the helper to capture that it returns the a filter
> > for all gfns in anticipation of zapping only the previous mapping types on
> > conversion.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > -static enum kvm_gfn_range_filter kvm_gmem_get_invalidate_filter(struct inode *inode)
> > +static enum kvm_gfn_range_filter kvm_gmem_get_all_gfns_filter(struct inode *inode)
> > {
> > + if (gmem_in_place_conversion)
> > + return KVM_FILTER_SHARED | KVM_FILTER_PRIVATE;
>
> If I understand correctly, above diff is dead code and will change according
> to
>
> And then in the main in-place conversion patch, have the conversion
> flow to only zap tap the "previous" types (with prep work as needed).
No, my thought is to keep the newly named kvm_gmem_get_all_gfns_filter() as-is,
continue using it flows where KVM needs to zap everything, e.g. PUNCH_HOLE, and
have the to-PRIVATE conversion flow open code KVM_FILTER_SHARED.