aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h5
-rw-r--r--drivers/kvm/kvm_main.c19
-rw-r--r--drivers/kvm/x86.c31
3 files changed, 40 insertions, 15 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index bdcc44e6b6d7..c1aa84f7ca0a 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -644,6 +644,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
644 644
645int kvm_dev_ioctl_check_extension(long ext); 645int kvm_dev_ioctl_check_extension(long ext);
646 646
647int kvm_get_dirty_log(struct kvm *kvm,
648 struct kvm_dirty_log *log, int *is_dirty);
649int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
650 struct kvm_dirty_log *log);
651
647int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, 652int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
648 struct 653 struct
649 kvm_userspace_memory_region *mem, 654 kvm_userspace_memory_region *mem,
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index b0b6ff2a8cbe..5f11e6b09458 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -389,19 +389,14 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
389 return kvm_set_memory_region(kvm, mem, user_alloc); 389 return kvm_set_memory_region(kvm, mem, user_alloc);
390} 390}
391 391
392/* 392int kvm_get_dirty_log(struct kvm *kvm,
393 * Get (and clear) the dirty memory log for a memory slot. 393 struct kvm_dirty_log *log, int *is_dirty)
394 */
395static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
396 struct kvm_dirty_log *log)
397{ 394{
398 struct kvm_memory_slot *memslot; 395 struct kvm_memory_slot *memslot;
399 int r, i; 396 int r, i;
400 int n; 397 int n;
401 unsigned long any = 0; 398 unsigned long any = 0;
402 399
403 mutex_lock(&kvm->lock);
404
405 r = -EINVAL; 400 r = -EINVAL;
406 if (log->slot >= KVM_MEMORY_SLOTS) 401 if (log->slot >= KVM_MEMORY_SLOTS)
407 goto out; 402 goto out;
@@ -420,17 +415,11 @@ static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
420 if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n)) 415 if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
421 goto out; 416 goto out;
422 417
423 /* If nothing is dirty, don't bother messing with page tables. */ 418 if (any)
424 if (any) { 419 *is_dirty = 1;
425 kvm_mmu_slot_remove_write_access(kvm, log->slot);
426 kvm_flush_remote_tlbs(kvm);
427 memset(memslot->dirty_bitmap, 0, n);
428 }
429 420
430 r = 0; 421 r = 0;
431
432out: 422out:
433 mutex_unlock(&kvm->lock);
434 return r; 423 return r;
435} 424}
436 425
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index 9618fcba887e..935e2769b787 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -937,6 +937,37 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
937 return r; 937 return r;
938} 938}
939 939
940/*
941 * Get (and clear) the dirty memory log for a memory slot.
942 */
943int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
944 struct kvm_dirty_log *log)
945{
946 int r;
947 int n;
948 struct kvm_memory_slot *memslot;
949 int is_dirty = 0;
950
951 mutex_lock(&kvm->lock);
952
953 r = kvm_get_dirty_log(kvm, log, &is_dirty);
954 if (r)
955 goto out;
956
957 /* If nothing is dirty, don't bother messing with page tables. */
958 if (is_dirty) {
959 kvm_mmu_slot_remove_write_access(kvm, log->slot);
960 kvm_flush_remote_tlbs(kvm);
961 memslot = &kvm->memslots[log->slot];
962 n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
963 memset(memslot->dirty_bitmap, 0, n);
964 }
965 r = 0;
966out:
967 mutex_unlock(&kvm->lock);
968 return r;
969}
970
940long kvm_arch_vm_ioctl(struct file *filp, 971long kvm_arch_vm_ioctl(struct file *filp,
941 unsigned int ioctl, unsigned long arg) 972 unsigned int ioctl, unsigned long arg)
942{ 973{