Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH v3] KVM: guest_memfd: Avoid deadlock in error_remove_folio()
@ 2026-07-27  2:37 Hao Zhang
  2026-07-27  2:50 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Hao Zhang @ 2026-07-27  2:37 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: Paolo Bonzini, kvm, Ackerley Tng

From: Hao Zhang <zhanghao1@kylinos.cn>

memory_failure() invokes ->error_remove_folio() while holding the
poisoned folio lock.  KVM's guest_memfd callback then takes
mapping->invalidate_lock for read before invalidating guest mappings.

This can deadlock with paths that hold mapping->invalidate_lock for write
and then try to lock the same folio, e.g. truncation from MADV_REMOVE or
FALLOC_FL_PUNCH_HOLE.  Because rwsems are fair, the problem is not limited
to guest_memfd punch-hole: a pending writer can also block future readers,
so ->error_remove_folio() must not block on the invalidate lock while
holding the poisoned folio lock.

Use filemap_invalidate_trylock_shared() in kvm_gmem_error_folio().  If the
invalidate lock is contended, fail the recovery instead of potentially
deadlocking the memory-failure path.

Fixes: a7800aa80ea4 ("KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory")
Signed-off-by: Hao Zhang <zhanghao1@kylinos.cn>
---
Changes in v3:
 - Drop the guest_memfd-private bindings_lock approach from v2 and go back
   to the trylock stopgap from v1, as suggested by Sean.
 - Rewrite the changelog and code comment to describe the problematic lock
   dependency as the poisoned folio lock vs. mapping->invalidate_lock, and
   avoid implying that mf_mutex is part of the actual deadlock.
 - Account for rwsem fairness: a pending writer can block future readers, so
   the issue is not limited to guest_memfd punch-hole.

Link to v2: https://lore.kernel.org/all/tencent_7DA064CAC9B463EB9B651801011E2CE4230A@qq.com/

 virt/kvm/guest_memfd.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index db57c5766ab6..6476ab4a2be7 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -500,7 +500,17 @@ static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *fol
 {
 	pgoff_t start, end;
 
-	filemap_invalidate_lock_shared(mapping);
+	/*
+	 * memory_failure() invokes ->error_remove_folio() while holding the
+	 * poisoned folio lock.  Do not block on mapping->invalidate_lock, as
+	 * a writer that already holds the invalidate lock can be waiting for
+	 * the same folio, e.g. truncation from MADV_REMOVE/FALLOC_FL_PUNCH_HOLE.
+	 *
+	 * If the invalidate lock is contended, fail the recovery instead of
+	 * risking a deadlock in the memory-failure path.
+	 */
+	if (!filemap_invalidate_trylock_shared(mapping))
+		return -EBUSY;
 
 	start = folio->index;
 	end = start + folio_nr_pages(folio);

base-commit: 58717b2a1365d06c8c64b72aa948541b53fe31eb
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-27  2:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27  2:37 [PATCH v3] KVM: guest_memfd: Avoid deadlock in error_remove_folio() Hao Zhang
2026-07-27  2:50 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox