All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leonardo Bras <leo.bras@arm.com>
To: sashiko-reviews@lists.linux.dev
Cc: Leonardo Bras <leo.bras@arm.com>,
	kvmarm@lists.linux.dev, Oliver Upton <oupton@kernel.org>,
	Marc Zyngier <maz@kernel.org>,
	kvm@vger.kernel.org
Subject: Re: [PATCH v3 05/11] kvm: Add arch-generic interface for hw-accelerated dirty-bitmap cleaning
Date: Mon,  3 Aug 2026 16:16:18 +0100	[thread overview]
Message-ID: <anCwwnBpnetj53Dt@LeoBrasDK> (raw)
In-Reply-To: <20260729110015.372101F00A3A@smtp.kernel.org>

On Wed, Jul 29, 2026 at 11:00:14AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [Critical] Successful hardware dirty log extraction completely bypasses the generic software dirty bitmap, dropping internally-dirtied pages.
> - [Critical] Hardware dirty bits are completely ignored when `KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2` is enabled.
> - [High] Fallback software loop clobbers partial hardware dirty log output and leaks garbage data if `kvm_arch_dirty_log_clear()` fails.
> - [Medium] The `kvm_arch_dirty_log_clear` API overloads two distinct behaviors based on an undocumented `NULL` parameter, risking a NULL pointer dereference in arch implementations.
> --
> 
> --- Patch [5]: [PATCH v3 05/11] kvm: Add arch-generic interface for hw-accelerated dirty-bitmap cleaning ---
> commit 4c5b443921b3fcc7c6b76fa46a7c11e8755ad50f
> Author: Leonardo Bras <leo.bras@arm.com>
> 
> kvm: Add arch-generic interface for hw-accelerated dirty-bitmap cleaning
> 
> This patch introduces kvm_arch_dirty_log_clear() to allow architectures
> to implement hardware-accelerated dirty-bitmap clearing. It adds hooks in
> both kvm_get_dirty_log_protect() and kvm_clear_dirty_log_protect() to try
> the hardware implementation first, falling back to the software loop if it
> fails or is unimplemented.
> 
> > diff --git a/include/linux/kvm_dirty_bit.h b/include/linux/kvm_dirty_bit.h
> > new file mode 100644
> > index 0000000000000..fa4f6b67b6235
> > --- /dev/null
> > +++ b/include/linux/kvm_dirty_bit.h
> 
> [ ... ]
> 
> > +static inline int kvm_arch_dirty_log_clear(struct kvm *kvm,
> > +					   struct kvm_memory_slot *memslot,
> > +					   struct kvm_clear_dirty_log *log,
> > +					   unsigned long *bitmap,
> > +					   bool *flush)
> 
> [Severity: Medium]
> The signature here strongly implies the log parameter is a valid clear
> operation struct. However, when this is called from
> kvm_get_dirty_log_protect(), NULL is passed for the log parameter.
> 
> Could this establish an undocumented API contract where new arch
> implementations blindly dereference the log pointer and cause a host
> kernel panic?

Well, there are 2 users of this functions, and one uses a NULL variable, so 
I don't think anyone will implement something that blingly deferences the 
log pointer.

In any case, I am open to fixing this. How should I add that information?
(Just a comment is enough?)

> 
> > +{
> > +	return -ENXIO;
> > +}
> 
> [ ... ]
> 
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 45e784462ec6e..7a13ef69b6e3e 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> 
> [ ... ]
> 
> > @@ -2262,6 +2263,10 @@ static int kvm_get_dirty_log_protect(struct kvm *kvm, struct kvm_dirty_log *log)
> >  		dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot);
> >  		memset(dirty_bitmap_buffer, 0, n);
> >  
> > +		if (kvm_arch_dirty_log_clear(kvm, memslot, NULL,
> > +					     dirty_bitmap_buffer, &flush) >= 0)
> 
> [Severity: Critical]
> Since this hardware clear is invoked inside the else block of the
> if (kvm->manual_dirty_log_protect) check, are hardware dirty bits
> completely ignored when manual protection is enabled?
> 
> Modern VMMs often enable manual dirty log protection by default. Will
> skipping the hardware tracking here result in userspace only receiving
> the software dirty bitmap, potentially causing silent memory corruption
> on the destination after a live migration?
> 

To skip it, kvm_arch_dirty_log_clear() should return a positive (or zero) 
value, meaning any error (ret < 0) will cause it to run the software 
cleaning. If the arch-specific routine skips cleaning and return >=0, then 
it's an implementation bug. 

> [Severity: Medium]
> This is the call site passing NULL for the log parameter.
> 
> As mentioned above, does this pose a risk of NULL pointer dereferences
> for architectural implementations expecting a valid
> struct kvm_clear_dirty_log pointer?

See previous discussion above.

> 
> > +			goto out;
> > +
> 
> [Severity: Critical]
> If kvm_arch_dirty_log_clear() succeeds, this goto out bypasses the generic
> software dirty bitmap processing loop completely.
> 

Yeah, that's what the arch-specific version is about.

> Does this mean KVM's internally-dirtied pages, such as those from MMIO
> emulation or virtual timers marked via mark_page_dirty(), are silently
> dropped from the dirty log?

No, as those are also cleaned as long as they hit the dirty-log (bitmap).

> 
> [Severity: High]
> If the arch-specific hardware routine fails partway through and returns
> an error code, could it leave partial hardware bits in dirty_bitmap_buffer?

It could. That's a implementation decision: should it return all bits and 
clean all using software, or continue where arch-specific version stopped?

> 
> If it falls through to the software loop, the software loop might overwrite
> hardware bits with software bits (if the software bit is 1) and preserve
> garbage hardware bits (if the software bit is 0). Should
> dirty_bitmap_buffer be cleared on failure?
> 

Depending on the fallback strategy, it should be restored to initial state, 
not cleared.


> >  		KVM_MMU_LOCK(kvm);
> >  		for (i = 0; i < n / sizeof(long); i++) {
> >  			unsigned long mask;
> 
> [ ... ]
> 
> > @@ -2373,6 +2379,10 @@ static int kvm_clear_dirty_log_protect(struct kvm *kvm,
> >  	if (copy_from_user(dirty_bitmap_buffer, log->dirty_bitmap, n))
> >  		return -EFAULT;
> >  
> > +	if (kvm_arch_dirty_log_clear(kvm, memslot, log, dirty_bitmap_buffer,
> > +				     &flush) >= 0)
> 
> [Severity: High]
> If the arch hook modifies dirty_bitmap_buffer before failing and
> returning an error, does it corrupt the mask used by the fallback
> clear loop?
> 
> The fallback software loop uses dirty_bitmap_buffer to decide which bits
> to clear. If it contains garbage from a failed hardware clear, could this
> cause the wrong pages to be cleared?

That's the arch-version responsibility to not put garbage in the buffer, 
and restore it depending on their strategy.

> 
> > +		goto out;
> > +
> 
> [Severity: Critical]
> Similar to the GET path, this goto out bypasses the loop that clears bits
> in memslot->dirty_bitmap using atomic_long_fetch_andnot().
> 
> If the hardware clear succeeds, will the software bits remain set
> indefinitely since they are bypassed from being cleared from KVM's
> internal tracking?

Again, it will write-protect all the pages pointed by the dirty-log, which 
is exactly what the sw routine does.

Thanks!
Leo

  reply	other threads:[~2026-08-03 15:16 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-29 10:45 [PATCH v3 00/11] KVM Dirty-bit cleaning hw accelerator (HACDBS) Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 01/11] KVM: arm64: HDBSS bits Leonardo Bras
2026-07-29 10:55   ` sashiko-bot
2026-08-03 13:13     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 02/11] arm64/cpufeature: Add system-wide FEAT_HACDBS detection Leonardo Bras
2026-07-29 11:02   ` sashiko-bot
2026-08-03 13:50     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 03/11] arm64/sysreg: Add HACDBS consumer and base registers Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 04/11] KVM: arm64: dirty_bit: Add base FEAT_HACDBS cleaning routine Leonardo Bras
2026-07-29 10:57   ` sashiko-bot
2026-08-03 14:47     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 05/11] kvm: Add arch-generic interface for hw-accelerated dirty-bitmap cleaning Leonardo Bras
2026-07-29 11:00   ` sashiko-bot
2026-08-03 15:16     ` Leonardo Bras [this message]
2026-07-29 10:45 ` [PATCH v3 06/11] KVM: arm64: Add hardware-accelerated dirty-bitmap cleaning routine Leonardo Bras
2026-07-29 11:18   ` sashiko-bot
2026-08-03 15:35     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 07/11] KVM: arm64: Dirty-bitmap: avoid splitting previously split blocks Leonardo Bras
2026-07-29 11:08   ` sashiko-bot
2026-08-03 15:54     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 08/11] kvm/dirty_ring: Introduce get_memslot and move helpers to header Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 09/11] kvm/dirty_ring: Add arch-generic interface for hw-accelerated dirty-ring cleaning Leonardo Bras
2026-07-29 11:14   ` sashiko-bot
2026-08-03 16:04     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 10/11] KVM: arm64: Add hardware-accelerated dirty-ring cleaning routine Leonardo Bras
2026-07-29 11:21   ` sashiko-bot
2026-08-03 16:07     ` Leonardo Bras
2026-07-29 10:45 ` [PATCH v3 11/11] KVM: arm64: Enable KVM_HW_DIRTY_BIT Leonardo Bras
2026-07-29 11:29   ` sashiko-bot
2026-08-03 16:38     ` Leonardo Bras

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=anCwwnBpnetj53Dt@LeoBrasDK \
    --to=leo.bras@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=oupton@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 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.