- support QEMU interface for initial VM Write Protect - QEMU Dirty bit map log retrieval Signed-off-by: Mario Smarduch <m.smarduch@xxxxxxxxxxx> --- arch/arm/kvm/arm.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index bd18bb8..9076e3d 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -241,6 +241,8 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, const struct kvm_memory_slot *old, enum kvm_mr_change change) { + if ((change != KVM_MR_DELETE) && (mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) + kvm_mmu_slot_remove_write_access(kvm, mem->slot); } void kvm_arch_flush_shadow_all(struct kvm *kvm) @@ -773,9 +775,67 @@ long kvm_arch_vcpu_ioctl(struct file *filp, } } +/* + * Walks the memslot dirty bitmap, write protects dirty pages for next rount, + * and stores the dirty bitmap fo QEMU retrieval. + * + */ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) { - return -EINVAL; + int r; + struct kvm_memory_slot *memslot; + unsigned long n, i; + unsigned long *dirty_bitmap; + unsigned long *dirty_bitmap_buffer; + bool is_dirty = false; + gfn_t offset; + + mutex_lock(&kvm->slots_lock); + r = -EINVAL; + + if (log->slot >= KVM_USER_MEM_SLOTS) + goto out; + + memslot = id_to_memslot(kvm->memslots, log->slot); + dirty_bitmap = memslot->dirty_bitmap; + + r = -ENOENT; + if (!dirty_bitmap) + goto out; + + n = kvm_dirty_bitmap_bytes(memslot); + dirty_bitmap_buffer = dirty_bitmap + n / sizeof(long); + memset(dirty_bitmap_buffer, 0, n); + + spin_lock(&kvm->mmu_lock); + for (i = 0; i < n / sizeof(long); i++) { + unsigned long mask; + + if (!dirty_bitmap[i]) + continue; + + is_dirty = true; + offset = i * BITS_PER_LONG; + kvm_mmu_write_protect_pt_masked(kvm, memslot, offset, + dirty_bitmap[i]); + mask = dirty_bitmap[i]; + dirty_bitmap_buffer[i] = mask; + dirty_bitmap[i] = 0; + } + + if (is_dirty) + kvm_tlb_flush_vmid(kvm); + + spin_unlock(&kvm->mmu_lock); + r = -EFAULT; + + if (copy_to_user(log->dirty_bitmap, dirty_bitmap_buffer, n)) + goto out; + + r = 0; +out: + mutex_unlock(&kvm->slots_lock); + return r; } static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html