Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: "Garg, Shivank" <shivankg@amd.com>
To: "sashiko-reviews@lists.linux.dev" <sashiko-reviews@lists.linux.dev>
Cc: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"hao_zhang_kdev@163.com" <hao_zhang_kdev@163.com>
Subject: Re: [PATCH RFC v2 2/4] KVM: guest_memfd: implement folio migration for non-confidential VMs
Date: Wed, 29 Jul 2026 12:10:21 +0000	[thread overview]
Message-ID: <6f7de096befe6468a0d1cdedf8098c38e4420834.camel@amd.com> (raw)
In-Reply-To: <20260728092027.225CF1F000E9@smtp.kernel.org>

On Tue, 2026-07-28 at 09:20 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] Pre-existing ABBA deadlock between `mapping->invalidate_lock` and `folio_lock` via `kvm_gmem_error_folio`.
> - [High] Unpaired `kvm_mmu_invalidate_start` due to lockless `f->bindings` xarray modification during `kvm_gmem_unbind`.
> --
> 
> --- Patch [2]: [PATCH RFC v2 2/4] KVM: guest_memfd: implement folio migration for non-confidential VMs ---
> commit cb30b8cd0e73b5e7ad80d0285306810cbf4d963e
> Author: Shivank Garg <shivankg@amd.com>
> KVM: guest_memfd: implement folio migration for non-confidential VMs
> 
> 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.
> 
> > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
> > index d3b1186b03b3a..ec881cabe8e3e 100644
> > --- a/virt/kvm/guest_memfd.c
> > +++ b/virt/kvm/guest_memfd.c
> [ ... ]
> > +	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.
> > +	 */
> > +	ret = filemap_migrate_folio(mapping, dst, src, mode);
> > +
> > +	kvm_gmem_invalidate_end(inode, start, end);
> 
> [Severity: High]
> This is a pre-existing issue, but does the iteration over bindings here race
> with kvm_gmem_unbind?
> 
> If a guest_memfd file is being closed and its refcount reaches zero
> concurrently, kvm_gmem_unbind takes the !file branch and removes the memslot
> from f->bindings without taking filemap_invalidate_lock.
> 
> Could this lockless modification happen between the calls to
> kvm_gmem_invalidate_start and kvm_gmem_invalidate_end?
> 
> If f->bindings is modified during this window, __kvm_gmem_invalidate_end
> might fail to find the binding and skip the slot, resulting in an unpaired
> start call. This would permanently leak the mmu_invalidate_in_progress
> counter and cause guest page faults to hang indefinitely.

This is valid point.
So, IIUC, I can remove !file branch and take an invalidate lock for slots-
>gmem.file, if I can't get reference on gmem.file.

	CLASS(gmem_get_file, file)(slot);
	struct file* f = file ? file: slot->gmem.file;

	filemap_invalidate_lock(f->f_mapping);
	__kvm_gmem_unbind(slot, f->private_data);
	filemap_invalidate_unlock(f->f_mapping);

This would prevent it from removing the memslot.

> > +
> > +	filemap_invalidate_unlock_shared(mapping);
> > +	return ret;
> >  }
> > +#else
> > +#define kvm_gmem_migrate_folio NULL
> > +#endif
> >  
> >  static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *folio)
> >  {
> 
> [Severity: High]
> This isn't a bug introduced by this patch, but does kvm_gmem_error_folio
> have the exact same ABBA deadlock that you correctly avoided above in
> kvm_gmem_migrate_folio?
> 
> In kvm_gmem_error_folio, it unconditionally calls
> filemap_invalidate_lock_shared while the caller (memory_failure) already
> holds the folio lock.
> 
> Meanwhile, the opposing truncation path in kvm_gmem_punch_hole establishes
> the strict lock ordering of acquiring mapping->invalidate_lock followed by
> locking the folio.
> 
> Could a concurrent fallocate PUNCH_HOLE and a memory failure on the same
> guest_memfd file deadlock the kernel here?
> 

Hao Zhang is actively working on this issue. [1]

[1] https://lore.kernel.org/all/ambEdSPjerZIVN0b@192.168.1.215

Thanks,
Shivank

  reply	other threads:[~2026-07-29 12:10 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28  9:05 [PATCH RFC v2 0/4] KVM: guest_memfd: folio migration for non-confidential VMs Shivank Garg
2026-07-28  9:05 ` [PATCH RFC v2 1/4] mm: split AS_UNMOVABLE back out of AS_INACCESSIBLE Shivank Garg
2026-07-28  9:05 ` [PATCH RFC v2 2/4] KVM: guest_memfd: implement folio migration for non-confidential VMs Shivank Garg
2026-07-28  9:20   ` sashiko-bot
2026-07-29 12:10     ` Garg, Shivank [this message]
2026-07-28  9:05 ` [PATCH RFC v2 3/4] KVM: guest_memfd: add GUEST_MEMFD_FLAG_MIGRATABLE Shivank Garg
2026-07-28  9:28   ` sashiko-bot
2026-07-30  8:15     ` Garg, Shivank
2026-07-28  9:05 ` [PATCH RFC v2 4/4] KVM: selftests: exercise guest_memfd folio migration Shivank Garg
2026-07-28  9:19   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6f7de096befe6468a0d1cdedf8098c38e4420834.camel@amd.com \
    --to=shivankg@amd.com \
    --cc=hao_zhang_kdev@163.com \
    --cc=kvm@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox