All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hao Zhang <hao_zhang_kdev@163.com>
To: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>, kvm@vger.kernel.org
Subject: [PATCH 1/2] KVM: Flush dirty ring resets before handling signals
Date: Fri, 28 Aug 2026 17:11:16 +0800	[thread overview]
Message-ID: <apFQtIs9SLEobo04@192.168.1.215> (raw)

From: Hao Zhang <zhanghao1@kylinos.cn>

KVM bails out of KVM_RESET_DIRTY_RINGS if a signal is pending, but the
dirty ring reset flow can already have consumed harvested entries before
noticing the signal.  In that case, the entries have been marked invalid
and reset_index has been advanced, but the batched GFNs may not yet have
been reprotected by kvm_reset_dirty_gfn().

This breaks the dirty ring state machine: userspace has handed the GFNs
back to KVM, but KVM can leave the corresponding pages writable.  Future
guest writes to those pages may then fail to generate new dirty-ring
entries, causing dirty tracking to miss updates.

Make the signal path break out of the scan loop instead of returning
immediately, so any pending batch is flushed before kvm_dirty_ring_reset()
returns.

Fixes: 49005a2a3d2a ("KVM: Bail from the dirty ring reset flow if a signal is pending")
Signed-off-by: Hao Zhang <zhanghao1@kylinos.cn>
---
 virt/kvm/dirty_ring.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/dirty_ring.c b/virt/kvm/dirty_ring.c
index 572b854edf74..451eee9d8f69 100644
--- a/virt/kvm/dirty_ring.c
+++ b/virt/kvm/dirty_ring.c
@@ -122,6 +122,7 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
 	u64 cur_offset, next_offset;
 	unsigned long mask = 0;
 	struct kvm_dirty_gfn *entry;
+	int r = 0;
 
 	/*
 	 * Ensure concurrent calls to KVM_RESET_DIRTY_RINGS are serialized,
@@ -132,8 +133,10 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
 	lockdep_assert_held(&kvm->slots_lock);
 
 	while (likely((*nr_entries_reset) < INT_MAX)) {
-		if (signal_pending(current))
-			return -EINTR;
+		if (signal_pending(current)) {
+			r = -EINTR;
+			break;
+		}
 
 		entry = &ring->dirty_gfns[ring->reset_index & (ring->size - 1)];
 
@@ -213,7 +216,7 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_dirty_ring *ring,
 
 	trace_kvm_dirty_ring_reset(ring);
 
-	return 0;
+	return r;
 }
 
 void kvm_dirty_ring_push(struct kvm_vcpu *vcpu, u32 slot, u64 offset)

base-commit: 45c13f3f9e3bb15fd89ff2864c6f627a3b4b4229
-- 
2.15.0


             reply	other threads:[~2026-08-28  9:11 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-28  9:11 Hao Zhang [this message]
2026-08-28  9:19 ` [PATCH 2/2] KVM: Return dirty ring reset errors if no entries were reset Hao Zhang

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=apFQtIs9SLEobo04@192.168.1.215 \
    --to=hao_zhang_kdev@163.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.