diff options
author | Avi Kivity <avi@qumranet.com> | 2007-01-05 19:36:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-06 02:55:27 -0500 |
commit | 714b93da1a6d97307dfafb9915517879d8a66c0d (patch) | |
tree | 619f30567c9e13b79830301023bef58b98b8f433 /drivers/kvm/kvm_main.c | |
parent | f51234c2cd3ab8bed836e09686e27877e1b55f2a (diff) |
[PATCH] KVM: MMU: Replace atomic allocations by preallocated objects
The mmu sometimes needs memory for reverse mapping and parent pte chains.
however, we can't allocate from within the mmu because of the atomic context.
So, move the allocations to a central place that can be executed before the
main mmu machinery, where we can bail out on failure before any damage is
done.
(error handling is deffered for now, but the basic structure is there)
Signed-off-by: Avi Kivity <avi@qumranet.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 18 |
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 | ||
705 | static 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 | } |