summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-03-01 15:26:55 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-03-01 15:26:55 -0600
commit88e6c60671df4c8b1b6c1eb8f76950ab1bea0ec2 (patch)
tree9ca77b39c347ebb52e5ce08c043d670c0d9dadc3
parent14655e482bc9ef44b841bdca55d79ab0891058e9 (diff)
parent8f6f962b994e1402935055ac7093ac977ccc9a5c (diff)
downloadfocaccia-qemu-88e6c60671df4c8b1b6c1eb8f76950ab1bea0ec2.tar.gz
focaccia-qemu-88e6c60671df4c8b1b6c1eb8f76950ab1bea0ec2.zip
Merge remote-tracking branch 'qemu-kvm/memory/urgent' into staging
* qemu-kvm/memory/urgent:
  kvm: fix unaligned slots
-rw-r--r--kvm-all.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/kvm-all.c b/kvm-all.c
index 7119751956..77eadf608f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -542,17 +542,26 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
     target_phys_addr_t start_addr = section->offset_within_address_space;
     ram_addr_t size = section->size;
     void *ram = NULL;
+    unsigned delta;
 
     /* kvm works in page size chunks, but the function may be called
        with sub-page size and unaligned start address. */
-    size = TARGET_PAGE_ALIGN(size);
-    start_addr = TARGET_PAGE_ALIGN(start_addr);
+    delta = TARGET_PAGE_ALIGN(size) - size;
+    if (delta > size) {
+        return;
+    }
+    start_addr += delta;
+    size -= delta;
+    size &= TARGET_PAGE_MASK;
+    if (!size || (start_addr & ~TARGET_PAGE_MASK)) {
+        return;
+    }
 
     if (!memory_region_is_ram(mr)) {
         return;
     }
 
-    ram = memory_region_get_ram_ptr(mr) + section->offset_within_region;
+    ram = memory_region_get_ram_ptr(mr) + section->offset_within_region + delta;
 
     while (1) {
         mem = kvm_lookup_overlapping_slot(s, start_addr, start_addr + size);