From: Uri Lublin <[EMAIL PROTECTED]>

Since c79baa60813812e8d0e34d998d609e848c093000 qemu does not know
about slots, it uses addresses. Getting the dirty-page-bitmap needs to
adapt to that change.

The user (qemu) requests (from libkvm) dirty page log for all
pages within a specific address range (specifically [0,phys_ram_size-1]).

libkvm iterates through all slots in the address range, calling
a qemu-kvm callback to update qemu's bytemap for each slot within
the requested range.

Signed-off-by: Izik Eidus <[EMAIL PROTECTED]>
Signed-off-by: Uri Lublin <[EMAIL PROTECTED]>
Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>

diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index cf0c249..ad90e0b 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -608,6 +608,32 @@ int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long 
phys_addr, void *buf)
        return kvm_get_map(kvm, KVM_GET_DIRTY_LOG, slot, buf);
 }
 
+#define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
+#define BITMAP_SIZE(m) (ALIGN(((m)/PAGE_SIZE), sizeof(long) * 8) / 8)
+
+int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
+                             unsigned long len, void *buf, void *opaque,
+                             int (*cb)(unsigned long start, unsigned long len,
+                                       void*bitmap, void *opaque))
+{
+       int i;
+       int r;
+       unsigned long end_addr = phys_addr + len;
+
+       for (i = 0; i < KVM_MAX_NUM_MEM_REGIONS; ++i) {
+               if ((slots[i].len && slots[i].phys_addr >= phys_addr) &&
+                   (slots[i].phys_addr + slots[i].len  <= end_addr)) {
+                       r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
+                       if (r)
+                               return r;
+                       r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
+                       if (r)
+                               return r;
+               }
+       }
+       return 0;
+}
+
 int kvm_get_mem_map(kvm_context_t kvm, unsigned long phys_addr, void *buf)
 {
        int slot;
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index ff260f4..d999ce9 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -423,7 +423,10 @@ int kvm_register_userspace_phys_mem(kvm_context_t kvm,
                        unsigned long phys_start, void *userspace_addr,
                        unsigned long len, int log);
 int kvm_get_dirty_pages(kvm_context_t, unsigned long phys_addr, void *buf);
-
+int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
+                             unsigned long end_addr, void *buf, void*opaque,
+                             int (*cb)(unsigned long start, unsigned long len,
+                                       void*bitmap, void *opaque));
 
 /*!
  * \brief Create a memory alias
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index 3aeba39..5580bb4 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -710,20 +710,15 @@ int kvm_physical_memory_set_dirty_tracking(int enable)
 }
 
 /* get kvm's dirty pages bitmap and update qemu's */
-int kvm_get_dirty_pages_log_slot(unsigned long start_addr,
-                                 unsigned char *bitmap,
-                                 unsigned int offset,
-                                 unsigned int len)
+int kvm_get_dirty_pages_log_range(unsigned long start_addr,
+                                  unsigned char *bitmap,
+                                  unsigned int offset,
+                                  unsigned long mem_size)
 {
-    int r;
     unsigned int i, j, n=0;
     unsigned char c;
     unsigned page_number, addr, addr1;
-
-    memset(bitmap, 0, len);
-    r = kvm_get_dirty_pages(kvm_context, start_addr, bitmap);
-    if (r)
-        return r;
+    unsigned int len = ((mem_size/TARGET_PAGE_SIZE) + 7) / 8;
 
     /* 
      * bitmap-traveling is faster than memory-traveling (for addr...) 
@@ -743,6 +738,11 @@ int kvm_get_dirty_pages_log_slot(unsigned long start_addr,
     }
     return 0;
 }
+int kvm_get_dirty_bitmap_cb(unsigned long start, unsigned long len,
+                            void *bitmap, void *opaque)
+{
+    return kvm_get_dirty_pages_log_range(start, bitmap, start, len);
+}
 
 /* 
  * get kvm's dirty pages bitmap and update qemu's
@@ -750,12 +750,12 @@ int kvm_get_dirty_pages_log_slot(unsigned long start_addr,
  */
 int kvm_update_dirty_pages_log(void)
 {
-    int r = 0, len;
+    int r = 0;
+
 
-    len = BITMAP_SIZE(0xa0000);
-    r =      kvm_get_dirty_pages_log_slot(0, kvm_dirty_bitmap, 0      , len);
-    len = BITMAP_SIZE(phys_ram_size - 0xc0000);
-    r = r || kvm_get_dirty_pages_log_slot(0xc0000, kvm_dirty_bitmap, 0xc0000, 
len);
+    r = kvm_get_dirty_pages_range(kvm_context, 0, phys_ram_size,
+                                  kvm_dirty_bitmap, NULL,
+                                  kvm_get_dirty_bitmap_cb);
     return r;
 }
 

-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
kvm-commits mailing list
kvm-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-commits

Reply via email to