[PATCH v4 3/6] KVM: arm64: Add auto DBM support for hardware dirty tracking
Tian Zheng
zhengtian10 at huawei.com
Wed Jul 29 01:51:59 PDT 2026
On 7/20/2026 8:58 PM, Leonardo Bras wrote:
> On Fri, Jul 17, 2026 at 04:21:32PM +0100, Leonardo Bras wrote:
>> On Fri, Jul 17, 2026 at 11:58:06AM +0800, Tian Zheng wrote:
>>>
>>> On 7/16/2026 3:39 PM, Oliver Upton wrote:
>>>> Hi Tian,
>>>>
>>>> On Thu, Jul 09, 2026 at 06:40:23PM +0800, Tian Zheng wrote:
>>>>> - if (prot & KVM_PGTABLE_PROT_W)
>>>>> + if (prot & KVM_PGTABLE_PROT_W) {
>>>>> set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
>>>>>
>>>>> + /*
>>>>> + * No DEVICE filter needed here: relax_perms is only called
>>>>> + * on FSC_PERM faults. Device pages always get full RW from
>>>>> + * initial mapping and are never write-protected during
>>>>> + * migration, so they never trigger a permission fault.
>>>>> + */
>>>>> + if (pgt->flags & KVM_PGTABLE_S2_DBM)
>>>>> + set |= KVM_PTE_LEAF_ATTR_HI_S2_DBM;
>>>>> + } else {
>>>>> + /*
>>>>> + * Clear DBM on W→RO downgrade to prevent hardware from
>>>>> + * silently upgrading RO+DBM back to W+dirty, which would
>>>>> + * bypass KVM's write tracking and cause data corruption.
>>>>> + */
>>>>> + clr |= KVM_PTE_LEAF_ATTR_HI_S2_DBM;
>>>>> + }
>>>>> +
>>>> This block makes it pretty evident that the DBM bit really *is* the
>>>> write permission bit. I'd much rather we introduce the concept of dirty
>>>> state to the page table library and migrate the abstract write
>>>> permission to the DBM field, even if we don't have FEAT_HAFDBS.
>>>>
>>
>> Ohh, that's an amazing idea!
>
> Thinking about that again...
> If we adopt the encoding with DBM being the write-permission bit, and all
> PTEs have it since the start, how can we have lazy-splitting happening?
>
> Only way I think of is removing both DBM and S2_S2AP_W bit from writable
> PTEs during dirty-track enable, and re-adding them during the first write
> fault. If we don't remove the DBM bit, systems with HDBSS would just dirty
> it by hardware, without causing a fault.
>
> DBM=0 would need to happen only in the first write-protect (only on
> lazy-splitting). All other write-protecting would just clean the S2_S2AP_W
> bit, as everything is already split.
>
> Is that what was intended?
>
> Thanks!
> Leo
>
Hi Leo,
I think the cleanest way to handle this is to simply avoid setting DBM
on block mappings. If we only set DBM on page-level PTEs, then block
mappings will naturally stay DBM=0 and trigger a write fault on first
access — exactly what we need for lazy splitting.
When the fault occurs, the block gets split into page-level PTEs, and at
that point we can set DBM=1 on the resulting leaf entries. This way:
1. Lazy split works naturally (fault -> split -> set DBM=1)
2. No need to clear DBM globally at dirty-track enable
3. No special handling for block mappings
So I think global DBM is still viable — we just need to filter out block
mappings when setting the DBM bit. That way the lazy split path is
preserved without extra complexity.
More information about the linux-arm-kernel
mailing list