Instead of each target knowing or guessing the guest page size,
just pass the desired size of dirtied memory area. This should also
improve performance due to memset() optimizations.
Signed-off-by: Blue Swirl <blauwir...@gmail.com>
---
 arch_init.c     |    3 ++-
 cpu-all.h       |    9 +++++++--
 hw/cirrus_vga.c |   18 ++++++++----------
 hw/g364fb.c     |   11 +++--------
 hw/qxl.c        |    5 +----
 hw/tcx.c        |   14 +++-----------
 hw/vga.c        |    6 +++---
 hw/vhost.c      |    2 +-
 kvm-all.c       |    8 +++++---
 memory.c        |    5 +++--
 memory.h        |    6 ++++--
 xen-all.c       |    4 +++-
 12 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index a411fdf..c77587e 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -281,7 +281,8 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int
stage, void *opaque)
                  addr += TARGET_PAGE_SIZE) {
                 if (!cpu_physical_memory_get_dirty(addr,
                                                    MIGRATION_DIRTY_FLAG)) {
-                    cpu_physical_memory_set_dirty(addr);
+                    cpu_physical_memory_range_set_dirty(addr,
+                                                        TARGET_PAGE_SIZE);
                 }
             }
         }
diff --git a/cpu-all.h b/cpu-all.h
index 7246a67..0cb62ca 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -535,9 +535,14 @@ static inline int
cpu_physical_memory_get_dirty(ram_addr_t addr,
     return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
 }

-static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
+static inline void cpu_physical_memory_range_set_dirty(ram_addr_t start,
+                                                       ram_addr_t size)
 {
-    ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
+    start >>= TARGET_PAGE_BITS;
+    size += TARGET_PAGE_SIZE - 1;
+    size >>= TARGET_PAGE_BITS;
+
+    memset(&ram_list.phys_dirty[start], 0xff, size);
 }

 static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index a11444c..728d9de 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -614,10 +614,7 @@ static void
cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
        off_cur = off_begin;
        off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
        off_cur &= TARGET_PAGE_MASK;
-       while (off_cur < off_cur_end) {
-           memory_region_set_dirty(&s->vga.vram, off_cur);
-           off_cur += TARGET_PAGE_SIZE;
-       }
+        memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
        off_begin += off_pitch;
     }
 }
@@ -1918,8 +1915,8 @@ static void
cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
        val <<= 1;
        dst++;
     }
-    memory_region_set_dirty(&s->vga.vram, offset);
-    memory_region_set_dirty(&s->vga.vram, offset + 7);
+    memory_region_set_dirty(&s->vga.vram, offset, 1);
+    memory_region_set_dirty(&s->vga.vram, offset + 7, 1);
 }

 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
@@ -1943,8 +1940,8 @@ static void
cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
        val <<= 1;
        dst += 2;
     }
-    memory_region_set_dirty(&s->vga.vram, offset);
-    memory_region_set_dirty(&s->vga.vram, offset + 15);
+    memory_region_set_dirty(&s->vga.vram, offset, 1);
+    memory_region_set_dirty(&s->vga.vram, offset + 15, 1);
 }

 /***************************************
@@ -2034,7 +2031,8 @@ static void cirrus_vga_mem_write(void *opaque,
                mode = s->vga.gr[0x05] & 0x7;
                if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
                    *(s->vga.vram_ptr + bank_offset) = mem_value;
-                   memory_region_set_dirty(&s->vga.vram, bank_offset);
+                    memory_region_set_dirty(&s->vga.vram, bank_offset,
+                                            sizeof(mem_value));
                } else {
                    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
                        cirrus_mem_writeb_mode4and5_8bpp(s, mode,
@@ -2306,7 +2304,7 @@ static void cirrus_linear_write(void *opaque,
target_phys_addr_t addr,
        mode = s->vga.gr[0x05] & 0x7;
        if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
            *(s->vga.vram_ptr + addr) = (uint8_t) val;
-           memory_region_set_dirty(&s->vga.vram, addr);
+            memory_region_set_dirty(&s->vga.vram, addr, 1);
        } else {
            if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
                cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 34fb08c..82cdaa3 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -268,12 +268,9 @@ static void g364fb_update_display(void *opaque)
 static inline void g364fb_invalidate_display(void *opaque)
 {
     G364State *s = opaque;
-    int i;

     s->blanked = 0;
-    for (i = 0; i < s->vram_size; i += G364_PAGE_SIZE) {
-        memory_region_set_dirty(&s->mem_vram, i);
-    }
+    memory_region_set_dirty(&s->mem_vram, 0, s->vram_size);
 }

 static void g364fb_reset(G364State *s)
@@ -385,7 +382,7 @@ static void g364fb_update_depth(G364State *s)

 static void g364_invalidate_cursor_position(G364State *s)
 {
-    int ymin, ymax, start, end, i;
+    int ymin, ymax, start, end;

     /* invalidate only near the cursor */
     ymin = s->cursor_position & 0xfff;
@@ -393,9 +390,7 @@ static void g364_invalidate_cursor_position(G364State *s)
     start = ymin * ds_get_linesize(s->ds);
     end = (ymax + 1) * ds_get_linesize(s->ds);

-    for (i = start; i < end; i += G364_PAGE_SIZE) {
-        memory_region_set_dirty(&s->mem_vram, i);
-    }
+    memory_region_set_dirty(&s->mem_vram, start, end - start);
 }

 static void g364fb_ctrl_write(void *opaque,
diff --git a/hw/qxl.c b/hw/qxl.c
index 41500e9..9cd36c4 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -343,10 +343,7 @@ static void init_qxl_ram(PCIQXLDevice *d)
 /* can be called from spice server thread context */
 static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
 {
-    while (addr < end) {
-        memory_region_set_dirty(mr, addr);
-        addr += TARGET_PAGE_SIZE;
-    }
+    memory_region_set_dirty(mr, addr, end - addr);
 }

 static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
diff --git a/hw/tcx.c b/hw/tcx.c
index a987357..fd45ce8 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -61,21 +61,13 @@ static void tcx24_screen_dump(void *opaque, const
char *filename);

 static void tcx_set_dirty(TCXState *s)
 {
-    unsigned int i;
-
-    for (i = 0; i < MAXX * MAXY; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_mem, i);
-    }
+    memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
 }

 static void tcx24_set_dirty(TCXState *s)
 {
-    unsigned int i;
-
-    for (i = 0; i < MAXX * MAXY * 4; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_mem, s->vram24_offset + i);
-        memory_region_set_dirty(&s->vram_mem, s->cplane_offset + i);
-    }
+    memory_region_set_dirty(&s->vram_mem, s->vram24_offset, MAXX * MAXY * 4);
+    memory_region_set_dirty(&s->vram_mem, s->cplane_offset, MAXX * MAXY * 4);
 }

 static void update_palette_entries(TCXState *s, int start, int end)
diff --git a/hw/vga.c b/hw/vga.c
index ca79aa1..85176a6 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -853,7 +853,7 @@ void vga_mem_writeb(VGACommonState *s,
target_phys_addr_t addr, uint32_t val)
             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            memory_region_set_dirty(&s->vram, addr);
+            memory_region_set_dirty(&s->vram, addr, 1);
         }
     } else if (s->gr[5] & 0x10) {
         /* odd/even mode (aka text mode mapping) */
@@ -866,7 +866,7 @@ void vga_mem_writeb(VGACommonState *s,
target_phys_addr_t addr, uint32_t val)
             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            memory_region_set_dirty(&s->vram, addr);
+            memory_region_set_dirty(&s->vram, addr, 1);
         }
     } else {
         /* standard VGA latched access */
@@ -940,7 +940,7 @@ void vga_mem_writeb(VGACommonState *s,
target_phys_addr_t addr, uint32_t val)
         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
                addr * 4, write_mask, val);
 #endif
-        memory_region_set_dirty(&s->vram, addr << 2);
+        memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
     }
 }

diff --git a/hw/vhost.c b/hw/vhost.c
index 0870cb7..556c785 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -50,7 +50,7 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
             ram_addr_t ram_addr;
             bit -= 1;
             ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE);
-            cpu_physical_memory_set_dirty(ram_addr);
+            cpu_physical_memory_range_set_dirty(ram_addr, VHOST_LOG_PAGE);
             log &= ~(0x1ull << bit);
         }
         addr += VHOST_LOG_CHUNK;
diff --git a/kvm-all.c b/kvm-all.c
index 4c466d6..38ab4ad 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -353,7 +353,8 @@ static int kvm_get_dirty_pages_log_range(unsigned
long start_addr,
                 addr1 = page_number * TARGET_PAGE_SIZE;
                 addr = offset + addr1;
                 ram_addr = cpu_get_physical_page_desc(addr);
-                cpu_physical_memory_set_dirty(ram_addr);
+                cpu_physical_memory_range_set_dirty(ram_addr,
+                                                    TARGET_PAGE_SIZE);
             } while (c != 0);
         }
     }
@@ -364,8 +365,9 @@ static int kvm_get_dirty_pages_log_range(unsigned
long start_addr,

 /**
  * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
- * This function updates qemu's dirty bitmap using
cpu_physical_memory_set_dirty().
- * This means all bits are set to dirty.
+ * This function updates qemu's dirty bitmap using
+ * cpu_physical_memory_range_set_dirty().  This means all bits are set
+ * to dirty.
  *
  * @start_add: start of logged region.
  * @end_addr: end of logged region.
diff --git a/memory.c b/memory.c
index adfdf14..71600d0 100644
--- a/memory.c
+++ b/memory.c
@@ -1068,10 +1068,11 @@ bool memory_region_get_dirty(MemoryRegion *mr,
target_phys_addr_t addr,
     return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client);
 }

-void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
+void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                             target_phys_addr_t size)
 {
     assert(mr->terminates);
-    return cpu_physical_memory_set_dirty(mr->ram_addr + addr);
+    return cpu_physical_memory_range_set_dirty(mr->ram_addr + addr, size);
 }

 void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
diff --git a/memory.h b/memory.h
index 53bf261..1f8b5a5 100644
--- a/memory.h
+++ b/memory.h
@@ -318,10 +318,12 @@ bool memory_region_get_dirty(MemoryRegion *mr,
target_phys_addr_t addr,
  *
  * Marks a page as dirty, after it has been dirtied outside guest code.
  *
- * @mr: the memory region being queried.
+ * @mr: the memory region being dirtied.
  * @addr: the address (relative to the start of the region) being dirtied.
+ * @size: size of the range being dirtied.
  */
-void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr);
+void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr,
+                             target_phys_addr_t size);

 /**
  * memory_region_sync_dirty_bitmap: Synchronize a region's dirty bitmap with
diff --git a/xen-all.c b/xen-all.c
index b5e28ab..c07494b 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -422,7 +422,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);
+            cpu_physical_memory_range_set_dirty(vram_offset + (i * width + j) *
+                                                TARGET_PAGE_SIZE,
+                                                TARGET_PAGE_SIZE);
         };
     }

-- 
1.7.2.5

Reply via email to