diff options
authorIgor Mitsyanko <i.mitsyanko@samsung.com>2012-08-10 18:45:11 +0400
committerBlue Swirl <blauwirbel@gmail.com>2012-08-11 12:23:46 +0000
commit5fda043f9c8b8ab18da2704de8e77b7c86fa9435 (patch)
parent0521d375a154a27d90eabab035303c6806a37920 (diff)
exec.c: fix dirty bitmap reallocation
For each newly created RAM block, dirty bitmap is reallocated with g_realloc, which doesn't make any promises on initial content of new extra data in returned buffer. In theory, we initialize this new data with cpu_physical_memory_set_dirty_range() call. The problem is, cpu_physical_memory_set_dirty_range() has a side effect of incrementing ram_list.dirty_pages variable, but only for pages which are not already dirty. And page "cleanliness" is determined using the same not yet uninitialized dirty bitmap we've just reallocated. This results in inconsistency between real dirty page number and value in ram_list.dirty_pages variable, which in turn could (and will) result in errors during VM migration. Zero initialize new dirty bitmap bytes to fix this problem. Signed-off-by: Igor Mitsyanko <i.mitsyanko@samsung.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
1 files changed, 2 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index a42a0b5b78..929db5cf0a 100644
--- a/exec.c
+++ b/exec.c
@@ -2550,6 +2550,8 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
last_ram_offset() >> TARGET_PAGE_BITS);
+ memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
+ 0, size >> TARGET_PAGE_BITS);
cpu_physical_memory_set_dirty_range(new_block->offset, size, 0xff);
if (kvm_enabled())