Commit cac80d6e authored by Alex Williamson's avatar Alex Williamson

vfio-pci: Generalize setup of simple eventfds

We want another single vector IRQ index to support signaling of
the device request to userspace.  Generalize the error reporting
IRQ index to avoid code duplication.
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 13060b64
...@@ -763,46 +763,60 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_device *vdev, ...@@ -763,46 +763,60 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_device *vdev,
return 0; return 0;
} }
static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev, static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx,
unsigned index, unsigned start, uint32_t flags, void *data)
unsigned count, uint32_t flags, void *data)
{ {
int32_t fd = *(int32_t *)data; int32_t fd = *(int32_t *)data;
if ((index != VFIO_PCI_ERR_IRQ_INDEX) || if (!(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
!(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
return -EINVAL; return -EINVAL;
/* DATA_NONE/DATA_BOOL enables loopback testing */ /* DATA_NONE/DATA_BOOL enables loopback testing */
if (flags & VFIO_IRQ_SET_DATA_NONE) { if (flags & VFIO_IRQ_SET_DATA_NONE) {
if (vdev->err_trigger) if (*ctx)
eventfd_signal(vdev->err_trigger, 1); eventfd_signal(*ctx, 1);
return 0; return 0;
} else if (flags & VFIO_IRQ_SET_DATA_BOOL) { } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
uint8_t trigger = *(uint8_t *)data; uint8_t trigger = *(uint8_t *)data;
if (trigger && vdev->err_trigger) if (trigger && *ctx)
eventfd_signal(vdev->err_trigger, 1); eventfd_signal(*ctx, 1);
return 0; return 0;
} }
/* Handle SET_DATA_EVENTFD */ /* Handle SET_DATA_EVENTFD */
if (fd == -1) { if (fd == -1) {
if (vdev->err_trigger) if (*ctx)
eventfd_ctx_put(vdev->err_trigger); eventfd_ctx_put(*ctx);
vdev->err_trigger = NULL; *ctx = NULL;
return 0; return 0;
} else if (fd >= 0) { } else if (fd >= 0) {
struct eventfd_ctx *efdctx; struct eventfd_ctx *efdctx;
efdctx = eventfd_ctx_fdget(fd); efdctx = eventfd_ctx_fdget(fd);
if (IS_ERR(efdctx)) if (IS_ERR(efdctx))
return PTR_ERR(efdctx); return PTR_ERR(efdctx);
if (vdev->err_trigger) if (*ctx)
eventfd_ctx_put(vdev->err_trigger); eventfd_ctx_put(*ctx);
vdev->err_trigger = efdctx; *ctx = efdctx;
return 0; return 0;
} else } else
return -EINVAL; return -EINVAL;
} }
static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
unsigned index, unsigned start,
unsigned count, uint32_t flags, void *data)
{
if (index != VFIO_PCI_ERR_IRQ_INDEX)
return -EINVAL;
/*
* We should sanitize start & count, but that wasn't caught
* originally, so this IRQ index must forever ignore them :-(
*/
return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data);
}
int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
unsigned index, unsigned start, unsigned count, unsigned index, unsigned start, unsigned count,
void *data) void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment