static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,

					  target_phys_addr_t end_addr)

{

    KVMState *s = kvm_state;

    unsigned long size, allocated_size = 0;

    KVMDirtyLog d;

    KVMSlot *mem;

    int ret = 0;



    d.dirty_bitmap = NULL;

    while (start_addr < end_addr) {

        mem = kvm_lookup_overlapping_slot(s, start_addr, end_addr);

        if (mem == NULL) {

            break;

        }



        size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8;

        if (!d.dirty_bitmap) {

            d.dirty_bitmap = qemu_malloc(size);

        } else if (size > allocated_size) {

            d.dirty_bitmap = qemu_realloc(d.dirty_bitmap, size);

        }

        allocated_size = size;

        memset(d.dirty_bitmap, 0, allocated_size);



        d.slot = mem->slot;



        if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {

            DPRINTF("ioctl failed %d\n", errno);

            ret = -1;

            break;

        }



        kvm_get_dirty_pages_log_range(mem->start_addr, d.dirty_bitmap,

                                      mem->start_addr, mem->memory_size);

        start_addr = mem->start_addr + mem->memory_size;

    }

    qemu_free(d.dirty_bitmap);



    return ret;

}
