From: James Houghton <jthoughton@google.com>
To: seanjc@google.com
Cc: amoorthy@google.com, corbet@lwn.net, dmatlack@google.com,
jthoughton@google.com, kalyazin@amazon.com, kvm@vger.kernel.org,
kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
maz@kernel.org, oliver.upton@linux.dev, pbonzini@redhat.com,
peterx@redhat.com, pgonda@google.com, wei.w.wang@intel.com,
yan.y.zhao@intel.com
Subject: Re: [PATCH v2 06/13] KVM: arm64: Add support for KVM_MEM_USERFAULT
Date: Wed, 28 May 2025 20:17:54 +0000 [thread overview]
Message-ID: <20250528201756.36271-1-jthoughton@google.com> (raw)
In-Reply-To: <aDdILHOu9g-m5hSm@google.com>
On Wed, May 28, 2025 at 1:30 PM Sean Christopherson <seanjc@google.com> wrote:
> On Wed, May 28, 2025, James Houghton wrote:
> > On Wed, May 28, 2025 at 11:09 AM James Houghton <jthoughton@google.com> wrote:
> > > On Tue, May 6, 2025 at 8:06 PM Sean Christopherson <seanjc@google.com> wrote:
> > > > @@ -2127,14 +2131,19 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
> > > > const struct kvm_memory_slot *new,
> > > > enum kvm_mr_change change)
> > > > {
> > > > - bool log_dirty_pages = new && new->flags & KVM_MEM_LOG_DIRTY_PAGES;
> > > > + u32 old_flags = old ? old->flags : 0;
> > > > + u32 new_flags = new ? new->flags : 0;
> > > > +
> > > > + /* Nothing to do if not toggling dirty logging. */
> > > > + if (!((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES))
> > > > + return;
> > >
> > > This is my bug, not yours, but I think this condition must also check
> > > that `change == KVM_MR_FLAGS_ONLY` for it to be correct. This, for
> > > example, will break the case where we are deleting a memslot that
> > > still has KVM_MEM_LOG_DIRTY_PAGES enabled. Will fix in the next
> > > version.
> >
> > Ah it wouldn't break that example, as `new` would be NULL. But I think
> > it would break the case where we are moving a memslot that keeps
> > `KVM_MEM_LOG_DIRTY_PAGES`.
>
> Can you elaborate? Maybe with the full snippet of the final code that's broken.
> I'm not entirely following what's path you're referring to.
This is even more broken than I realized.
I mean that this diff should be applied on top of your patch:
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 5e2ccde66f43c..f1db3f7742b28 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -2134,8 +2134,12 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
u32 old_flags = old ? old->flags : 0;
u32 new_flags = new ? new->flags : 0;
- /* Nothing to do if not toggling dirty logging. */
- if (!((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES))
+ /*
+ * If only changing flags, nothing to do if not toggling
+ * dirty logging.
+ */
+ if (change == KVM_MR_FLAGS_ONLY &&
+ !((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES))
return;
/*
So the final commit looks like:
commit 3c4b57b25b1123629c5f2b64065d51ecdadb6771
Author: James Houghton <jthoughton@google.com>
Date: Tue May 6 15:38:31 2025 -0700
KVM: arm64: Add support for KVM userfault exits
<to be written by James>
Signed-off-by: James Houghton <jthoughton@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index c5d21bcfa3ed4..f1db3f7742b28 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -2127,15 +2131,23 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
const struct kvm_memory_slot *new,
enum kvm_mr_change change)
{
- bool log_dirty_pages = new && new->flags & KVM_MEM_LOG_DIRTY_PAGES;
+ u32 old_flags = old ? old->flags : 0;
+ u32 new_flags = new ? new->flags : 0;
+
+ /*
+ * If only changing flags, nothing to do if not toggling
+ * dirty logging.
+ */
+ if (change == KVM_MR_FLAGS_ONLY &&
+ !((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES))
+ return;
/*
* At this point memslot has been committed and there is an
* allocated dirty_bitmap[], dirty pages will be tracked while the
* memory slot is write protected.
*/
- if (log_dirty_pages) {
-
+ if (new_flags & KVM_MEM_LOG_DIRTY_PAGES) {
if (change == KVM_MR_DELETE)
return;
So we need to bail out early if we are enabling KVM_MEM_USERFAULT but
KVM_MEM_LOG_DIRTY_PAGES is already enabled, otherwise we'll be
write-protecting a bunch of PTEs that we don't need or want to WP.
When *disabling* KVM_MEM_USERFAULT, we definitely don't want to WP
things, as we aren't going to get the unmap afterwards anyway.
So the check we started with handles this:
> > > > + u32 old_flags = old ? old->flags : 0;
> > > > + u32 new_flags = new ? new->flags : 0;
> > > > +
> > > > + /* Nothing to do if not toggling dirty logging. */
> > > > + if (!((old_flags ^ new_flags) & KVM_MEM_LOG_DIRTY_PAGES))
> > > > + return;
So why also check for `change == KVM_MR_FLAGS_ONLY` as well? Everything I just
said doesn't really apply when the memslot is being created, moved, or
destroyed. Otherwise, consider the case where we never enable dirty logging:
- Memslot deletion would be totally broken; we'll see that
KVM_MEM_LOG_DIRTY_PAGES is not getting toggled and then bail out, skipping
some freeing.
- Memslot creation would be broken in a similar way; we'll skip a bunch of
setup work.
- For memslot moving, the only case that we could possibly be leaving
KVM_MEM_LOG_DIRTY_PAGES set without the change being KVM_MR_FLAGS_ONLY,
I think we still need to do the split and WP stuff.
next prev parent reply other threads:[~2025-05-28 20:17 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-09 20:49 [PATCH v2 00/13] KVM: Introduce KVM Userfault James Houghton
2025-01-09 20:49 ` [PATCH v2 01/13] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap James Houghton
2025-05-07 0:01 ` Sean Christopherson
2025-05-28 15:21 ` James Houghton
2025-01-09 20:49 ` [PATCH v2 02/13] KVM: Add KVM_MEMORY_EXIT_FLAG_USERFAULT James Houghton
2025-01-09 20:49 ` [PATCH v2 03/13] KVM: Allow late setting of KVM_MEM_USERFAULT on guest_memfd memslot James Houghton
2025-05-07 0:03 ` Sean Christopherson
2025-01-09 20:49 ` [PATCH v2 04/13] KVM: Advertise KVM_CAP_USERFAULT in KVM_CHECK_EXTENSION James Houghton
2025-01-09 20:49 ` [PATCH v2 05/13] KVM: x86/mmu: Add support for KVM_MEM_USERFAULT James Houghton
2025-05-07 0:05 ` Sean Christopherson
2025-05-28 20:21 ` Oliver Upton
2025-05-28 21:22 ` Sean Christopherson
2025-05-29 14:56 ` Sean Christopherson
2025-05-29 15:37 ` James Houghton
2025-01-09 20:49 ` [PATCH v2 06/13] KVM: arm64: " James Houghton
2025-05-07 0:06 ` Sean Christopherson
2025-05-28 15:09 ` James Houghton
2025-05-28 15:25 ` James Houghton
2025-05-28 17:30 ` Sean Christopherson
2025-05-28 20:17 ` James Houghton [this message]
2025-05-28 23:25 ` Sean Christopherson
2025-06-09 23:04 ` James Houghton
2025-01-09 20:49 ` [PATCH v2 07/13] KVM: selftests: Fix vm_mem_region_set_flags docstring James Houghton
2025-01-09 20:49 ` [PATCH v2 08/13] KVM: selftests: Fix prefault_mem logic James Houghton
2025-01-09 20:49 ` [PATCH v2 09/13] KVM: selftests: Add va_start/end into uffd_desc James Houghton
2025-01-09 20:49 ` [PATCH v2 10/13] KVM: selftests: Add KVM Userfault mode to demand_paging_test James Houghton
2025-01-09 20:49 ` [PATCH v2 11/13] KVM: selftests: Inform set_memory_region_test of KVM_MEM_USERFAULT James Houghton
2025-01-09 20:49 ` [PATCH v2 12/13] KVM: selftests: Add KVM_MEM_USERFAULT + guest_memfd toggle tests James Houghton
2025-01-09 20:49 ` [PATCH v2 13/13] KVM: Documentation: Add KVM_CAP_USERFAULT and KVM_MEM_USERFAULT details James Houghton
2025-05-06 23:48 ` [PATCH v2 00/13] KVM: Introduce KVM Userfault Sean Christopherson
2025-05-07 0:13 ` Sean Christopherson
2025-05-28 15:48 ` James Houghton
2025-05-29 15:28 ` Sean Christopherson
2025-05-29 16:17 ` James Houghton
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=20250528201756.36271-1-jthoughton@google.com \
--to=jthoughton@google.com \
--cc=amoorthy@google.com \
--cc=corbet@lwn.net \
--cc=dmatlack@google.com \
--cc=kalyazin@amazon.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=pgonda@google.com \
--cc=seanjc@google.com \
--cc=wei.w.wang@intel.com \
--cc=yan.y.zhao@intel.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.