Revision 151f7749 kvm-all.c
b/kvm-all.c | ||
---|---|---|
272 | 272 |
* @start_add: start of logged region. |
273 | 273 |
* @end_addr: end of logged region. |
274 | 274 |
*/ |
275 |
void kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
|
|
276 |
target_phys_addr_t end_addr)
|
|
275 |
int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
|
|
276 |
target_phys_addr_t end_addr) |
|
277 | 277 |
{ |
278 | 278 |
KVMState *s = kvm_state; |
279 |
KVMDirtyLog d; |
|
280 |
KVMSlot *mem = kvm_lookup_matching_slot(s, start_addr, end_addr); |
|
281 |
unsigned long alloc_size; |
|
279 |
unsigned long size, allocated_size = 0; |
|
280 |
target_phys_addr_t phys_addr; |
|
282 | 281 |
ram_addr_t addr; |
283 |
target_phys_addr_t phys_addr = start_addr; |
|
282 |
KVMDirtyLog d; |
|
283 |
KVMSlot *mem; |
|
284 |
int ret = 0; |
|
284 | 285 |
|
285 |
dprintf("sync addr: " TARGET_FMT_lx " into %lx\n", start_addr, |
|
286 |
mem->phys_offset); |
|
287 |
if (mem == NULL) { |
|
288 |
fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-" |
|
289 |
TARGET_FMT_plx "\n", __func__, phys_addr, end_addr - 1); |
|
290 |
return; |
|
291 |
} |
|
286 |
d.dirty_bitmap = NULL; |
|
287 |
while (start_addr < end_addr) { |
|
288 |
mem = kvm_lookup_overlapping_slot(s, start_addr, end_addr); |
|
289 |
if (mem == NULL) { |
|
290 |
break; |
|
291 |
} |
|
292 | 292 |
|
293 |
alloc_size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8; |
|
294 |
d.dirty_bitmap = qemu_mallocz(alloc_size); |
|
293 |
size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8; |
|
294 |
if (!d.dirty_bitmap) { |
|
295 |
d.dirty_bitmap = qemu_malloc(size); |
|
296 |
} else if (size > allocated_size) { |
|
297 |
d.dirty_bitmap = qemu_realloc(d.dirty_bitmap, size); |
|
298 |
} |
|
299 |
allocated_size = size; |
|
300 |
memset(d.dirty_bitmap, 0, allocated_size); |
|
295 | 301 |
|
296 |
d.slot = mem->slot; |
|
297 |
dprintf("slot %d, phys_addr %llx, uaddr: %llx\n", |
|
298 |
d.slot, mem->start_addr, mem->phys_offset); |
|
302 |
d.slot = mem->slot; |
|
299 | 303 |
|
300 |
if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) { |
|
301 |
dprintf("ioctl failed %d\n", errno); |
|
302 |
goto out; |
|
303 |
} |
|
304 |
if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) { |
|
305 |
dprintf("ioctl failed %d\n", errno); |
|
306 |
ret = -1; |
|
307 |
break; |
|
308 |
} |
|
309 |
|
|
310 |
for (phys_addr = mem->start_addr, addr = mem->phys_offset; |
|
311 |
phys_addr < mem->start_addr + mem->memory_size; |
|
312 |
phys_addr += TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { |
|
313 |
unsigned long *bitmap = (unsigned long *)d.dirty_bitmap; |
|
314 |
unsigned nr = (phys_addr - mem->start_addr) >> TARGET_PAGE_BITS; |
|
315 |
unsigned word = nr / (sizeof(*bitmap) * 8); |
|
316 |
unsigned bit = nr % (sizeof(*bitmap) * 8); |
|
304 | 317 |
|
305 |
phys_addr = start_addr; |
|
306 |
for (addr = mem->phys_offset; phys_addr < end_addr; phys_addr+= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { |
|
307 |
unsigned long *bitmap = (unsigned long *)d.dirty_bitmap; |
|
308 |
unsigned nr = (phys_addr - start_addr) >> TARGET_PAGE_BITS; |
|
309 |
unsigned word = nr / (sizeof(*bitmap) * 8); |
|
310 |
unsigned bit = nr % (sizeof(*bitmap) * 8); |
|
311 |
if ((bitmap[word] >> bit) & 1) |
|
312 |
cpu_physical_memory_set_dirty(addr); |
|
318 |
if ((bitmap[word] >> bit) & 1) { |
|
319 |
cpu_physical_memory_set_dirty(addr); |
|
320 |
} |
|
321 |
} |
|
322 |
start_addr = phys_addr; |
|
313 | 323 |
} |
314 |
out: |
|
315 | 324 |
qemu_free(d.dirty_bitmap); |
325 |
|
|
326 |
return ret; |
|
316 | 327 |
} |
317 | 328 |
|
318 | 329 |
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) |
Also available in: Unified diff