diff options
Diffstat (limited to 'drivers/hv/mshv_eventfd.c')
-rw-r--r-- | drivers/hv/mshv_eventfd.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c index 8dd22be2ca0b..806674722868 100644 --- a/drivers/hv/mshv_eventfd.c +++ b/drivers/hv/mshv_eventfd.c @@ -368,6 +368,14 @@ static void mshv_irqfd_queue_proc(struct file *file, wait_queue_head_t *wqh, container_of(polltbl, struct mshv_irqfd, irqfd_polltbl); irqfd->irqfd_wqh = wqh; + + /* + * TODO: Ensure there isn't already an exclusive, priority waiter, e.g. + * that the irqfd isn't already bound to another partition. Only the + * first exclusive waiter encountered will be notified, and + * add_wait_queue_priority() doesn't enforce exclusivity. + */ + irqfd->irqfd_wait.flags |= WQ_FLAG_EXCLUSIVE; add_wait_queue_priority(wqh, &irqfd->irqfd_wait); } @@ -377,10 +385,11 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL; struct mshv_irqfd *irqfd, *tmp; unsigned int events; - struct fd f; int ret; int idx; + CLASS(fd, f)(args->fd); + irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); if (!irqfd) return -ENOMEM; @@ -390,8 +399,7 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, INIT_WORK(&irqfd->irqfd_shutdown, mshv_irqfd_shutdown); seqcount_spinlock_init(&irqfd->irqfd_irqe_sc, &pt->pt_irqfds_lock); - f = fdget(args->fd); - if (!fd_file(f)) { + if (fd_empty(f)) { ret = -EBADF; goto out; } @@ -496,12 +504,6 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, mshv_assert_irq_slow(irqfd); srcu_read_unlock(&pt->pt_irq_srcu, idx); - /* - * do not drop the file until the irqfd is fully initialized, otherwise - * we might race against the POLLHUP - */ - fdput(f); - return 0; fail: @@ -514,8 +516,6 @@ fail: if (eventfd && !IS_ERR(eventfd)) eventfd_ctx_put(eventfd); - fdput(f); - out: kfree(irqfd); return ret; |