aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 2e6bc5659953..6623fecff040 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -702,6 +702,13 @@ out:
702 return r; 702 return r;
703} 703}
704 704
705static void do_remove_write_access(struct kvm_vcpu *vcpu, int slot)
706{
707 spin_lock(&vcpu->kvm->lock);
708 kvm_mmu_slot_remove_write_access(vcpu, slot);
709 spin_unlock(&vcpu->kvm->lock);
710}
711
705/* 712/*
706 * Get (and clear) the dirty memory log for a memory slot. 713 * Get (and clear) the dirty memory log for a memory slot.
707 */ 714 */
@@ -711,6 +718,7 @@ static int kvm_dev_ioctl_get_dirty_log(struct kvm *kvm,
711 struct kvm_memory_slot *memslot; 718 struct kvm_memory_slot *memslot;
712 int r, i; 719 int r, i;
713 int n; 720 int n;
721 int cleared;
714 unsigned long any = 0; 722 unsigned long any = 0;
715 723
716 spin_lock(&kvm->lock); 724 spin_lock(&kvm->lock);
@@ -741,15 +749,17 @@ static int kvm_dev_ioctl_get_dirty_log(struct kvm *kvm,
741 749
742 750
743 if (any) { 751 if (any) {
744 spin_lock(&kvm->lock); 752 cleared = 0;
745 kvm_mmu_slot_remove_write_access(kvm, log->slot);
746 spin_unlock(&kvm->lock);
747 memset(memslot->dirty_bitmap, 0, n);
748 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 753 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
749 struct kvm_vcpu *vcpu = vcpu_load(kvm, i); 754 struct kvm_vcpu *vcpu = vcpu_load(kvm, i);
750 755
751 if (!vcpu) 756 if (!vcpu)
752 continue; 757 continue;
758 if (!cleared) {
759 do_remove_write_access(vcpu, log->slot);
760 memset(memslot->dirty_bitmap, 0, n);
761 cleared = 1;
762 }
753 kvm_arch_ops->tlb_flush(vcpu); 763 kvm_arch_ops->tlb_flush(vcpu);
754 vcpu_put(vcpu); 764 vcpu_put(vcpu);
755 } 765 }