diff options
-rw-r--r-- | drivers/kvm/kvm.h | 5 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 19 | ||||
-rw-r--r-- | drivers/kvm/x86.c | 31 |
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 | ||
645 | int kvm_dev_ioctl_check_extension(long ext); | 645 | int kvm_dev_ioctl_check_extension(long ext); |
646 | 646 | ||
647 | int kvm_get_dirty_log(struct kvm *kvm, | ||
648 | struct kvm_dirty_log *log, int *is_dirty); | ||
649 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | ||
650 | struct kvm_dirty_log *log); | ||
651 | |||
647 | int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, | 652 | int 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 | /* | 392 | int 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 | */ | ||
395 | static 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 | |||
432 | out: | 422 | out: |
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 | */ | ||
943 | int 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; | ||
966 | out: | ||
967 | mutex_unlock(&kvm->lock); | ||
968 | return r; | ||
969 | } | ||
970 | |||
940 | long kvm_arch_vm_ioctl(struct file *filp, | 971 | long kvm_arch_vm_ioctl(struct file *filp, |
941 | unsigned int ioctl, unsigned long arg) | 972 | unsigned int ioctl, unsigned long arg) |
942 | { | 973 | { |