Add a boolean 'hdbss' accelerator property (default: on) to allow enabling or disabling HDBSS hardware dirty tracking per VM via KVM_CAP_ARM_HDBSS (cap 252). Usage: -accel kvm,hdbss=on (default, enables HDBSS) -accel kvm,hdbss=off (disables HDBSS for comparison testing) A fallback define is provided for KVM_CAP_ARM_HDBSS in case the installed kernel headers do not yet have the definition. --- accel/kvm/kvm-all.c | 48 ++++++++++++++++++++++++++++++++++++++++ include/sysemu/kvm_int.h | 1 + 2 files changed, 49 insertions(+) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index c5cb768c9c..495f1c9d44 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -19,6 +19,10 @@ #include <linux/kvm.h> +#ifndef KVM_CAP_ARM_HDBSS +#define KVM_CAP_ARM_HDBSS 252 +#endif + #include "qemu/atomic.h" #include "qemu/option.h" #include "qemu/config-file.h" @@ -2648,6 +2652,14 @@ static int kvm_init(MachineState *ms) goto err; } + ret = kvm_vm_check_extension(s, KVM_CAP_ARM_HDBSS); + if (ret > 0) { + ret = kvm_vm_enable_cap(s, KVM_CAP_ARM_HDBSS, 0, s->kvm_hdbss ? 1 : 0); + if (ret < 0) { + goto err; + } + } + /* * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no @@ -3812,6 +3824,35 @@ static void kvm_get_dirty_ring_size(Object *obj, Visitor *v, visit_type_uint32(v, name, &value, errp); } +static void kvm_get_hdbss(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + KVMState *s = KVM_STATE(obj); + bool value = s->kvm_hdbss; + + visit_type_bool(v, name, &value, errp); +} + +static void kvm_set_hdbss(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + KVMState *s = KVM_STATE(obj); + bool value; + + if (s->fd != -1) { + error_setg(errp, "Cannot set properties after the accelerator has been initialized"); + return; + } + + if (!visit_type_bool(v, name, &value, errp)) { + return; + } + + s->kvm_hdbss = value; +} + static void kvm_set_dirty_ring_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -3854,6 +3895,7 @@ static void kvm_accel_instance_init(Object *obj) s->kvm_smccc_filter_enabled = false; s->kvm_eager_split_size = 0; s->kvm_hdbss_buffer_size = 0; + s->kvm_hdbss = true; s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN; s->notify_window = 0; s->xen_version = 0; @@ -3899,6 +3941,12 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "dirty-ring-size", "Size of KVM dirty page ring buffer (default: 0, i.e. use bitmap)"); + object_class_property_add(oc, "hdbss", "bool", + kvm_get_hdbss, kvm_set_hdbss, + NULL, NULL); + object_class_property_set_description(oc, "hdbss", + "Enable/disable HDBSS hardware dirty tracking (on/off, default: on)"); + kvm_arch_accel_class_init(oc); } diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index 68e9d21652..9268f7b18b 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -114,6 +114,7 @@ struct KVMState uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */ bool kvm_dirty_ring_with_bitmap; bool kvm_smccc_filter_enabled; + bool kvm_hdbss; /* Enable/disable HDBSS hardware dirty tracking */ 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; -- 2.33.0