aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/eventfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/eventfd.c')
-rw-r--r--virt/kvm/eventfd.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 30f70fd511c4..a9d3fc6c681c 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -72,12 +72,13 @@ static void
72irqfd_shutdown(struct work_struct *work) 72irqfd_shutdown(struct work_struct *work)
73{ 73{
74 struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown); 74 struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown);
75 u64 cnt;
75 76
76 /* 77 /*
77 * Synchronize with the wait-queue and unhook ourselves to prevent 78 * Synchronize with the wait-queue and unhook ourselves to prevent
78 * further events. 79 * further events.
79 */ 80 */
80 remove_wait_queue(irqfd->wqh, &irqfd->wait); 81 eventfd_ctx_remove_wait_queue(irqfd->eventfd, &irqfd->wait, &cnt);
81 82
82 /* 83 /*
83 * We know no new events will be scheduled at this point, so block 84 * We know no new events will be scheduled at this point, so block
@@ -166,7 +167,7 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
166static int 167static int
167kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) 168kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
168{ 169{
169 struct _irqfd *irqfd; 170 struct _irqfd *irqfd, *tmp;
170 struct file *file = NULL; 171 struct file *file = NULL;
171 struct eventfd_ctx *eventfd = NULL; 172 struct eventfd_ctx *eventfd = NULL;
172 int ret; 173 int ret;
@@ -203,9 +204,20 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
203 init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup); 204 init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
204 init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc); 205 init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
205 206
207 spin_lock_irq(&kvm->irqfds.lock);
208
209 ret = 0;
210 list_for_each_entry(tmp, &kvm->irqfds.items, list) {
211 if (irqfd->eventfd != tmp->eventfd)
212 continue;
213 /* This fd is used for another irq already. */
214 ret = -EBUSY;
215 spin_unlock_irq(&kvm->irqfds.lock);
216 goto fail;
217 }
218
206 events = file->f_op->poll(file, &irqfd->pt); 219 events = file->f_op->poll(file, &irqfd->pt);
207 220
208 spin_lock_irq(&kvm->irqfds.lock);
209 list_add_tail(&irqfd->list, &kvm->irqfds.items); 221 list_add_tail(&irqfd->list, &kvm->irqfds.items);
210 spin_unlock_irq(&kvm->irqfds.lock); 222 spin_unlock_irq(&kvm->irqfds.lock);
211 223