Skip to content

Commit

Permalink
Merge remote-tracking branch 'awilliam/tags/qemu-1.4-vfio-20130109.0'…
Browse files Browse the repository at this point in the history
… 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: Anthony Liguori <aliguori@us.ibm.com>
  • Loading branch information
Anthony Liguori committed Jan 10, 2013
2 parents 5e3bc73 + 8fc94e5 commit 8757c09
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions hw/vfio_pci.c
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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);
}

/*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 8757c09

Please sign in to comment.