From: Leonardo Bras <leo.bras@arm.com>
To: sashiko-reviews@lists.linux.dev
Cc: Leonardo Bras <leo.bras@arm.com>,
kvm@vger.kernel.org, Marc Zyngier <maz@kernel.org>,
Oliver Upton <oupton@kernel.org>,
kvmarm@lists.linux.dev
Subject: Re: [PATCH v3 11/11] KVM: arm64: Enable KVM_HW_DIRTY_BIT
Date: Mon, 3 Aug 2026 17:38:40 +0100 [thread overview]
Message-ID: <anDEEJIfwbHmMi1X@LeoBrasDK> (raw)
In-Reply-To: <20260729112918.C51721F000E9@smtp.kernel.org>
On Wed, Jul 29, 2026 at 11:29:18AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [Critical] Direct accesses to EL2 system registers from EL1 cause host panics on nVHE and pKVM configurations.
> - [High] Writes to control-plane system registers are missing immediate `isb()` synchronization instructions.
> - [High] Unbounded hardware polling loop with preemption disabled.
> - [Medium] Preempt notifier is registered within an atomic section where preemption is inherently disabled.
> --
>
> --- Patch [11]: [PATCH v3 11/11] KVM: arm64: Enable KVM_HW_DIRTY_BIT ---
> commit 9dec1efff0823ef68d8ee166e3fa545263373c0f
> Author: Leonardo Bras <leo.bras@arm.com>
>
> KVM: arm64: Enable KVM_HW_DIRTY_BIT
>
> Set the corresponding bit to enable hardware accelerated dirty-bitmap and
> dirty-ring cleaning for arm64. Actually using acceleration depends on the
> cpus enabling FEAT_HACDBS as well as the pre-requisite features for it,
> such as FEAT_HDBSS and FEAT_HAFDBS.
>
> > diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> > index 449154f9a4852..3264d8ca093e3 100644
> > --- a/arch/arm64/kvm/Kconfig
> > +++ b/arch/arm64/kvm/Kconfig
> > @@ -34,6 +34,7 @@ menuconfig KVM
> > select HAVE_KVM_IRQ_BYPASS
> > select HAVE_KVM_READONLY_MEM
> > select HAVE_KVM_VCPU_RUN_PID_CHANGE
> > + select HAVE_KVM_HW_DIRTY_BIT
> > select SCHED_INFO
> > select GUEST_PERF_EVENTS if PERF_EVENTS
> > select KVM_GUEST_MEMFD
> > diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
> > new file mode 100644
> > index 0000000000000..ca9cfefe0893b
> > --- /dev/null
> > +++ b/arch/arm64/kvm/dirty_bit.c
> > @@ -0,0 +1,438 @@
> [ ... ]
> > +static void hacdbs_start(u64 *hw_entries, int size)
> > +{
> > + u64 br;
> > + /* Each entry is 8 bytes */
> > + int size_b = size * sizeof(hw_entries[0]);
> > + int size_p2 = max(roundup_pow_of_two(size_b), PAGE_SIZE);
> > +
> > + /* If not using the full size of the array, put a stop entry at the end */
> > + if (size_b < size_p2)
> > + hw_entries[size] = HDBSS_ENTRY_VALID | HDBSS_ENTRY_TTWL_RESV;
> > +
> > + sysreg_clear_set_s(SYS_HACDBSCONS_EL2,
> > + HACDBSCONS_EL2_ERR_REASON | HACDBSCONS_EL2_INDEX, 0);
>
> [Severity: Critical]
> Can this code cause a host panic on nVHE and pKVM configurations?
It's VHE only
>
> The code directly attempts to read and write EL2 registers, which triggers
> a synchronous undefined exception at EL1. Since kvm_arch_dirty_clear_enabled()
> only checks for system_supports_hacdbs() and does not enforce has_vhe(),
> could an unprivileged userspace application reliably crash the host by
> triggering this on non-VHE hardware?
>
> [Severity: High]
> Does this code allow the CPU pipeline to observe architecturally undefined
> state?
>
> The ARM64 subsystem rules require an isb() as the very next instruction
> following a control-plane sysreg write. Here, SYS_HACDBSCONS_EL2 is modified
> but several instructions and variable assignments occur before an isb() is
> reached.
Already commented on a early patch.
>
> > +
> > + br = (virt_to_phys(hw_entries) & HACDBSBR_EL2_BADDR_MASK) |
> > + FIELD_PREP(HACDBSBR_EL2_SZ, ilog2(size_p2) - 12) |
> > + FIELD_PREP(HACDBSBR_EL2_EN, 1);
> > +
> > + /* All writes to the array have to complete before starting */
> > + dsb(ishst);
> > +
> > + write_sysreg_s(br, SYS_HACDBSBR_EL2);
> > + isb();
> > +}
> [ ... ]
> > +static void hacdbs_sched_in(struct preempt_notifier *notifier, int cpu)
> > +{
> > + struct hacdbs_sched_save *save = container_of(notifier,
> > + struct hacdbs_sched_save,
> > + notifier);
> > +
> > + write_sysreg_s(save->save.vtcr_el2, SYS_VTCR_EL2);
> > + write_sysreg_s(save->save.vttbr_el2, SYS_VTTBR_EL2);
> > + isb();
>
> [Severity: High]
> Can this missing synchronization lead to unpredictable execution?
>
> The ARM64 subsystem rules require an isb() as the very next instruction
> following a control-plane sysreg write, but SYS_VTCR_EL2 is written followed
> by SYS_VTTBR_EL2 before the isb() is issued.
>
iden
> > +
> > + if (save->save.hcr_vm_set) {
> > + sysreg_clear_set_hcr(0, HCR_EL2_VM);
> > + isb();
> > + }
> > +
> > + write_sysreg_s(save->save.hacdbscons_el2, SYS_HACDBSCONS_EL2);
> > + write_sysreg_s(save->save.hacdbsbr_el2, SYS_HACDBSBR_EL2);
> > + isb();
>
> [Severity: High]
> Is another isb() required here?
>
> SYS_HACDBSCONS_EL2 is written followed by SYS_HACDBSBR_EL2 without
> an intervening isb(). Does this sequence allow the CPU pipeline to observe
> stale configurations?
>
iden
> > +}
> [ ... ]
> > +static int dirty_bit_clear(struct kvm *kvm, u64 *hw_entries, int size)
> > +{
> > + int ret;
> > + u64 cons;
> > + struct hacdbs_sched_save save;
> > +
> > + preempt_notifier_init(&save.notifier, &hacdbs_preempt_ops);
> > + preempt_disable();
> > + preempt_notifier_register(&save.notifier);
> > + preempt_enable();
>
> [Severity: Medium]
> Are these preempt notifiers effectively dead code on standard kernels?
>
> The calling functions (__kvm_arch_dirty_log_clear and
> __kvm_arch_dirty_ring_clear) acquire write_lock(&kvm->mmu_lock) before
> this code runs.
>
> Since the mmu_lock rwlock already disables preemption, this region cannot be
> preempted. If the hardware cleaning takes a long time, won't the thread
> stall rather than cleanly context switching?
>
iden
> > +
> > + __load_stage2(&kvm->arch.mmu);
> > + sysreg_clear_set_hcr(0, HCR_EL2_VM);
> > + isb();
>
> [Severity: Critical]
> Does this code also trigger a synchronous undefined exception at EL1?
>
> Directly attempting to access EL2 registers from EL1 causes traps on non-VHE
> hardware.
>
iden
> > +
> > + hacdbs_start(hw_entries, size);
> > +
> > + do {
> > + cons = read_sysreg_s(SYS_HACDBSCONS_EL2);
> > + if (FIELD_GET(HACDBSCONS_EL2_ERR_REASON, cons))
> > + break;
> > +
> > + if (FIELD_GET(HACDBSCONS_EL2_INDEX, cons) >= size)
> > + break;
> > +
> > + udelay(1);
> > + } while (true);
>
> [Severity: High]
> Could this unbounded polling loop cause a hard lockup?
>
> Since this runs under write_lock(&kvm->mmu_lock) with preemption disabled,
> if the hardware accelerator hangs, takes unusually long, or fails to set an
> error reason, the CPU will stall indefinitely. Should there be a timeout or
> fallback mechanism here?
iden
Leo
prev parent reply other threads:[~2026-08-03 16:38 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
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 [this message]
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=anDEEJIfwbHmMi1X@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.