Commit 8757c09f authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'awilliam/tags/qemu-1.4-vfio-20130109.0' into staging



vfio-pci: Fixes for qemu 1.4 & stable

* awilliam/tags/qemu-1.4-vfio-20130109.0:
  vfio-pci: Loosen sanity checks to allow future features
  vfio-pci: Make host MSI-X enable track guest

Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents 5e3bc735 8fc94e5a
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -562,8 +562,8 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
    return ret;
}

static int vfio_msix_vector_use(PCIDevice *pdev,
                                unsigned int nr, MSIMessage msg)
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
                                   MSIMessage *msg, IOHandler *handler)
{
    VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
    VFIOMSIVector *vector;
@@ -587,7 +587,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
     * Attempt to enable route through KVM irqchip,
     * default to userspace handling if unavailable.
     */
    vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
    vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
    if (vector->virq < 0 ||
        kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
                                       vector->virq) < 0) {
@@ -596,7 +596,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
            vector->virq = -1;
        }
        qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
                            vfio_msi_interrupt, NULL, vector);
                            handler, NULL, vector);
    }

    /*
@@ -639,6 +639,12 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
    return 0;
}

static int vfio_msix_vector_use(PCIDevice *pdev,
                                unsigned int nr, MSIMessage msg)
{
    return vfio_msix_vector_do_use(pdev, nr, &msg, vfio_msi_interrupt);
}

static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
{
    VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
@@ -697,6 +703,22 @@ static void vfio_enable_msix(VFIODevice *vdev)

    vdev->interrupt = VFIO_INT_MSIX;

    /*
     * Some communication channels between VF & PF or PF & fw rely on the
     * physical state of the device and expect that enabling MSI-X from the
     * guest enables the same on the host.  When our guest is Linux, the
     * guest driver call to pci_enable_msix() sets the enabling bit in the
     * MSI-X capability, but leaves the vector table masked.  We therefore
     * can't rely on a vector_use callback (from request_irq() in the guest)
     * to switch the physical device into MSI-X mode because that may come a
     * long time after pci_enable_msix().  This code enables vector 0 with
     * 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.
     */
    vfio_msix_vector_do_use(&vdev->pdev, 0, NULL, NULL);
    vfio_msix_vector_release(&vdev->pdev, 0);

    if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
                                  vfio_msix_vector_release, NULL)) {
        error_report("vfio: msix_set_vector_notifiers failed\n");
@@ -1815,13 +1837,13 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
        error_report("Warning, device %s does not support reset\n", name);
    }

    if (dev_info.num_regions != VFIO_PCI_NUM_REGIONS) {
    if (dev_info.num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
        error_report("vfio: unexpected number of io regions %u\n",
                     dev_info.num_regions);
        goto error;
    }

    if (dev_info.num_irqs != VFIO_PCI_NUM_IRQS) {
    if (dev_info.num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {
        error_report("vfio: unexpected number of irqs %u\n", dev_info.num_irqs);
        goto error;
    }