'defer_kvm_irq_routing' indicates whether we should defer to commit the kvm routing.
Signed-off-by: Longpeng(Mike) <longpe...@huawei.com> --- hw/vfio/pci.c | 42 +++++++++++++++++++++++++++++++++++++++++- hw/vfio/pci.h | 1 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 8236cd7..dda60a5 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -422,12 +422,24 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, return; } - virq = kvm_irqchip_add_msi_route(kvm_state, vector_n, &vdev->pdev); + virq = kvm_irqchip_add_deferred_msi_route(kvm_state, vector_n, &vdev->pdev); if (virq < 0) { event_notifier_cleanup(&vector->kvm_interrupt); return; } + if (vdev->defer_kvm_irq_routing) { + /* + * Hold the allocated virq in vector->virq temporarily, will + * reset it to -1 when we fail to add the corresponding irqfd + * in vfio_commit_kvm_msi_virq(). + */ + vector->virq = virq; + return; + } + + kvm_irqchip_commit_routes(); + if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt, NULL, virq) < 0) { kvm_irqchip_release_virq(kvm_state, virq); @@ -566,6 +578,34 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr) } } +static void vfio_commit_kvm_msi_virq(VFIOPCIDevice *vdev) +{ + int i; + VFIOMSIVector *vector; + + if (!vdev->defer_kvm_irq_routing || !vdev->nr_vectors) { + return; + } + + kvm_irqchip_commit_routes(kvm_state); + + for (i = 0; i < vdev->nr_vectors; i++) { + vector = &vdev->msi_vectors[i]; + + if (!vector->use || vector->virq < 0) { + continue; + } + + if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, + &vector->kvm_interrupt, + NULL, vector->virq) < 0) { + kvm_irqchip_release_virq(kvm_state, vector->virq); + event_notifier_cleanup(&vector->kvm_interrupt); + vector->virq = -1; + } + } +} + static void vfio_msix_enable(VFIOPCIDevice *vdev) { PCIDevice *pdev = &vdev->pdev; diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 6477751..d3c5177 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -171,6 +171,7 @@ struct VFIOPCIDevice { bool no_kvm_ioeventfd; bool no_vfio_ioeventfd; bool enable_ramfb; + bool defer_kvm_irq_routing; VFIODisplay *dpy; Notifier irqchip_change_notifier; }; -- 1.8.3.1