Re: [PATCH v3 07/11] KVM: arm64: Dirty-bitmap: avoid splitting previously split blocks

Leonardo Bras <[email protected]> Mon, 3 Aug 2026 16:54:22 +0100
Newsgroups dev.linux.lists.kvmarm,dev.linux.lists.sashiko-reviews,org.kernel.vger.kvm
Message-ID <anC5rniXDZNFGfvy@LeoBrasDK>
On Wed, Jul 29, 2026 at 11:08:54AM +0000, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] Dropping `mmu_lock` during eager page splitting creates a race window that can permanently lose hardware-managed dirty bits (FEAT_HAFDBS), leading to silent guest data corruption during live migration.
> --
> 
> --- Patch [7]: [PATCH v3 07/11] KVM: arm64: Dirty-bitmap: avoid splitting previously split blocks ---
> commit fb963a566e307a780c669718446f8bf7c2c6ef94
> Author: Leonardo Bras <[email protected]>
> 
> 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
> > index 5a6266205295e..d7e624f9b6308 100644
> > --- a/arch/arm64/kvm/dirty_bit.c
> > +++ b/arch/arm64/kvm/dirty_bit.c
> > @@ -295,10 +296,15 @@ 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)) {
> > +			gpa_t split_start = gfn_to_gpa(offset + __ffs(mask));
> > +			gpa_t split_end =  gfn_to_gpa(offset + __fls(mask) + 1);
> > +
> > +			if (split_end > last_split) {
> > +				kvm_mmu_split_huge_pages(kvm, split_start, split_end);
> 
> [Severity: High]
> Can this sequence lose dirty state due to a race with hardware dirty bit
> management?
> 
> In __kvm_arch_dirty_log_clear(), the software dirty_bitmap for the target pages
> is fetched and cleared before reaching this point.
> 
> When kvm_mmu_split_huge_pages() is called, it can temporarily drop
> kvm->mmu_lock to allocate memory.
> 
> During this unlocked window, a vCPU could locklessly write to the page. With
> FEAT_HAFDBS enabled, the hardware automatically sets the PTE dirty bit without
> trapping to KVM.
> 
> After the lock is reacquired, the loop proceeds to dirty_bit_clear(), which
> unconditionally clears the hardware PTE dirty bit (via FEAT_HACDBS).
> 
> Because the software bitmap was already cleared and the hardware state is wiped
> without feeding the dirty state back, could a write during the unlocked window
> be permanently lost if userspace reads the page data before the clear operation?
> The next KVM_GET_DIRTY_LOG would not see it.

The bit, if was clear before the current KVM_GET_DIRTY_LOG(), will be set 
in the dirty-bitmap. HACDBS will not clean it, but sw fallback could.
In any case, it will be requested to be clean (again) in the next 
iteration.

This is the same as software dirty-bit cleaning. 

Leo