[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 01/87] kvm: Reallocate dirty_bmap when we change a slot
From: |
Paolo Bonzini |
Subject: |
[PULL 01/87] kvm: Reallocate dirty_bmap when we change a slot |
Date: |
Wed, 18 Dec 2019 13:01:27 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
kvm_set_phys_mem can be called to reallocate a slot by something the
guest does (e.g. writing to PAM and other chipset registers).
This can happen in the middle of a migration, and if we're unlucky
it can now happen between the split 'sync' and 'clear'; the clear
asserts if there's no bmap to clear. Recreate the bmap whenever
we change the slot, keeping the clear path happy.
Typically this is triggered by the guest rebooting during a migrate.
Corresponds to:
https://bugzilla.redhat.com/show_bug.cgi?id=1772774
https://bugzilla.redhat.com/show_bug.cgi?id=1771032
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
Reviewed-by: Peter Xu <address@hidden>
---
accel/kvm/kvm-all.c | 44 +++++++++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ca00daa..7b9f92d 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -518,6 +518,27 @@ static int
kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))
+/* Allocate the dirty bitmap for a slot */
+static void kvm_memslot_init_dirty_bitmap(KVMSlot *mem)
+{
+ /*
+ * XXX bad kernel interface alert
+ * For dirty bitmap, kernel allocates array of size aligned to
+ * bits-per-long. But for case when the kernel is 64bits and
+ * the userspace is 32bits, userspace can't align to the same
+ * bits-per-long, since sizeof(long) is different between kernel
+ * and user space. This way, userspace will provide buffer which
+ * may be 4 bytes less than the kernel will use, resulting in
+ * userspace memory corruption (which is not detectable by valgrind
+ * too, in most cases).
+ * So for now, let's align to 64 instead of HOST_LONG_BITS here, in
+ * a hope that sizeof(long) won't become >8 any time soon.
+ */
+ hwaddr bitmap_size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
+ /*HOST_LONG_BITS*/ 64) / 8;
+ mem->dirty_bmap = g_malloc0(bitmap_size);
+}
+
/**
* kvm_physical_sync_dirty_bitmap - Sync dirty bitmap from kernel space
*
@@ -550,23 +571,9 @@ static int
kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
goto out;
}
- /* XXX bad kernel interface alert
- * For dirty bitmap, kernel allocates array of size aligned to
- * bits-per-long. But for case when the kernel is 64bits and
- * the userspace is 32bits, userspace can't align to the same
- * bits-per-long, since sizeof(long) is different between kernel
- * and user space. This way, userspace will provide buffer which
- * may be 4 bytes less than the kernel will use, resulting in
- * userspace memory corruption (which is not detectable by valgrind
- * too, in most cases).
- * So for now, let's align to 64 instead of HOST_LONG_BITS here, in
- * a hope that sizeof(long) won't become >8 any time soon.
- */
if (!mem->dirty_bmap) {
- hwaddr bitmap_size = ALIGN(((mem->memory_size) >>
TARGET_PAGE_BITS),
- /*HOST_LONG_BITS*/ 64) / 8;
/* Allocate on the first log_sync, once and for all */
- mem->dirty_bmap = g_malloc0(bitmap_size);
+ kvm_memslot_init_dirty_bitmap(mem);
}
d.dirty_bitmap = mem->dirty_bmap;
@@ -1067,6 +1074,13 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
mem->ram = ram;
mem->flags = kvm_mem_flags(mr);
+ if (mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
+ /*
+ * Reallocate the bmap; it means it doesn't disappear in
+ * middle of a migrate.
+ */
+ kvm_memslot_init_dirty_bitmap(mem);
+ }
err = kvm_set_user_memory_region(kml, mem, true);
if (err) {
fprintf(stderr, "%s: error registering slot: %s\n", __func__,
--
1.8.3.1
- [PULL 00/87] Misc patches for 2019-12-18, Paolo Bonzini, 2019/12/18
- [PULL 01/87] kvm: Reallocate dirty_bmap when we change a slot,
Paolo Bonzini <=
- [PULL 02/87] migration-test: Create cmd_soure and cmd_target, Paolo Bonzini, 2019/12/18
- [PULL 03/87] migration-test: Move hide_stderr to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 04/87] migration-test: Move -machine to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 06/87] migration-test: Move shmem handling to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 05/87] migration-test: Move memory size to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 07/87] migration-test: Move -name handling to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 08/87] migration-test: Move -serial handling to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 09/87] migration-test: Move -incomming handling to common commandline, Paolo Bonzini, 2019/12/18
- [PULL 14/87] tcg: move qemu_tcg_configure to accel/tcg/tcg-all.c, Paolo Bonzini, 2019/12/18
- [PULL 15/87] vl: extract accelerator option processing to a separate function, Paolo Bonzini, 2019/12/18