This series of patches add support to the Hardware Dirty state tracking Structure (HDBSS) feature, which is introduced by the ARM architecture in the DDI0601 (ID121123) version. The HDBSS feature is an extension to the architecture that enhances tracking translation table descriptors' dirty state, identified as FEAT_HDBSS. This feature utilizes hardware assistance to achieve dirty page tracking, aiming to significantly reduce the overhead of scanning for dirty pages. The purpose of this feature is to make the execution overhead of live migration lower to both the guest and the host, compared to existing approaches (write-protect or search stage-2 tables). The required sysreg definitions for FEAT_HDBSS have been merged into arm64 /sysregs: [1/5] arm64/sysreg: Add HDBSS related register information https://git.kernel.org/arm64/c/72f7be0c2e30 After these patches, the kernel automatically enables HDBSS when dirty logging is enabled on any memslot, and disables HDBSS when dirty logging is disabled on all memslots. This series supports both dirty-bitmap mode and dirty ring mode. v4: https://lore.kernel.org/linux-arm-kernel/20260709104026.2612599-1-zhengtian1... v4->v5 changes: - Drop Leonardo Bras' "Enable eager hugepage splitting if HDBSS is available" patch and the dependency on it. v5 supports lazy split natively: stage2_attr_walker() strips DBM from block entries (level < KVM_PGTABLE_LAST_LEVEL) during write-protect, forcing blocks into the NW state so a guest write generates a permission fault that triggers the existing lazy split path to break the block down to level-3 pages. Level-3 pages keep DBM, staying in WC state so the first guest write after write-protect marks the page dirty automatically. - Rework the DBM dirty tracking into a three-state model (NW/WC/WD). v4 set DBM conditionally through the KVM_PGTABLE_S2_DBM page-table flag; v5 sets DBM unconditionally on all writable pages and relies on VTCR_EL2.HD to decide whether hardware manages the WC->WD transition. This removes the KVM_PGTABLE_S2_DBM flag definition. Block DBM stripping is added per the point above. - Decouple the HDBSS buffer lifecycle from dirty logging state: buffers are pre-allocated at vCPU creation time (when hardware supports HDBSS) and freed at vCPU destruction, instead of being allocated on enable and freed on disable. This eliminates cross-CPU state mutation during enable/disable and removes use-after-free risks. The per-VM enable_hdbss flag and hdbss_order are replaced by a single hdbss_buffer_size (in bytes); the buffer base_phys field is replaced by hdbss_pg plus buddy_order. A kvm_hdbss_buffer_size() helper falls back to the default (PAGE_SIZE) when unset. - Use a single HDBSS buffer flush point: the buffer is flushed on every VM exit in kvm_arch_vcpu_ioctl_run(), before handling the exit reason. This replaces the KVM_REQ_FLUSH_HDBSS request used in v4 (on vcpu_put, check_vcpu_requests and sync_dirty_log), ensuring entries pushed to the dirty ring are accounted for when check_vcpu_requests() runs dirty_ring_check_request() on the next loop iteration, preventing ring overflow. - Protect the flush with SRCU instead of mmu_lock. Flush can be called from kvm_arch_vcpu_ioctl_run() while holding the scheduler rq->lock, so taking mmu_lock there would risk an ABBA deadlock. - Enable/disable now touches VTCR only: it modifies the VTCR_EL2 bits and kicks all vCPUs out of guest mode, without allocating or freeing buffers. sync_dirty_log() uses kvm_for_each_vcpu() + kvm_vcpu_kick() instead of kvm_make_all_cpus_request(KVM_REQ_FLUSH_HDBSS), relying on the per-VM-exit flush to drain the buffer. - Add nested-virtualization-aware helpers: kvm_hdbss_enabled() tests kvm->arch.mmu.vtcr (L1 only), and vcpu_hdbss_enabled() tests hw_mmu->vtcr, filtering out vCPUs running a nested (L2) guest whose shadow stage-2 has no HDBSS bits. - Add KVM_CAP_ARM_HDBSS_BUFFER_SIZE (251) to let userspace configure the per-VM HDBSS buffer size before vCPUs are created. The size is specified in bytes via KVM_ENABLE_CAP, must be a power of two in the range [PAGE_SIZE, SZ_2M], and can only be set before any vCPU is created. KVM_CHECK_EXTENSION returns the configured size for a VM, or the maximum supported size (SZ_2M) when queried globally. - Add dirty ring mode support. v4 rejected dirty ring mode; v5 allows HDBSS to coexist with the dirty ring. In dirty ring mode the buffer is fixed at PAGE_SIZE to keep the reserved entries low and the soft_limit high, maximizing the drain interval, so userspace cannot override it via KVM_CAP_ARM_HDBSS_BUFFER_SIZE. A new generic kvm_arch_dirty_ring_size_updated() hook (called after dirty_ring_size is set) is overridden by arm64 to auto-configure the buffer, and kvm_cpu_dirty_log_size() reports the buffer entry count so the dirty ring framework computes correct rsvd/soft_limit values. - Add a KVM: arm64: Document HDBSS buffer size ioctl patch documenting the new capability in Documentation/virt/kvm/api.rst. - Add WARN_ON_ONCE guards for !system_supports_hdbss() and !vcpu_hdbss_enabled() in the fault handler to defend against non-VHE and nested contexts, and add a min_t() bounds check in the flush loop. Tian Zheng (6): KVM: arm64: Add support for FEAT_HDBSS KVM: arm64: Add auto DBM support for hardware dirty tracking KVM: arm64: Add auto HDBSS enable/disable on dirty logging change KVM: arm64: Add HDBSS buffer size ioctl for dirty-bitmap mode KVM: arm64: Support HDBSS with dirty ring mode KVM: arm64: Document HDBSS buffer size ioctl eillon (2): KVM: arm64: Add HDBSS per-vCPU buffer management KVM: arm64: Add HDBSS fault handling and buffer flush Documentation/virt/kvm/api.rst | 29 ++++ arch/arm64/include/asm/cpufeature.h | 5 + arch/arm64/include/asm/esr.h | 5 + arch/arm64/include/asm/kvm_dirty_bit.h | 75 +++++++++++ arch/arm64/include/asm/kvm_host.h | 13 ++ arch/arm64/include/asm/kvm_pgtable.h | 2 + arch/arm64/include/asm/sysreg.h | 9 ++ arch/arm64/kernel/cpufeature.c | 12 ++ arch/arm64/kvm/Makefile | 1 + arch/arm64/kvm/arm.c | 103 +++++++++++++- arch/arm64/kvm/dirty_bit.c | 179 +++++++++++++++++++++++++ arch/arm64/kvm/hyp/pgtable.c | 36 ++++- arch/arm64/kvm/hyp/vhe/switch.c | 16 +++ arch/arm64/kvm/mmu.c | 15 +++ arch/arm64/kvm/reset.c | 3 + arch/arm64/tools/cpucaps | 1 + include/linux/kvm_dirty_ring.h | 1 + include/uapi/linux/kvm.h | 1 + virt/kvm/dirty_ring.c | 4 + virt/kvm/kvm_main.c | 1 + 20 files changed, 507 insertions(+), 4 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_dirty_bit.h create mode 100644 arch/arm64/kvm/dirty_bit.c base-commit: a4ff2be345d0abc943da8dd8da98151843b750dc -- 2.33.0