return (flags & PCI_MSIX_FLAGS_QSIZE) + 1;
}
- } else if (irq_type == VFIO_PCI_ERR_IRQ_INDEX)
+ } else if (irq_type == VFIO_PCI_ERR_IRQ_INDEX) {
if (pci_is_pcie(vdev->pdev))
return 1;
+ } else if (irq_type == VFIO_PCI_REQ_IRQ_INDEX) {
+ return 1;
+ }
return 0;
}
switch (info.index) {
case VFIO_PCI_INTX_IRQ_INDEX ... VFIO_PCI_MSIX_IRQ_INDEX:
+ case VFIO_PCI_REQ_IRQ_INDEX:
break;
case VFIO_PCI_ERR_IRQ_INDEX:
if (pci_is_pcie(vdev->pdev))
req_len, vma->vm_page_prot);
}
+static void vfio_pci_request(void *device_data, unsigned int count)
+{
+ struct vfio_pci_device *vdev = device_data;
+
+ mutex_lock(&vdev->igate);
+
+ if (vdev->req_trigger) {
+ dev_dbg(&vdev->pdev->dev, "Requesting device from user\n");
+ eventfd_signal(vdev->req_trigger, 1);
+ }
+
+ mutex_unlock(&vdev->igate);
+}
+
static const struct vfio_device_ops vfio_pci_ops = {
.name = "vfio-pci",
.open = vfio_pci_open,
.read = vfio_pci_read,
.write = vfio_pci_write,
.mmap = vfio_pci_mmap,
+ .request = vfio_pci_request,
};
static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data);
}
+static int vfio_pci_set_req_trigger(struct vfio_pci_device *vdev,
+ unsigned index, unsigned start,
+ unsigned count, uint32_t flags, void *data)
+{
+ if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count != 1)
+ return -EINVAL;
+
+ return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger, flags, data);
+}
+
int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
unsigned index, unsigned start, unsigned count,
void *data)
func = vfio_pci_set_err_trigger;
break;
}
+ case VFIO_PCI_REQ_IRQ_INDEX:
+ switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
+ case VFIO_IRQ_SET_ACTION_TRIGGER:
+ func = vfio_pci_set_req_trigger;
+ break;
+ }
}
if (!func)