aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2015-02-06 17:05:07 -0500
committerAlex Williamson <alex.williamson@redhat.com>2015-02-10 14:37:57 -0500
commitcac80d6e382f63243ee4f31eb55afe22ed423e53 (patch)
tree06c577bbff9603d8f4268fac3b5bac723761dc8a
parent13060b64b819c194909121b90b5f8dd9abb5ea4e (diff)
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: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index e8d695b3f54e..b134befbfd0e 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -763,46 +763,60 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_device *vdev,
763 return 0; 763 return 0;
764} 764}
765 765
766static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev, 766static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx,
767 unsigned index, unsigned start, 767 uint32_t flags, void *data)
768 unsigned count, uint32_t flags, void *data)
769{ 768{
770 int32_t fd = *(int32_t *)data; 769 int32_t fd = *(int32_t *)data;
771 770
772 if ((index != VFIO_PCI_ERR_IRQ_INDEX) || 771 if (!(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
773 !(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
774 return -EINVAL; 772 return -EINVAL;
775 773
776 /* DATA_NONE/DATA_BOOL enables loopback testing */ 774 /* DATA_NONE/DATA_BOOL enables loopback testing */
777 if (flags & VFIO_IRQ_SET_DATA_NONE) { 775 if (flags & VFIO_IRQ_SET_DATA_NONE) {
778 if (vdev->err_trigger) 776 if (*ctx)
779 eventfd_signal(vdev->err_trigger, 1); 777 eventfd_signal(*ctx, 1);
780 return 0; 778 return 0;
781 } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { 779 } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
782 uint8_t trigger = *(uint8_t *)data; 780 uint8_t trigger = *(uint8_t *)data;
783 if (trigger && vdev->err_trigger) 781 if (trigger && *ctx)
784 eventfd_signal(vdev->err_trigger, 1); 782 eventfd_signal(*ctx, 1);
785 return 0; 783 return 0;
786 } 784 }
787 785
788 /* Handle SET_DATA_EVENTFD */ 786 /* Handle SET_DATA_EVENTFD */
789 if (fd == -1) { 787 if (fd == -1) {
790 if (vdev->err_trigger) 788 if (*ctx)
791 eventfd_ctx_put(vdev->err_trigger); 789 eventfd_ctx_put(*ctx);
792 vdev->err_trigger = NULL; 790 *ctx = NULL;
793 return 0; 791 return 0;
794 } else if (fd >= 0) { 792 } else if (fd >= 0) {
795 struct eventfd_ctx *efdctx; 793 struct eventfd_ctx *efdctx;
796 efdctx = eventfd_ctx_fdget(fd); 794 efdctx = eventfd_ctx_fdget(fd);
797 if (IS_ERR(efdctx)) 795 if (IS_ERR(efdctx))
798 return PTR_ERR(efdctx); 796 return PTR_ERR(efdctx);
799 if (vdev->err_trigger) 797 if (*ctx)
800 eventfd_ctx_put(vdev->err_trigger); 798 eventfd_ctx_put(*ctx);
801 vdev->err_trigger = efdctx; 799 *ctx = efdctx;
802 return 0; 800 return 0;
803 } else 801 } else
804 return -EINVAL; 802 return -EINVAL;
805} 803}
804
805static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
806 unsigned index, unsigned start,
807 unsigned count, uint32_t flags, void *data)
808{
809 if (index != VFIO_PCI_ERR_IRQ_INDEX)
810 return -EINVAL;
811
812 /*
813 * We should sanitize start & count, but that wasn't caught
814 * originally, so this IRQ index must forever ignore them :-(
815 */
816
817 return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data);
818}
819
806int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, 820int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
807 unsigned index, unsigned start, unsigned count, 821 unsigned index, unsigned start, unsigned count,
808 void *data) 822 void *data)