aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vfio/pci/vfio_pci.c21
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c16
-rw-r--r--drivers/vfio/pci/vfio_pci_private.h1
-rw-r--r--include/uapi/linux/vfio.h1
4 files changed, 38 insertions, 1 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 7cc0122a18ce..f8a186381ae8 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -239,9 +239,12 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type)
239 239
240 return (flags & PCI_MSIX_FLAGS_QSIZE) + 1; 240 return (flags & PCI_MSIX_FLAGS_QSIZE) + 1;
241 } 241 }
242 } else if (irq_type == VFIO_PCI_ERR_IRQ_INDEX) 242 } else if (irq_type == VFIO_PCI_ERR_IRQ_INDEX) {
243 if (pci_is_pcie(vdev->pdev)) 243 if (pci_is_pcie(vdev->pdev))
244 return 1; 244 return 1;
245 } else if (irq_type == VFIO_PCI_REQ_IRQ_INDEX) {
246 return 1;
247 }
245 248
246 return 0; 249 return 0;
247} 250}
@@ -464,6 +467,7 @@ static long vfio_pci_ioctl(void *device_data,
464 467
465 switch (info.index) { 468 switch (info.index) {
466 case VFIO_PCI_INTX_IRQ_INDEX ... VFIO_PCI_MSIX_IRQ_INDEX: 469 case VFIO_PCI_INTX_IRQ_INDEX ... VFIO_PCI_MSIX_IRQ_INDEX:
470 case VFIO_PCI_REQ_IRQ_INDEX:
467 break; 471 break;
468 case VFIO_PCI_ERR_IRQ_INDEX: 472 case VFIO_PCI_ERR_IRQ_INDEX:
469 if (pci_is_pcie(vdev->pdev)) 473 if (pci_is_pcie(vdev->pdev))
@@ -828,6 +832,20 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
828 req_len, vma->vm_page_prot); 832 req_len, vma->vm_page_prot);
829} 833}
830 834
835static void vfio_pci_request(void *device_data, unsigned int count)
836{
837 struct vfio_pci_device *vdev = device_data;
838
839 mutex_lock(&vdev->igate);
840
841 if (vdev->req_trigger) {
842 dev_dbg(&vdev->pdev->dev, "Requesting device from user\n");
843 eventfd_signal(vdev->req_trigger, 1);
844 }
845
846 mutex_unlock(&vdev->igate);
847}
848
831static const struct vfio_device_ops vfio_pci_ops = { 849static const struct vfio_device_ops vfio_pci_ops = {
832 .name = "vfio-pci", 850 .name = "vfio-pci",
833 .open = vfio_pci_open, 851 .open = vfio_pci_open,
@@ -836,6 +854,7 @@ static const struct vfio_device_ops vfio_pci_ops = {
836 .read = vfio_pci_read, 854 .read = vfio_pci_read,
837 .write = vfio_pci_write, 855 .write = vfio_pci_write,
838 .mmap = vfio_pci_mmap, 856 .mmap = vfio_pci_mmap,
857 .request = vfio_pci_request,
839}; 858};
840 859
841static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 860static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index b134befbfd0e..f88bfdf5b6a0 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -817,6 +817,16 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
817 return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data); 817 return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data);
818} 818}
819 819
820static int vfio_pci_set_req_trigger(struct vfio_pci_device *vdev,
821 unsigned index, unsigned start,
822 unsigned count, uint32_t flags, void *data)
823{
824 if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count != 1)
825 return -EINVAL;
826
827 return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger, flags, data);
828}
829
820int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, 830int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
821 unsigned index, unsigned start, unsigned count, 831 unsigned index, unsigned start, unsigned count,
822 void *data) 832 void *data)
@@ -858,6 +868,12 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
858 func = vfio_pci_set_err_trigger; 868 func = vfio_pci_set_err_trigger;
859 break; 869 break;
860 } 870 }
871 case VFIO_PCI_REQ_IRQ_INDEX:
872 switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
873 case VFIO_IRQ_SET_ACTION_TRIGGER:
874 func = vfio_pci_set_req_trigger;
875 break;
876 }
861 } 877 }
862 878
863 if (!func) 879 if (!func)
diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h
index 671c17a6e6d0..c9f9b323f152 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -58,6 +58,7 @@ struct vfio_pci_device {
58 struct pci_saved_state *pci_saved_state; 58 struct pci_saved_state *pci_saved_state;
59 int refcnt; 59 int refcnt;
60 struct eventfd_ctx *err_trigger; 60 struct eventfd_ctx *err_trigger;
61 struct eventfd_ctx *req_trigger;
61}; 62};
62 63
63#define is_intx(vdev) (vdev->irq_type == VFIO_PCI_INTX_IRQ_INDEX) 64#define is_intx(vdev) (vdev->irq_type == VFIO_PCI_INTX_IRQ_INDEX)
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 29715d27548f..82889c30f4f5 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -333,6 +333,7 @@ enum {
333 VFIO_PCI_MSI_IRQ_INDEX, 333 VFIO_PCI_MSI_IRQ_INDEX,
334 VFIO_PCI_MSIX_IRQ_INDEX, 334 VFIO_PCI_MSIX_IRQ_INDEX,
335 VFIO_PCI_ERR_IRQ_INDEX, 335 VFIO_PCI_ERR_IRQ_INDEX,
336 VFIO_PCI_REQ_IRQ_INDEX,
336 VFIO_PCI_NUM_IRQS 337 VFIO_PCI_NUM_IRQS
337}; 338};
338 339