aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio/pci/vfio_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vfio/pci/vfio_pci.c')
-rw-r--r--drivers/vfio/pci/vfio_pci.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 09d2e3ffd6fc..ac3725440d64 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -201,7 +201,9 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type)
201 201
202 return (flags & PCI_MSIX_FLAGS_QSIZE) + 1; 202 return (flags & PCI_MSIX_FLAGS_QSIZE) + 1;
203 } 203 }
204 } 204 } else if (irq_type == VFIO_PCI_ERR_IRQ_INDEX)
205 if (pci_is_pcie(vdev->pdev))
206 return 1;
205 207
206 return 0; 208 return 0;
207} 209}
@@ -317,6 +319,17 @@ static long vfio_pci_ioctl(void *device_data,
317 if (info.argsz < minsz || info.index >= VFIO_PCI_NUM_IRQS) 319 if (info.argsz < minsz || info.index >= VFIO_PCI_NUM_IRQS)
318 return -EINVAL; 320 return -EINVAL;
319 321
322 switch (info.index) {
323 case VFIO_PCI_INTX_IRQ_INDEX ... VFIO_PCI_MSIX_IRQ_INDEX:
324 break;
325 case VFIO_PCI_ERR_IRQ_INDEX:
326 if (pci_is_pcie(vdev->pdev))
327 break;
328 /* pass thru to return error */
329 default:
330 return -EINVAL;
331 }
332
320 info.flags = VFIO_IRQ_INFO_EVENTFD; 333 info.flags = VFIO_IRQ_INFO_EVENTFD;
321 334
322 info.count = vfio_pci_get_irq_count(vdev, info.index); 335 info.count = vfio_pci_get_irq_count(vdev, info.index);
@@ -552,11 +565,40 @@ static void vfio_pci_remove(struct pci_dev *pdev)
552 kfree(vdev); 565 kfree(vdev);
553} 566}
554 567
568static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
569 pci_channel_state_t state)
570{
571 struct vfio_pci_device *vdev;
572 struct vfio_device *device;
573
574 device = vfio_device_get_from_dev(&pdev->dev);
575 if (device == NULL)
576 return PCI_ERS_RESULT_DISCONNECT;
577
578 vdev = vfio_device_data(device);
579 if (vdev == NULL) {
580 vfio_device_put(device);
581 return PCI_ERS_RESULT_DISCONNECT;
582 }
583
584 if (vdev->err_trigger)
585 eventfd_signal(vdev->err_trigger, 1);
586
587 vfio_device_put(device);
588
589 return PCI_ERS_RESULT_CAN_RECOVER;
590}
591
592static struct pci_error_handlers vfio_err_handlers = {
593 .error_detected = vfio_pci_aer_err_detected,
594};
595
555static struct pci_driver vfio_pci_driver = { 596static struct pci_driver vfio_pci_driver = {
556 .name = "vfio-pci", 597 .name = "vfio-pci",
557 .id_table = NULL, /* only dynamic ids */ 598 .id_table = NULL, /* only dynamic ids */
558 .probe = vfio_pci_probe, 599 .probe = vfio_pci_probe,
559 .remove = vfio_pci_remove, 600 .remove = vfio_pci_remove,
601 .err_handler = &vfio_err_handlers,
560}; 602};
561 603
562static void __exit vfio_pci_cleanup(void) 604static void __exit vfio_pci_cleanup(void)