@@ -2025,6 +2025,8 @@ static void machvirt_init(MachineState *machine)
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
MachineClass *mc = MACHINE_GET_CLASS(machine);
const CPUArchIdList *possible_cpus;
+ const char *gictype = NULL;
+ const char *itsclass = NULL;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *secure_sysmem = NULL;
MemoryRegion *tag_sysmem = NULL;
@@ -2072,6 +2074,30 @@ static void machvirt_init(MachineState *machine)
*/
finalize_gic_version(vms);
+ /*
+ * When "kvm-arm-gicv3" or "arm-its-kvm" is used, the backup dirty
+ * bitmap has to be enabled for KVM dirty ring, before any memory
+ * slot is added. Otherwise, the migration will fail with the dirty
+ * ring.
+ */
+ if (kvm_enabled()) {
+ if (vms->gic_version != VIRT_GIC_VERSION_2) {
+ gictype = gicv3_class_name();
+ }
+
+ if (vms->gic_version != VIRT_GIC_VERSION_2 && vms->its) {
+ itsclass = its_class_name();
+ }
+
+ if (((gictype && !strcmp(gictype, "kvm-arm-gicv3")) ||
+ (itsclass && !strcmp(itsclass, "arm-its-kvm"))) &&
+ !kvm_arm_enable_dirty_ring_with_bitmap()) {
+ error_report("Failed to enable the backup bitmap for "
+ "KVM dirty ring");
+ exit(1);
+ }
+ }
+
if (vms->secure) {
/*
* The Secure view of the world is the same as the NonSecure,
@@ -764,6 +764,31 @@ bool kvm_arm_steal_time_supported(void)
return kvm_check_extension(kvm_state, KVM_CAP_STEAL_TIME);
}
+bool kvm_arm_enable_dirty_ring_with_bitmap(void)
+{
+ int ret;
+
+ /* No need to enable the backup bitmap if dirty ring isn't enabled */
+ if (!kvm_dirty_ring_enabled()) {
+ return true;
+ }
+
+ ret = kvm_check_extension(kvm_state, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP);
+ if (!ret) {
+ return false;
+ }
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP,
+ 0, 1);
+ if (ret) {
+ return false;
+ }
+
+ kvm_state->kvm_dirty_ring_with_bitmap = true;
+
+ return true;
+}
+
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
uint32_t kvm_arm_sve_get_vls(CPUState *cs)
@@ -282,6 +282,13 @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp);
*/
bool kvm_arm_steal_time_supported(void);
+/**
+ * kvm_arm_enable_dirty_ring_with_bitmap:
+ * Returns: true if KVM dirty ring's backup bitmap is enabled
+ * and false otherwise.
+ */
+bool kvm_arm_enable_dirty_ring_with_bitmap(void);
+
/**
* kvm_arm_aarch32_supported:
*
@@ -395,6 +402,11 @@ static inline bool kvm_arm_steal_time_supported(void)
return false;
}
+static inline bool kvm_arm_enable_dirty_ring_with_bitmap(void)
+{
+ return false;
+}
+
/*
* These functions should never actually be called without KVM support.
*/
When KVM device "kvm-arm-gicv3" or "arm-its-kvm" is used, we have to enable the backup bitmap for the dirty ring. Otherwise, the migration will fail because those two devices are using the backup bitmap to track dirty guest memory, corresponding to various hardware tables. Signed-off-by: Gavin Shan <gshan@redhat.com> --- hw/arm/virt.c | 26 ++++++++++++++++++++++++++ target/arm/kvm64.c | 25 +++++++++++++++++++++++++ target/arm/kvm_arm.h | 12 ++++++++++++ 3 files changed, 63 insertions(+)