aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio
diff options
context:
space:
mode:
Diffstat (limited to 'hw/vfio')
-rw-r--r--hw/vfio/pci.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 759a3b1abf..5c65aa0a98 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -569,6 +569,9 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
static void vfio_msix_enable(VFIOPCIDevice *vdev)
{
+ PCIDevice *pdev = &vdev->pdev;
+ unsigned int nr, max_vec = 0;
+
vfio_disable_interrupts(vdev);
vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->msix->entries);
@@ -587,11 +590,22 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
* triggering to userspace, then immediately release the vector, leaving
* the physical device with no vectors enabled, but MSI-X enabled, just
* like the guest view.
+ * If there are already unmasked vectors (in migration resume phase and
+ * some guest startups) which will be enabled soon, we can allocate all
+ * of them here to avoid inefficiently disabling and enabling vectors
+ * repeatedly later.
*/
- vfio_msix_vector_do_use(&vdev->pdev, 0, NULL, NULL);
- vfio_msix_vector_release(&vdev->pdev, 0);
+ if (!pdev->msix_function_masked) {
+ for (nr = 0; nr < msix_nr_vectors_allocated(pdev); nr++) {
+ if (!msix_is_masked(pdev, nr)) {
+ max_vec = nr;
+ }
+ }
+ }
+ vfio_msix_vector_do_use(pdev, max_vec, NULL, NULL);
+ vfio_msix_vector_release(pdev, max_vec);
- if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
+ if (msix_set_vector_notifiers(pdev, vfio_msix_vector_use,
vfio_msix_vector_release, NULL)) {
error_report("vfio: msix_set_vector_notifiers failed");
}