1 // SPDX-License-Identifier: GPL-2.0-only
3 * VFIO generic eventfd code for IRQFD support.
4 * Derived from drivers/vfio/pci/vfio_pci_intrs.c
6 * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
7 * Author: Alex Williamson <alex.williamson@redhat.com>
10 #include <linux/vfio.h>
11 #include <linux/eventfd.h>
12 #include <linux/file.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
16 #define DRIVER_VERSION "0.1"
17 #define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"
18 #define DRIVER_DESC "IRQFD support for VFIO bus drivers"
20 static struct workqueue_struct
*vfio_irqfd_cleanup_wq
;
21 static DEFINE_SPINLOCK(virqfd_lock
);
23 static int __init
vfio_virqfd_init(void)
25 vfio_irqfd_cleanup_wq
=
26 create_singlethread_workqueue("vfio-irqfd-cleanup");
27 if (!vfio_irqfd_cleanup_wq
)
33 static void __exit
vfio_virqfd_exit(void)
35 destroy_workqueue(vfio_irqfd_cleanup_wq
);
38 static void virqfd_deactivate(struct virqfd
*virqfd
)
40 queue_work(vfio_irqfd_cleanup_wq
, &virqfd
->shutdown
);
43 static int virqfd_wakeup(wait_queue_entry_t
*wait
, unsigned mode
, int sync
, void *key
)
45 struct virqfd
*virqfd
= container_of(wait
, struct virqfd
, wait
);
46 __poll_t flags
= key_to_poll(key
);
48 if (flags
& EPOLLIN
) {
49 /* An event has been signaled, call function */
50 if ((!virqfd
->handler
||
51 virqfd
->handler(virqfd
->opaque
, virqfd
->data
)) &&
53 schedule_work(&virqfd
->inject
);
56 if (flags
& EPOLLHUP
) {
58 spin_lock_irqsave(&virqfd_lock
, flags
);
61 * The eventfd is closing, if the virqfd has not yet been
62 * queued for release, as determined by testing whether the
63 * virqfd pointer to it is still valid, queue it now. As
64 * with kvm irqfds, we know we won't race against the virqfd
65 * going away because we hold the lock to get here.
67 if (*(virqfd
->pvirqfd
) == virqfd
) {
68 *(virqfd
->pvirqfd
) = NULL
;
69 virqfd_deactivate(virqfd
);
72 spin_unlock_irqrestore(&virqfd_lock
, flags
);
78 static void virqfd_ptable_queue_proc(struct file
*file
,
79 wait_queue_head_t
*wqh
, poll_table
*pt
)
81 struct virqfd
*virqfd
= container_of(pt
, struct virqfd
, pt
);
82 add_wait_queue(wqh
, &virqfd
->wait
);
85 static void virqfd_shutdown(struct work_struct
*work
)
87 struct virqfd
*virqfd
= container_of(work
, struct virqfd
, shutdown
);
90 eventfd_ctx_remove_wait_queue(virqfd
->eventfd
, &virqfd
->wait
, &cnt
);
91 flush_work(&virqfd
->inject
);
92 eventfd_ctx_put(virqfd
->eventfd
);
97 static void virqfd_inject(struct work_struct
*work
)
99 struct virqfd
*virqfd
= container_of(work
, struct virqfd
, inject
);
101 virqfd
->thread(virqfd
->opaque
, virqfd
->data
);
104 int vfio_virqfd_enable(void *opaque
,
105 int (*handler
)(void *, void *),
106 void (*thread
)(void *, void *),
107 void *data
, struct virqfd
**pvirqfd
, int fd
)
110 struct eventfd_ctx
*ctx
;
111 struct virqfd
*virqfd
;
115 virqfd
= kzalloc(sizeof(*virqfd
), GFP_KERNEL
);
119 virqfd
->pvirqfd
= pvirqfd
;
120 virqfd
->opaque
= opaque
;
121 virqfd
->handler
= handler
;
122 virqfd
->thread
= thread
;
125 INIT_WORK(&virqfd
->shutdown
, virqfd_shutdown
);
126 INIT_WORK(&virqfd
->inject
, virqfd_inject
);
134 ctx
= eventfd_ctx_fileget(irqfd
.file
);
140 virqfd
->eventfd
= ctx
;
143 * virqfds can be released by closing the eventfd or directly
144 * through ioctl. These are both done through a workqueue, so
145 * we update the pointer to the virqfd under lock to avoid
146 * pushing multiple jobs to release the same virqfd.
148 spin_lock_irq(&virqfd_lock
);
151 spin_unlock_irq(&virqfd_lock
);
157 spin_unlock_irq(&virqfd_lock
);
160 * Install our own custom wake-up handling so we are notified via
161 * a callback whenever someone signals the underlying eventfd.
163 init_waitqueue_func_entry(&virqfd
->wait
, virqfd_wakeup
);
164 init_poll_funcptr(&virqfd
->pt
, virqfd_ptable_queue_proc
);
166 events
= vfs_poll(irqfd
.file
, &virqfd
->pt
);
169 * Check if there was an event already pending on the eventfd
170 * before we registered and trigger it as if we didn't miss it.
172 if (events
& EPOLLIN
) {
173 if ((!handler
|| handler(opaque
, data
)) && thread
)
174 schedule_work(&virqfd
->inject
);
178 * Do not drop the file until the irqfd is fully initialized,
179 * otherwise we might race against the EPOLLHUP.
185 eventfd_ctx_put(ctx
);
193 EXPORT_SYMBOL_GPL(vfio_virqfd_enable
);
195 void vfio_virqfd_disable(struct virqfd
**pvirqfd
)
199 spin_lock_irqsave(&virqfd_lock
, flags
);
202 virqfd_deactivate(*pvirqfd
);
206 spin_unlock_irqrestore(&virqfd_lock
, flags
);
209 * Block until we know all outstanding shutdown jobs have completed.
210 * Even if we don't queue the job, flush the wq to be sure it's
213 flush_workqueue(vfio_irqfd_cleanup_wq
);
215 EXPORT_SYMBOL_GPL(vfio_virqfd_disable
);
217 module_init(vfio_virqfd_init
);
218 module_exit(vfio_virqfd_exit
);
220 MODULE_VERSION(DRIVER_VERSION
);
221 MODULE_LICENSE("GPL v2");
222 MODULE_AUTHOR(DRIVER_AUTHOR
);
223 MODULE_DESCRIPTION(DRIVER_DESC
);