On Thu, 2026-09-10 at 12:05 +0200, David Hildenbrand (Arm) wrote:
> On 8/5/26 08:40, Shivank Garg wrote:
> > Implement kvm_gmem_migrate_folio() using filemap_migrate_folio() for
> > non-confidential VMs but don't enable it yet. guest_memfd mappings
> > are still marked unmovable, so MM never calls it.
> > 
> > MM invokes ->migrate_folio() callback with folios already locked and
> > acquires the invalidate lock afterwards. kvm_gmem_punch_hole() takes
> > the invalidate lock before locking folios during truncation, so
> > taking invalidate lock in migration callback can cause an ABBA-deadlock
> > situation. Use filemap_invalidate_trylock_shared() to avoid this.
> > 
> > A subsequent patch adds an opt-in flag to change the mapping to
> > movable and enable migration. Non-confidential VMs can use
> > host-side copy via folio_mc_copy(), whereas confidential VMs will
> > require firmware-assisted copying before they can opt in.
> > 
> > Signed-off-by: Shivank Garg <[email protected]>
> > ---
> >  virt/kvm/guest_memfd.c | 36 ++++++++++++++++++++++++++++++++++--
> >  1 file changed, 34 insertions(+), 2 deletions(-)
> > 
> > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
> > index 169f75f95433..583341d593c9 100644
> > --- a/virt/kvm/guest_memfd.c
> > +++ b/virt/kvm/guest_memfd.c
> > @@ -488,13 +488,45 @@ static struct file_operations kvm_gmem_fops = {
> >     .fallocate      = kvm_gmem_fallocate,
> >  };
> >  
> > +#ifdef CONFIG_MIGRATION
> >  static int kvm_gmem_migrate_folio(struct address_space *mapping,
> >                               struct folio *dst, struct folio *src,
> >                               enum migrate_mode mode)
> >  {
> > -   WARN_ON_ONCE(1);
> > -   return -EINVAL;
> > +   struct inode *inode = mapping->host;
> > +   pgoff_t start, end;
> > +   int ret;
> > +
> > +   /*
> > +    * Migration invokes ->migrate_folio() while holding the folio lock.
> > +    * Use a non-blocking trylock to avoid inverting the lock order with
> > +    * truncation, which takes the invalidate lock before locking the
> > +    * folios.
> > +    */
> > +   if (!filemap_invalidate_trylock_shared(mapping))
> > +           return -EAGAIN;
> > +
> > +   start = src->index;
> > +   end = start + folio_nr_pages(src);
> > +
> > +   kvm_gmem_invalidate_start(inode, start, end);
> > +
> > +   /*
> > +    * For non-confidential guests the folio is host-readable, so
> > +    * filemap_migrate_folio() can copy the contents itself via
> > +    * folio_mc_copy().
> > +    * For confidential guests, this would need firmware assistance.
> > +    */
> 
> I think this is all more closely related to mapping_inaccessible().
> 
> If accessible, this is just trivially true that we can support this.
> 
> So I would not comment on what to do for confidential VMs for now, and limit 
> it
> only to the shared-only case where pages are accessible.

Right, mapping_inaccessible is required for confidential memory to prevent
writes to memory in truncation path.

I agree that for shared guest-memfd only, I can defer splitting out AS_UNMOVABLE
and simply not do mapping_set_inaccessible.
This will further simplify this series.


Thanks,
Shivank

Reply via email to