aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/async_pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/async_pf.c')
-rw-r--r--virt/kvm/async_pf.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c
index 8035cc1eb955..efeceb0a222d 100644
--- a/virt/kvm/async_pf.c
+++ b/virt/kvm/async_pf.c
@@ -91,6 +91,7 @@ static void async_pf_execute(struct work_struct *work)
91 91
92 spin_lock(&vcpu->async_pf.lock); 92 spin_lock(&vcpu->async_pf.lock);
93 list_add_tail(&apf->link, &vcpu->async_pf.done); 93 list_add_tail(&apf->link, &vcpu->async_pf.done);
94 apf->vcpu = NULL;
94 spin_unlock(&vcpu->async_pf.lock); 95 spin_unlock(&vcpu->async_pf.lock);
95 96
96 /* 97 /*
@@ -113,6 +114,8 @@ static void async_pf_execute(struct work_struct *work)
113 114
114void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) 115void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
115{ 116{
117 spin_lock(&vcpu->async_pf.lock);
118
116 /* cancel outstanding work queue item */ 119 /* cancel outstanding work queue item */
117 while (!list_empty(&vcpu->async_pf.queue)) { 120 while (!list_empty(&vcpu->async_pf.queue)) {
118 struct kvm_async_pf *work = 121 struct kvm_async_pf *work =
@@ -120,6 +123,14 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
120 typeof(*work), queue); 123 typeof(*work), queue);
121 list_del(&work->queue); 124 list_del(&work->queue);
122 125
126 /*
127 * We know it's present in vcpu->async_pf.done, do
128 * nothing here.
129 */
130 if (!work->vcpu)
131 continue;
132
133 spin_unlock(&vcpu->async_pf.lock);
123#ifdef CONFIG_KVM_ASYNC_PF_SYNC 134#ifdef CONFIG_KVM_ASYNC_PF_SYNC
124 flush_work(&work->work); 135 flush_work(&work->work);
125#else 136#else
@@ -129,9 +140,9 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
129 kmem_cache_free(async_pf_cache, work); 140 kmem_cache_free(async_pf_cache, work);
130 } 141 }
131#endif 142#endif
143 spin_lock(&vcpu->async_pf.lock);
132 } 144 }
133 145
134 spin_lock(&vcpu->async_pf.lock);
135 while (!list_empty(&vcpu->async_pf.done)) { 146 while (!list_empty(&vcpu->async_pf.done)) {
136 struct kvm_async_pf *work = 147 struct kvm_async_pf *work =
137 list_first_entry(&vcpu->async_pf.done, 148 list_first_entry(&vcpu->async_pf.done,