diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-01 15:26:55 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-01 15:26:55 -0600 |
commit | 88e6c60671df4c8b1b6c1eb8f76950ab1bea0ec2 (patch) | |
tree | 9ca77b39c347ebb52e5ce08c043d670c0d9dadc3 /kvm-all.c | |
parent | 14655e482bc9ef44b841bdca55d79ab0891058e9 (diff) | |
parent | 8f6f962b994e1402935055ac7093ac977ccc9a5c (diff) |
Merge remote-tracking branch 'qemu-kvm/memory/urgent' into staging
* qemu-kvm/memory/urgent:
kvm: fix unaligned slots
Diffstat (limited to 'kvm-all.c')
-rw-r--r-- | kvm-all.c | 15 |
1 files changed, 12 insertions, 3 deletions
@@ -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); |