aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c35
1 files changed, 16 insertions, 19 deletions
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index 4bc704e1b7c7..641bc87bdb96 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -130,8 +130,8 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
130 void (*thread)(struct vfio_pci_device *, void *), 130 void (*thread)(struct vfio_pci_device *, void *),
131 void *data, struct virqfd **pvirqfd, int fd) 131 void *data, struct virqfd **pvirqfd, int fd)
132{ 132{
133 struct file *file = NULL; 133 struct fd irqfd;
134 struct eventfd_ctx *ctx = NULL; 134 struct eventfd_ctx *ctx;
135 struct virqfd *virqfd; 135 struct virqfd *virqfd;
136 int ret = 0; 136 int ret = 0;
137 unsigned int events; 137 unsigned int events;
@@ -149,16 +149,16 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
149 INIT_WORK(&virqfd->shutdown, virqfd_shutdown); 149 INIT_WORK(&virqfd->shutdown, virqfd_shutdown);
150 INIT_WORK(&virqfd->inject, virqfd_inject); 150 INIT_WORK(&virqfd->inject, virqfd_inject);
151 151
152 file = eventfd_fget(fd); 152 irqfd = fdget(fd);
153 if (IS_ERR(file)) { 153 if (!irqfd.file) {
154 ret = PTR_ERR(file); 154 ret = -EBADF;
155 goto fail; 155 goto err_fd;
156 } 156 }
157 157
158 ctx = eventfd_ctx_fileget(file); 158 ctx = eventfd_ctx_fileget(irqfd.file);
159 if (IS_ERR(ctx)) { 159 if (IS_ERR(ctx)) {
160 ret = PTR_ERR(ctx); 160 ret = PTR_ERR(ctx);
161 goto fail; 161 goto err_ctx;
162 } 162 }
163 163
164 virqfd->eventfd = ctx; 164 virqfd->eventfd = ctx;
@@ -174,7 +174,7 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
174 if (*pvirqfd) { 174 if (*pvirqfd) {
175 spin_unlock_irq(&vdev->irqlock); 175 spin_unlock_irq(&vdev->irqlock);
176 ret = -EBUSY; 176 ret = -EBUSY;
177 goto fail; 177 goto err_busy;
178 } 178 }
179 *pvirqfd = virqfd; 179 *pvirqfd = virqfd;
180 180
@@ -187,7 +187,7 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
187 init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup); 187 init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup);
188 init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc); 188 init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc);
189 189
190 events = file->f_op->poll(file, &virqfd->pt); 190 events = irqfd.file->f_op->poll(irqfd.file, &virqfd->pt);
191 191
192 /* 192 /*
193 * Check if there was an event already pending on the eventfd 193 * Check if there was an event already pending on the eventfd
@@ -202,17 +202,14 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
202 * Do not drop the file until the irqfd is fully initialized, 202 * Do not drop the file until the irqfd is fully initialized,
203 * otherwise we might race against the POLLHUP. 203 * otherwise we might race against the POLLHUP.
204 */ 204 */
205 fput(file); 205 fdput(irqfd);
206 206
207 return 0; 207 return 0;
208 208err_busy:
209fail: 209 eventfd_ctx_put(ctx);
210 if (ctx && !IS_ERR(ctx)) 210err_ctx:
211 eventfd_ctx_put(ctx); 211 fdput(irqfd);
212 212err_fd:
213 if (file && !IS_ERR(file))
214 fput(file);
215
216 kfree(virqfd); 213 kfree(virqfd);
217 214
218 return ret; 215 return ret;