]> xenbits.xensource.com Git - qemu-upstream-4.2-testing.git/commitdiff
xen: Set the vram dirty when an error occurs.
authorAnthony PERARD <anthony.perard@citrix.com>
Thu, 21 Feb 2013 12:16:42 +0000 (12:16 +0000)
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>
Thu, 21 Feb 2013 12:16:42 +0000 (12:16 +0000)
If the call to xc_hvm_track_dirty_vram() fails, then we set dirtybit on all the
video ram. This case happens during migration.

Backport of 8aba7dc02d5660df7e7d8651304b3079908358be

This backport is less clean that it might be because there is no
memory_region_set_dirty that copes with more than one page in 4.2,
and the case where the call to xc_hvm_track_dirty_vram is
successful also needs to ensure xen_modified_memory is
called (which would on unstable have been done within
memory_region_set_dirty).

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Alex Bligh <alex@alex.org.uk>
xen-all.c

index 121289da7d7f6d491653b88237d9648b5dc5ac2e..dbd759cb05cd7aa028508c4797c498652966e274 100644 (file)
--- a/xen-all.c
+++ b/xen-all.c
@@ -470,7 +470,21 @@ static int xen_sync_dirty_bitmap(XenIOState *state,
     rc = xc_hvm_track_dirty_vram(xen_xc, xen_domid,
                                  start_addr >> TARGET_PAGE_BITS, npages,
                                  bitmap);
-    if (rc) {
+    if (rc < 0) {
+        if (rc != -ENODATA) {
+            ram_addr_t addr, end;
+
+            xen_modified_memory(start_addr, size);
+            
+            end = TARGET_PAGE_ALIGN(start_addr + size);
+            for (addr = start_addr & TARGET_PAGE_MASK; addr < end; addr += TARGET_PAGE_SIZE) {
+                cpu_physical_memory_set_dirty(addr);
+            }
+
+            DPRINTF("xen: track_dirty_vram failed (0x" TARGET_FMT_plx
+                    ", 0x" TARGET_FMT_plx "): %s\n",
+                    start_addr, start_addr + size, strerror(-rc));
+        }
         return rc;
     }
 
@@ -479,7 +493,9 @@ static int xen_sync_dirty_bitmap(XenIOState *state,
         while (map != 0) {
             j = ffsl(map) - 1;
             map &= ~(1ul << j);
-            cpu_physical_memory_set_dirty(vram_offset + (i * width + j) * TARGET_PAGE_SIZE);
+            target_phys_addr_t todirty = vram_offset + (i * width + j) * TARGET_PAGE_SIZE;
+            xen_modified_memory(todirty, TARGET_PAGE_SIZE);
+            cpu_physical_memory_set_dirty(todirty);
         };
     }