qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 1/2] vfio : resume notifier


From: Zhou Jie
Subject: [Qemu-devel] [PATCH v2 1/2] vfio : resume notifier
Date: Tue, 19 Jul 2016 15:32:42 +0800

From: root <address@hidden>

---
 drivers/vfio/pci/vfio_pci.c         | 28 +++++++++++++++++++++++++++-
 drivers/vfio/pci/vfio_pci_intrs.c   | 18 ++++++++++++++++++
 drivers/vfio/pci/vfio_pci_private.h |  1 +
 include/uapi/linux/vfio.h           |  1 +
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 188b1ff..2d12b03 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -363,7 +363,8 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device 
*vdev, int irq_type)
 
                        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 ||
+                  irq_type == VFIO_PCI_RESUME_IRQ_INDEX) {
                if (pci_is_pcie(vdev->pdev))
                        return 1;
        } else if (irq_type == VFIO_PCI_REQ_IRQ_INDEX) {
@@ -731,6 +732,7 @@ static long vfio_pci_ioctl(void *device_data,
                case VFIO_PCI_REQ_IRQ_INDEX:
                        break;
                case VFIO_PCI_ERR_IRQ_INDEX:
+               case VFIO_PCI_RESUME_IRQ_INDEX:
                        if (pci_is_pcie(vdev->pdev))
                                break;
                /* pass thru to return error */
@@ -1234,8 +1236,32 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct 
pci_dev *pdev,
        return PCI_ERS_RESULT_CAN_RECOVER;
 }
 
+static void vfio_pci_aer_resume(struct pci_dev *pdev)
+{
+       struct vfio_pci_device *vdev;
+       struct vfio_device *device;
+
+       device = vfio_device_get_from_dev(&pdev->dev);
+       if (device == NULL)
+               return;
+
+       vdev = vfio_device_data(device);
+       if (vdev == NULL) {
+               vfio_device_put(device);
+               return;
+       }
+
+       mutex_lock(&vdev->igate);
+       if (vdev->resume_trigger)
+               eventfd_signal(vdev->resume_trigger, 1);
+
+       mutex_unlock(&vdev->igate);
+       vfio_device_put(device);
+}
+
 static const struct pci_error_handlers vfio_err_handlers = {
        .error_detected = vfio_pci_aer_err_detected,
+       .resume         = vfio_pci_aer_resume,
 };
 
 static struct pci_driver vfio_pci_driver = {
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c 
b/drivers/vfio/pci/vfio_pci_intrs.c
index 15ecfc9..3a01a62 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -617,6 +617,16 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_device 
*vdev,
        return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, flags, data);
 }
 
+static int vfio_pci_set_resume_trigger(struct vfio_pci_device *vdev,
+                                   unsigned index, unsigned start,
+                                   unsigned count, uint32_t flags, void *data)
+{
+       if (index != VFIO_PCI_RESUME_IRQ_INDEX)
+               return -EINVAL;
+
+       return vfio_pci_set_ctx_trigger_single(&vdev->resume_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)
@@ -676,6 +686,14 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, 
uint32_t flags,
                        break;
                }
                break;
+       case VFIO_PCI_RESUME_IRQ_INDEX:
+               switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
+               case VFIO_IRQ_SET_ACTION_TRIGGER:
+                       if (pci_is_pcie(vdev->pdev))
+                               func = vfio_pci_set_resume_trigger;
+                       break;
+               }
+               break;
        }
 
        if (!func)
diff --git a/drivers/vfio/pci/vfio_pci_private.h 
b/drivers/vfio/pci/vfio_pci_private.h
index 016c14a..80d4ddd 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -88,6 +88,7 @@ struct vfio_pci_device {
        int                     refcnt;
        struct eventfd_ctx      *err_trigger;
        struct eventfd_ctx      *req_trigger;
+       struct eventfd_ctx      *resume_trigger;
 };
 
 #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 255a211..34ab138 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -433,6 +433,7 @@ enum {
        VFIO_PCI_MSIX_IRQ_INDEX,
        VFIO_PCI_ERR_IRQ_INDEX,
        VFIO_PCI_REQ_IRQ_INDEX,
+       VFIO_PCI_RESUME_IRQ_INDEX,
        VFIO_PCI_NUM_IRQS
 };
 
-- 
1.8.3.1






reply via email to

[Prev in Thread] Current Thread [Next in Thread]