mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Virt

Threads by month
  • ----- 2026 -----
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
virt@openeuler.org

September 2026

  • 1 participants
  • 2 discussions
[PATCH 1/3] kvm: Add hdbss-buffer-size accelerator property for HDBSS buffer configuration
by Tian Zheng 04 Sep '26

04 Sep '26
From: AkiraZheng <1428384878(a)qq.com> Add a new KVM accelerator property 'hdbss-buffer-size' that allows userspace to configure the HDBSS (Hardware Dirty Bit State Structure) buffer size per-VM before vCPUs are created. The property accepts a size in entries (number of u64 slots), matching the convention of dirty-ring-size which also uses entries as the user-facing unit. QEMU converts entries to bytes (entries * sizeof(u64)) before passing to the KVM_ENABLE_CAP ioctl, consistent with how dirty-ring-size converts entries to bytes (entries * sizeof(kvm_dirty_gfn)). hdbss-buffer-size and dirty-ring-size are mutually exclusive: setting one while the other is already set returns an error. In dirty-ring mode, the kernel auto-configures the HDBSS buffer size based on the dirty ring size (see kvm_arch_dirty_ring_size_updated). Usage: -accel kvm,hdbss-buffer-size=512 When set to 0 (default), the kernel uses its default buffer size (PAGE_SIZE / sizeof(u64) entries per vCPU). Signed-off-by: AkiraZheng <1428384878(a)qq.com> --- accel/kvm/kvm-all.c | 5 ++++ include/sysemu/kvm_int.h | 1 + linux-headers/linux/kvm.h | 1 + qemu-options.hx | 1 + target/arm/kvm.c | 57 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 4f2a84c94c..c5cb768c9c 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3831,6 +3831,10 @@ static void kvm_set_dirty_ring_size(Object *obj, Visitor *v, error_setg(errp, "dirty-ring-size must be a power of two."); return; } + if (value && s->kvm_hdbss_buffer_size) { + error_setg(errp, "dirty-ring-size and hdbss-buffer-size are mutually exclusive"); + return; + } s->kvm_dirty_ring_size = value; } @@ -3849,6 +3853,7 @@ static void kvm_accel_instance_init(Object *obj) s->kvm_dirty_ring_with_bitmap = false; s->kvm_smccc_filter_enabled = false; s->kvm_eager_split_size = 0; + s->kvm_hdbss_buffer_size = 0; s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN; s->notify_window = 0; s->xen_version = 0; diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index 7b90117a86..68e9d21652 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -115,6 +115,7 @@ struct KVMState bool kvm_dirty_ring_with_bitmap; bool kvm_smccc_filter_enabled; uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */ + uint32_t kvm_hdbss_buffer_size; /* HDBSS buffer size in entries per vCPU */ struct KVMDirtyRingReaper reaper; NotifyVmexitOption notify_vmexit; uint32_t notify_window; diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 15c55c7f82..0ef9a8a6b5 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1243,6 +1243,7 @@ struct kvm_ppc_resize_hpt { /* support userspace to request management of CSV3 shared pages */ #define KVM_CAP_HYGON_COCO_EXT_CSV3_SP_MGR (1 << 4) +#define KVM_CAP_ARM_HDBSS_BUFFER_SIZE 251 #define KVM_CAP_ARM_HW_DIRTY_STATE_TRACK 502 #define KVM_CAP_ARM_TLBIDOMAIN 503 diff --git a/qemu-options.hx b/qemu-options.hx index 9c50a41c2a..3e4a58477a 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -187,6 +187,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel, " tb-size=n (TCG translation block cache size)\n" " dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n" " eager-split-size=n (KVM Eager Page Split chunk size, default 0, disabled. ARM only)\n" + " hdbss-buffer-size=n (KVM HDBSS buffer entry count, default 0, kernel default. ARM only)\n" " notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n" " thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL) SRST diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 435459632c..4d9ecbd0c2 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -417,6 +417,18 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } + if (s->kvm_hdbss_buffer_size) { + uint64_t buffer_bytes = (uint64_t)s->kvm_hdbss_buffer_size * sizeof(uint64_t); + + ret = kvm_vm_enable_cap(s, KVM_CAP_ARM_HDBSS_BUFFER_SIZE, 0, + buffer_bytes); + if (ret < 0) { + error_report("Enabling of HDBSS buffer size failed: %s", + strerror(-ret)); + return ret; + } + } + /* * To be able to handle PSCI CPU ON calls in QEMU, we need to install SMCCC * filter in the Host KVM. This is required to support features like @@ -1586,6 +1598,43 @@ static void kvm_arch_set_eager_split_size(Object *obj, Visitor *v, s->kvm_eager_split_size = value; } +static void kvm_arch_get_hdbss_buffer_size(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + KVMState *s = KVM_STATE(obj); + uint32_t value = s->kvm_hdbss_buffer_size; + + visit_type_uint32(v, name, &value, errp); +} + +static void kvm_arch_set_hdbss_buffer_size(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + KVMState *s = KVM_STATE(obj); + uint32_t value; + + if (s->fd != -1) { + error_setg(errp, "Cannot set hdbss-buffer-size after the accelerator has been initialized"); + return; + } + + if (!visit_type_uint32(v, name, &value, errp)) { + return; + } + if (value && (value & (value - 1))) { + error_setg(errp, "hdbss-buffer-size must be a power of two"); + return; + } + if (value && s->kvm_dirty_ring_size) { + error_setg(errp, "hdbss-buffer-size and dirty-ring-size are mutually exclusive"); + return; + } + + s->kvm_hdbss_buffer_size = value; +} + static bool virt_get_ipiv(Object *obj, Error **errp) { KVMState *s = KVM_STATE(obj); @@ -1609,6 +1658,14 @@ void kvm_arch_accel_class_init(ObjectClass *oc) object_class_property_set_description(oc, "eager-split-size", "Eager Page Split chunk size for hugepages. (default: 0, disabled)"); + object_class_property_add(oc, "hdbss-buffer-size", "uint32", + kvm_arch_get_hdbss_buffer_size, + kvm_arch_set_hdbss_buffer_size, NULL, NULL); + + object_class_property_set_description(oc, "hdbss-buffer-size", + "HDBSS buffer size in entries for hardware dirty page tracking. " + "(default: 0, use kernel default. ARM only)"); + object_class_property_add_bool(oc, "ipiv", virt_get_ipiv, virt_set_ipiv); -- 2.33.0
1 2
0 0
[PATCH v5 0/8] Support the FEAT_HDBSS introduced in Armv9.5
by Tian Zheng 04 Sep '26

04 Sep '26
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-zhengtian… 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
1 8
0 0

HyperKitty Powered by HyperKitty