From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Fuad Tabba <fuad.tabba@linux.dev>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>,
kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Isaku Yamahata <isaku.yamahata@intel.com>,
Rick Edgecombe <rick.p.edgecombe@intel.com>,
Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
kvmarm@lists.linux.dev, Wei-Lin Chang <weilin.chang@arm.com>,
Will Deacon <will@kernel.org>
Subject: Re: [PATCH 2/2] KVM: selftests: Test KVM_PRE_FAULT_MEMORY against a full dirty ring
Date: Tue, 10 Nov 2026 15:57:37 +0000 [thread overview]
Message-ID: <avM9i8xWNZ2fU8_2@gremlin> (raw)
In-Reply-To: <CA+EHjTxT_9NghyLSZmOOi_oQboQw-g+6z9WxwaF=-7RdaGbMNw@mail.gmail.com>
On Tue, Nov 10, 2026 at 03:37:05PM +0000, Fuad Tabba wrote:
> Hi Lorenzo,
>
> On Tue, 10 Nov 2026 14:38:27 +0000, "Lorenzo Stoakes (ARM)"
> <ljs@kernel.org> wrote:
> > On Tue, Nov 10, 2026 at 11:07:24AM +0000, Fuad Tabba wrote:
> > > Pre-fault more populated, dirty-logged pages than the vCPU's dirty ring
> > > holds, and check that each call stops before the ring overflows, that a
> > > retry returns ENOSPC without progress, and that the harvested entries
> > > are the pages in order. A read pre-fault can map a page read-only, or
> >
> > Are we asserting an invariant that prefaulting happens in address order
> > here? Is that explicitly presumed in the prefault API, or just how it
> > happens to pan out?
> >
> > I wonder if we might decide for whatever reason in future to do things
> > differently there. Bit nitty I know, but wonder if it's asserting an
> > implementation detail?
>
> Yes, the API doesn't guarantee an order. I'll assert that every page
> is reported exactly once instead.
THanks!
>
> [...]
> > > diff --git a/tools/testing/selftests/kvm/pre_fault_memory_test.c b/tools/testing/selftests/kvm/pre_fault_memory_test.c
> [...]
> > > +static void test_pre_fault_dirty_ring(void)
> [...]
> > > + /* Populate the pages, so that pre-faulting can map them writable. */
> >
> > Reviewed below, but I wonder how x86 could then read fault these?
>
> KVM_PRE_FAULT_MEMORY is defined as a read fault, but x86 maps the page
> writable when the host page is, and marks it dirty, unless it falls
> back to access tracking (below). Populating the pages makes sure they
> aren't backed by the zero page.
Ack.
>
> [...]
> > > + while (range.size) {
> >
> > NIT: n could be scoped to this block instead.
>
> Will do.
Thanks!
>
> [...]
> > > + for (n = 0; ; n++) {
> >
> > Could this loop forever if cur->flags always == KVM_DIRTY_GFN_F_DIRTY? Or
> > is that guaranteed not to be the case?
>
> It can't. Every harvested entry is set to KVM_DIRTY_GFN_F_RESET and
> stays that way until KVM_RESET_DIRTY_RINGS, which runs after the loop,
> so one pass stops after at most a full ring.
Ack OK.
>
> > > + cur = &gfns[fetch % entries];
> > > + if (smp_load_acquire(&cur->flags) != KVM_DIRTY_GFN_F_DIRTY)
> >
> > Is this and the below release paired with equivalent stuff in the dirty ring code?
>
> Yes, the acquire pairs with the smp_wmb() in kvm_dirty_ring_push()
> ahead of the flag store, and the release with the smp_load_acquire()
> in kvm_dirty_gfn_harvested(). dirty_log_test does the same.
I know it's test code, but general kernel practice is to add a comment saying
what memory barriers pair with so it's easier to track, could you add those for
these?
>
> [...]
> > > + /* A read pre-fault can map a page read-only, or access-tracked on x86. */
> >
> > Hmm under what circumstances would that happen? Is there no way to ensure pages
> > are dirtied by prefaulting? I imagine not though!
>
> No, it's up to the architecture. arm64 maps a read fault read-only
> while the slot is logged with a bitmap, and x86 with EPT but no A/D
> bits maps it access-tracked. Neither pushes anything to the ring.
Right, OK, makes sense.
>
> > > + if (!n && !harvested && !range.size) {
> >
> > Hmm, so !n && (harvested || range_size) will pass this, but then you assert
> > n immediately below, so it seems like n is an unconditional requirement.
> >
> > So I wonder whether this should just be !n in this conditional or maybe the
> > assert afterwards should be dropped?
>
> The skip is for when pre-faulting dirties nothing at all: the first
> call maps the whole range without pushing a single entry, so there's
> nothing to test. Any other empty harvest is a bug, which the assert
> reports, so I'd rather keep both as they are.
OK I see. Really the assert below is !n && (harvested || range.size), maybe
clearer to be explicit but it's also a bit noisy so not a big deal.
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-11-10 15:57 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 11:07 [PATCH 0/2] KVM: Bound KVM_PRE_FAULT_MEMORY by the vCPU's dirty ring Fuad Tabba
2026-11-10 11:07 ` [PATCH 1/2] KVM: Stop KVM_PRE_FAULT_MEMORY when the vCPU's dirty ring is full Fuad Tabba
2026-11-10 14:22 ` Lorenzo Stoakes (ARM)
2026-11-10 15:48 ` Sean Christopherson
2026-11-10 17:18 ` Fuad Tabba
2026-11-10 18:35 ` Sean Christopherson
2026-11-10 11:07 ` [PATCH 2/2] KVM: selftests: Test KVM_PRE_FAULT_MEMORY against a full dirty ring Fuad Tabba
2026-11-10 14:38 ` Lorenzo Stoakes (ARM)
2026-11-10 15:37 ` Fuad Tabba
2026-11-10 15:53 ` Sean Christopherson
2026-11-10 16:02 ` Lorenzo Stoakes (ARM)
2026-11-11 10:02 ` Alexandru Elisei
2026-11-11 14:57 ` Sean Christopherson
2026-11-10 17:29 ` Fuad Tabba
2026-11-10 15:57 ` Lorenzo Stoakes (ARM) [this message]
2026-11-10 17:31 ` Fuad Tabba
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=avM9i8xWNZ2fU8_2@gremlin \
--to=ljs@kernel.org \
--cc=corbet@lwn.net \
--cc=fuad.tabba@linux.dev \
--cc=isaku.yamahata@intel.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=rick.p.edgecombe@intel.com \
--cc=seanjc@google.com \
--cc=skhan@linuxfoundation.org \
--cc=weilin.chang@arm.com \
--cc=will@kernel.org \
/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.