Add a new VFIO_PCI_DMA_FAULT_IRQ_INDEX index. This allows to
set/unset an eventfd that will be triggered when DMA translation
faults are detected at physical level when the nested mode is used.

Signed-off-by: Eric Auger <eric.au...@redhat.com>
---
 drivers/vfio/pci/vfio_pci.c       |  3 +++
 drivers/vfio/pci/vfio_pci_intrs.c | 19 +++++++++++++++++++
 include/uapi/linux/vfio.h         |  1 +
 3 files changed, 23 insertions(+)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index f9e2c8292e60..66d44736e71d 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -495,6 +495,8 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device 
*vdev, int irq_type)
                        return 1;
        } else if (irq_type == VFIO_PCI_REQ_IRQ_INDEX) {
                return 1;
+       } else if (irq_type == VFIO_PCI_DMA_FAULT_IRQ_INDEX) {
+               return 1;
        }
 
        return 0;
@@ -822,6 +824,7 @@ static long vfio_pci_ioctl(void *device_data,
                switch (info.index) {
                case VFIO_PCI_INTX_IRQ_INDEX ... VFIO_PCI_MSIX_IRQ_INDEX:
                case VFIO_PCI_REQ_IRQ_INDEX:
+               case VFIO_PCI_DMA_FAULT_IRQ_INDEX:
                        break;
                case VFIO_PCI_ERR_IRQ_INDEX:
                        if (pci_is_pcie(vdev->pdev))
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c 
b/drivers/vfio/pci/vfio_pci_intrs.c
index 1c46045b0e7f..28a96117daf3 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -622,6 +622,18 @@ static int vfio_pci_set_req_trigger(struct vfio_pci_device 
*vdev,
                                               count, flags, data);
 }
 
+static int vfio_pci_set_dma_fault_trigger(struct vfio_pci_device *vdev,
+                                         unsigned index, unsigned start,
+                                         unsigned count, uint32_t flags,
+                                         void *data)
+{
+       if (index != VFIO_PCI_DMA_FAULT_IRQ_INDEX || start != 0 || count > 1)
+               return -EINVAL;
+
+       return vfio_pci_set_ctx_trigger_single(&vdev->dma_fault_trigger,
+                                              count, flags, data);
+}
+
 int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
                            unsigned index, unsigned start, unsigned count,
                            void *data)
@@ -671,6 +683,13 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, 
uint32_t flags,
                        break;
                }
                break;
+       case VFIO_PCI_DMA_FAULT_IRQ_INDEX:
+               switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
+               case VFIO_IRQ_SET_ACTION_TRIGGER:
+                       func = vfio_pci_set_dma_fault_trigger;
+                       break;
+               }
+               break;
        }
 
        if (!func)
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index b78c2c62af6d..47b65ef9d448 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -554,6 +554,7 @@ enum {
        VFIO_PCI_MSIX_IRQ_INDEX,
        VFIO_PCI_ERR_IRQ_INDEX,
        VFIO_PCI_REQ_IRQ_INDEX,
+       VFIO_PCI_DMA_FAULT_IRQ_INDEX,
        VFIO_PCI_NUM_IRQS
 };
 
-- 
2.17.2

Reply via email to