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 v2 09/13] KVM: arm64: Dirty-bitmap: avoid splitting previously split blocks
Date: Mon, 29 Jun 2026 18:07:55 +0100 [thread overview]
Message-ID: <akKma9XqQcurXLa2@LeoBrasDK> (raw)
In-Reply-To: <20260629113938.405FC1F000E9@smtp.kernel.org>
On Mon, Jun 29, 2026 at 11:39:37AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [High] Incorrect PMD boundary calculation skips huge page splitting for adjacent PMDs and causes redundant splitting for the last chunk of each PMD.
> - [Low] Variable `split_end` is declared as a Guest Physical Address (`gpa_t`) but assigned and compared as a Guest Frame Number (`gfn_t`).
> - [Low] The local variables `start` and `end` shadow the outer loop bounds.
> --
>
> commit 8863fe6c6c67ca7006255c8805499ac99f887014
> Author: Leonardo Bras <leo.bras@arm.com>
>
> KVM: arm64: Dirty-bitmap: avoid splitting previously split blocks
>
> If previous dirty-clean already split a block, then avoid calling the
> split helper on that block again.
>
> > diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
> > --- a/arch/arm64/kvm/dirty_bit.c
> > +++ b/arch/arm64/kvm/dirty_bit.c
> > @@ -160,6 +160,7 @@ int __kvm_arch_dirty_log_clear(struct kvm *kvm,
> > u64 ttwl;
> > u64 start, end;
> > gfn_t base_gfn;
> > + gpa_t split_end = 0;
>
> [Severity: Low]
> This isn't a bug, but should split_end be declared as a gfn_t?
>
> It is declared as a Guest Physical Address (gpa_t) here, but later receives
> a Guest Frame Number (gfn_t) from gpa_to_gfn(). While both compile as u64,
> this mixes address types.
>
> [ ... ]
Sure, can be changed.
>
> > @@ -204,10 +205,14 @@ int __kvm_arch_dirty_log_clear(struct kvm *kvm,
> >
> > offset = base_gfn + i * BITS_PER_LONG;
> >
> > - if (kvm_dirty_log_manual_protect_and_init_set(kvm))
> > - kvm_mmu_split_huge_pages(kvm,
> > - gfn_to_gpa(offset + __ffs(mask)),
> > - gfn_to_gpa(offset + __fls(mask) + 1));
> > + if (kvm_dirty_log_manual_protect_and_init_set(kvm) &&
> > + (offset + BITS_PER_LONG > split_end)) {
>
> [Severity: High]
> Does this comparison check an exclusive GFN against an inclusive GFN?
>
> The expression offset + BITS_PER_LONG calculates an exclusive boundary,
> while split_end is calculated below as an inclusive boundary:
>
> split_end = gpa_to_gfn(ALIGN_DOWN(end, PMD_SIZE) + PMD_SIZE - 1);
>
> Comparing these might cause a redundant split for the last 64-page batch
> of an already-split PMD.
>
It can not.
offset+bits_per_long has to be bigger than split_end. Since split_end is
the last bit of a level-2 block, it starts splitting again only if the
address > split_end.
> > + gpa_t start = gfn_to_gpa(offset + __ffs(mask));
> > + gpa_t end = gfn_to_gpa(offset + __fls(mask) + 1);
>
> [Severity: Low]
> This isn't a bug, but do these variables shadow the outer loop bounds?
>
> The variables start and end declared here share names with the loop bounds:
>
Yes, they are used as loop bounds.
No they are not re-declared inside a loop, so it should be fine.
> u64 start, end;
> ...
> for (unsigned long i = start; i < end; i++) {
>
> While scoping rules use the correct variables, shadowing loop control
> variables might make the code prone to subtle bugs during future refactoring.
>
> > +
> > + kvm_mmu_split_huge_pages(kvm, start, end);
> > + split_end = gpa_to_gfn(ALIGN_DOWN(end, PMD_SIZE) + PMD_SIZE - 1);
>
> [Severity: High]
> Can this alignment skip splitting for the next PMD?
>
> The variable end is an exclusive physical address:
>
> gpa_t end = gfn_to_gpa(offset + __fls(mask) + 1);
>
> If a block of dirty pages ends exactly at a PMD boundary, ALIGN_DOWN() on
> the exclusive end address aligns it to that boundary. Adding PMD_SIZE - 1
> then advances split_end to the end of the next PMD.
Okay, because this end is non-inclusive in kvm_mmu_split_huge_pages, but
for split_end it will cause to use the next block of address.
>
> This would skip huge page splitting for the adjacent PMD, breaking dirty
> logging and potentially causing data corruption during live migration as
> dirty pages would not be tracked at the PTE level.
I need to fix this in v3.
>
> > + }
> >
> > do {
> > idx = mask_to_hdbss(&mask, hw_entries, offset, ttwl, idx, entries_sz);
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260629111820.1873540-1-leo.bras@arm.com?part=9
next prev parent reply other threads:[~2026-06-29 17:07 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 11:17 [PATCH v2 00/13] KVM Dirty-bit cleaning hw accelerator (HACDBS) Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 01/13] KVM: arm64: HDBSS bits Leonardo Bras
2026-06-29 11:34 ` sashiko-bot
2026-06-29 12:57 ` Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 02/13] KVM: arm64: Enable eager hugepage splitting if HDBSS is available Leonardo Bras
2026-06-29 11:36 ` sashiko-bot
2026-06-29 14:47 ` Leonardo Bras
2026-06-29 17:06 ` Oliver Upton
2026-06-30 12:58 ` Leonardo Bras
2026-06-30 15:44 ` Oliver Upton
2026-06-30 17:09 ` Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 03/13] arm64/cpufeature: Add system-wide FEAT_HACDBS detection Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 04/13] arm64/sysreg: Add HACDBS consumer and base registers Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 05/13] KVM: arm64: Detect (via ACPI) and initialize HACDBSIRQ Leonardo Bras
2026-06-29 11:32 ` sashiko-bot
2026-06-29 15:43 ` Leonardo Bras
2026-06-29 16:52 ` Vladimir Murzin
2026-06-30 14:52 ` Leonardo Bras
2026-06-29 17:22 ` Oliver Upton
2026-06-30 14:50 ` Leonardo Bras
2026-06-30 16:03 ` Oliver Upton
2026-06-30 17:19 ` Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 06/13] KVM: arm64: dirty_bit: Add base FEAT_HACDBS cleaning routine Leonardo Bras
2026-06-29 11:29 ` sashiko-bot
2026-06-29 15:54 ` Leonardo Bras
2026-06-29 17:36 ` Oliver Upton
2026-06-30 14:59 ` Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 07/13] kvm: Add arch-generic interface for hw-accelerated dirty-bitmap cleaning Leonardo Bras
2026-06-29 11:38 ` sashiko-bot
2026-06-29 16:07 ` Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 08/13] KVM: arm64: Add hardware-accelerated dirty-bitmap cleaning routine Leonardo Bras
2026-06-29 11:45 ` sashiko-bot
2026-06-29 16:49 ` Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 09/13] KVM: arm64: Dirty-bitmap: avoid splitting previously split blocks Leonardo Bras
2026-06-29 11:39 ` sashiko-bot
2026-06-29 17:07 ` Leonardo Bras [this message]
2026-06-29 11:17 ` [PATCH v2 10/13] kvm/dirty_ring: Introduce get_memslot and move helpers to header Leonardo Bras
2026-06-29 11:17 ` [PATCH v2 11/13] kvm/dirty_ring: Add arch-generic interface for hw-accelerated dirty-ring cleaning Leonardo Bras
2026-06-29 11:49 ` sashiko-bot
2026-06-29 17:09 ` Leonardo Bras
2026-06-29 11:18 ` [PATCH v2 12/13] KVM: arm64: Add hardware-accelerated dirty-ring cleaning routine Leonardo Bras
2026-06-29 11:49 ` sashiko-bot
2026-06-29 17:26 ` Leonardo Bras
2026-06-29 11:18 ` [PATCH v2 13/13] KVM: arm64: Enable KVM_HW_DIRTY_BIT Leonardo Bras
2026-06-29 11:52 ` sashiko-bot
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=akKma9XqQcurXLa2@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox