summary refs log tree commit diff stats
path: root/include/exec
diff options
context:
space:
mode:
authorJuan Quintela <quintela@redhat.com>2013-11-05 15:52:54 +0100
committerJuan Quintela <quintela@redhat.com>2014-01-13 14:04:55 +0100
commit5ff7fb77b3cee8e26648e4fdccb23a77c2a6d3c6 (patch)
tree25d52129ce3f7a666a3f4ddf5be726845c3f7513 /include/exec
parentc9dd46fc0d64d9f314aa3c220d4aff9d01ab778e (diff)
downloadfocaccia-qemu-5ff7fb77b3cee8e26648e4fdccb23a77c2a6d3c6.tar.gz
focaccia-qemu-5ff7fb77b3cee8e26648e4fdccb23a77c2a6d3c6.zip
memory: move bitmap synchronization to its own function
We want to have all the functions that handle directly the dirty
bitmap near.  We will change it later.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Orit Wasserman <owasserm@redhat.com>
Diffstat (limited to 'include/exec')
-rw-r--r--include/exec/ram_addr.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index db977fbdae..c6736ed04f 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -79,6 +79,37 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
     xen_modified_memory(start, length);
 }
 
+static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
+                                                          ram_addr_t start,
+                                                          ram_addr_t pages)
+{
+    unsigned int i, j;
+    unsigned long page_number, c;
+    hwaddr addr;
+    ram_addr_t ram_addr;
+    unsigned int len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
+    unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE;
+
+    /*
+     * bitmap-traveling is faster than memory-traveling (for addr...)
+     * especially when most of the memory is not dirty.
+     */
+    for (i = 0; i < len; i++) {
+        if (bitmap[i] != 0) {
+            c = leul_to_cpu(bitmap[i]);
+            do {
+                j = ffsl(c) - 1;
+                c &= ~(1ul << j);
+                page_number = (i * HOST_LONG_BITS + j) * hpratio;
+                addr = page_number * TARGET_PAGE_SIZE;
+                ram_addr = start + addr;
+                cpu_physical_memory_set_dirty_range(ram_addr,
+                                                    TARGET_PAGE_SIZE * hpratio);
+            } while (c != 0);
+        }
+    }
+}
+
 static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start,
                                                          ram_addr_t length,
                                                          unsigned client)