static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,

                                   MSIMessage *msg, IOHandler *handler)

{

    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);

    VFIOMSIVector *vector;

    int ret;



    trace_vfio_msix_vector_do_use(vdev->vbasedev.name, nr);



    vector = &vdev->msi_vectors[nr];



    if (!vector->use) {

        vector->vdev = vdev;

        vector->virq = -1;

        if (event_notifier_init(&vector->interrupt, 0)) {

            error_report("vfio: Error: event_notifier_init failed");

        }

        vector->use = true;

        msix_vector_use(pdev, nr);

    }



    qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),

                        handler, NULL, vector);



    /*

     * Attempt to enable route through KVM irqchip,

     * default to userspace handling if unavailable.

     */

    if (vector->virq >= 0) {

        if (!msg) {

            vfio_remove_kvm_msi_virq(vector);

        } else {

            vfio_update_kvm_msi_virq(vector, *msg);

        }

    } else {

        vfio_add_kvm_msi_virq(vector, msg, true);

    }



    /*

     * We don't want to have the host allocate all possible MSI vectors

     * for a device if they're not in use, so we shutdown and incrementally

     * increase them as needed.

     */

    if (vdev->nr_vectors < nr + 1) {

        vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);

        vdev->nr_vectors = nr + 1;

        ret = vfio_enable_vectors(vdev, true);

        if (ret) {

            error_report("vfio: failed to enable vectors, %d", ret);

        }

    } else {

        int argsz;

        struct vfio_irq_set *irq_set;

        int32_t *pfd;



        argsz = sizeof(*irq_set) + sizeof(*pfd);



        irq_set = g_malloc0(argsz);

        irq_set->argsz = argsz;

        irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |

                         VFIO_IRQ_SET_ACTION_TRIGGER;

        irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;

        irq_set->start = nr;

        irq_set->count = 1;

        pfd = (int32_t *)&irq_set->data;



        if (vector->virq >= 0) {

            *pfd = event_notifier_get_fd(&vector->kvm_interrupt);

        } else {

            *pfd = event_notifier_get_fd(&vector->interrupt);

        }



        ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);

        g_free(irq_set);

        if (ret) {

            error_report("vfio: failed to modify vector, %d", ret);

        }

    }



    return 0;

}

static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,

                                   MSIMessage *msg, IOHandler *handler)

{

    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);

    VFIOMSIVector *vector;

    int ret;



    trace_vfio_msix_vector_do_use(vdev->vbasedev.name, nr);



    vector = &vdev->msi_vectors[nr];



    if (!vector->use) {

        vector->vdev = vdev;

        vector->virq = -1;

        if (event_notifier_init(&vector->interrupt, 0)) {

            error_report("vfio: Error: event_notifier_init failed");

        }

        vector->use = true;

        msix_vector_use(pdev, nr);

    }



    qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),

                        handler, NULL, vector);



    







    if (vector->virq >= 0) {

        if (!msg) {

            vfio_remove_kvm_msi_virq(vector);

        } else {

            vfio_update_kvm_msi_virq(vector, *msg);

        }

    } else {

        vfio_add_kvm_msi_virq(vector, msg, true);

    }



    









    if (vdev->nr_vectors < nr + 1) {

        vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);

        vdev->nr_vectors = nr + 1;

        ret = vfio_enable_vectors(vdev, true);

        if (ret) {

            error_report("vfio: failed to enable vectors, %d", ret);

        }

    } else {

        int argsz;

        struct vfio_irq_set *irq_set;

        int32_t *pfd;



        argsz = sizeof(*irq_set) + sizeof(*pfd);



        irq_set = g_malloc0(argsz);

        irq_set->argsz = argsz;

        irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |

                         VFIO_IRQ_SET_ACTION_TRIGGER;

        irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;

        irq_set->start = nr;

        irq_set->count = 1;

        pfd = (int32_t *)&irq_set->data;



        if (vector->virq >= 0) {

            *pfd = event_notifier_get_fd(&vector->kvm_interrupt);

        } else {

            *pfd = event_notifier_get_fd(&vector->interrupt);

        }



        ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);

        g_free(irq_set);

        if (ret) {

            error_report("vfio: failed to modify vector, %d", ret);

        }

    }



    return 0;

}

static int FUNC_0(PCIDevice *VAR_0, unsigned int VAR_1,

                                   MSIMessage *VAR_2, IOHandler *VAR_3)

{

    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, VAR_0, VAR_0);

    VFIOMSIVector *vector;

    int VAR_4;



    trace_vfio_msix_vector_do_use(vdev->vbasedev.name, VAR_1);



    vector = &vdev->msi_vectors[VAR_1];



    if (!vector->use) {

        vector->vdev = vdev;

        vector->virq = -1;

        if (event_notifier_init(&vector->interrupt, 0)) {

            error_report("vfio: Error: event_notifier_init failed");

        }

        vector->use = true;

        msix_vector_use(VAR_0, VAR_1);

    }



    qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),

                        VAR_3, NULL, vector);



    







    if (vector->virq >= 0) {

        if (!VAR_2) {

            vfio_remove_kvm_msi_virq(vector);

        } else {

            vfio_update_kvm_msi_virq(vector, *VAR_2);

        }

    } else {

        vfio_add_kvm_msi_virq(vector, VAR_2, true);

    }



    









    if (vdev->nr_vectors < VAR_1 + 1) {

        vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);

        vdev->nr_vectors = VAR_1 + 1;

        VAR_4 = vfio_enable_vectors(vdev, true);

        if (VAR_4) {

            error_report("vfio: failed to enable vectors, %d", VAR_4);

        }

    } else {

        int VAR_5;

        struct vfio_irq_set *VAR_6;

        int32_t *pfd;



        VAR_5 = sizeof(*VAR_6) + sizeof(*pfd);



        VAR_6 = g_malloc0(VAR_5);

        VAR_6->VAR_5 = VAR_5;

        VAR_6->flags = VFIO_IRQ_SET_DATA_EVENTFD |

                         VFIO_IRQ_SET_ACTION_TRIGGER;

        VAR_6->index = VFIO_PCI_MSIX_IRQ_INDEX;

        VAR_6->start = VAR_1;

        VAR_6->count = 1;

        pfd = (int32_t *)&VAR_6->data;



        if (vector->virq >= 0) {

            *pfd = event_notifier_get_fd(&vector->kvm_interrupt);

        } else {

            *pfd = event_notifier_get_fd(&vector->interrupt);

        }



        VAR_4 = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, VAR_6);

        g_free(VAR_6);

        if (VAR_4) {

            error_report("vfio: failed to modify vector, %d", VAR_4);

        }

    }



    return 0;

}

static int FUNC_0(PCIDevice *VAR_0, unsigned int VAR_1,
MSIMessage *VAR_2, IOHandler *VAR_3)
{ VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, VAR_0, VAR_0); VFIOMSIVector *vector; int VAR_4; trace_vfio_msix_vector_do_use(vdev->vbasedev.name, VAR_1); vector = &vdev->msi_vectors[VAR_1]; if (!vector->use) { vector->vdev = vdev; vector->virq = -1; if (event_notifier_init(&vector->interrupt, 0)) { error_report("vfio: Error: event_notifier_init failed"); } vector->use = true; msix_vector_use(VAR_0, VAR_1); } qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
VAR_3, NULL, vector); if (vector->virq >= 0) { if (!VAR_2) { vfio_remove_kvm_msi_virq(vector); } else { vfio_update_kvm_msi_virq(vector, *VAR_2); } } else { vfio_add_kvm_msi_virq(vector, VAR_2, true); } if (vdev->nr_vectors < VAR_1 + 1) { vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); vdev->nr_vectors = VAR_1 + 1; VAR_4 = vfio_enable_vectors(vdev, true); if (VAR_4) { error_report("vfio: failed to enable vectors, %d", VAR_4); } } else { int VAR_5; struct vfio_irq_set *VAR_6; int32_t *pfd; VAR_5 = sizeof(*VAR_6) + sizeof(*pfd); VAR_6 = g_malloc0(VAR_5); VAR_6->VAR_5 = VAR_5; VAR_6->flags = VFIO_IRQ_SET_DATA_EVENTFD |
VFIO_IRQ_SET_ACTION_TRIGGER; VAR_6->index = VFIO_PCI_MSIX_IRQ_INDEX; VAR_6->start = VAR_1; VAR_6->count = 1; pfd = (int32_t *)&VAR_6->data; if (vector->virq >= 0) { *pfd = event_notifier_get_fd(&vector->kvm_interrupt); } else { *pfd = event_notifier_get_fd(&vector->interrupt); } VAR_4 = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, VAR_6); g_free(VAR_6); if (VAR_4) { error_report("vfio: failed to modify vector, %d", VAR_4); } } return 0; }