Commit 14526738 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150706.0' into staging



VFIO updates for 2.4-rc0
- "real" host page size API (Peter Crosthwaite)
- platform device irqfd support (Eric Auger)
- spapr container disconnect fix (Alexey Kardashevskiy)
- quirk for broken Chelsio hardware (Gabriel Laupre)
- coverity fix (Paolo Bonzini)

# gpg: Signature made Mon Jul  6 19:23:49 2015 BST using RSA key ID 3BB08B22
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>"
# gpg:                 aka "Alex Williamson <alex@shazbot.org>"
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>"
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>"

* remotes/awilliam/tags/vfio-update-20150706.0:
  vfio/pci : Add pba_offset PCI quirk for Chelsio T5 devices
  vfio: Unregister IOMMU notifiers when container is destroyed
  hw/vfio/platform: add irqfd support
  kvm: some fixes to kvm_resamplefds_allowed
  sysbus: add irq_routing_notifier
  intc: arm_gic_kvm: set the qemu_irq/gsi mapping
  kvm-all.c: add qemu_irq/gsi hash table and utility routines
  kvm: rename kvm_irqchip_[add,remove]_irqfd_notifier with gsi suffix
  vfio: cpu: Use "real" page size API
  cpu-all: complete "real" host page size API
  vfio: fix return type of pread

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>

Conflicts:
	kvm-all.c
parents f6e3035f 43302969
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -109,7 +109,13 @@ qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n)

void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
{
    SysBusDeviceClass *sbd = SYS_BUS_DEVICE_GET_CLASS(dev);

    qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq);

    if (sbd->connect_irq_notifier) {
        sbd->connect_irq_notifier(dev, irq);
    }
}

/* Check whether an MMIO region exists */
+6 −0
Original line number Diff line number Diff line
@@ -570,6 +570,12 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
     */
    i += (GIC_INTERNAL * s->num_cpu);
    qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i);

    for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
        qemu_irq irq = qdev_get_gpio_in(dev, i);
        kvm_irqchip_set_qemuirq_gsi(kvm_state, irq, i);
    }

    /* We never use our outbound IRQ/FIQ lines but provide them so that
     * we maintain the same interface as the non-KVM GIC.
     */
+4 −4
Original line number Diff line number Diff line
@@ -1316,7 +1316,7 @@ static int virtio_ccw_add_irqfd(VirtioCcwDevice *dev, int n)
    VirtQueue *vq = virtio_get_queue(vdev, n);
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);

    return kvm_irqchip_add_irqfd_notifier(kvm_state, notifier, NULL,
    return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, notifier, NULL,
                                              dev->routes.gsi[n]);
}

@@ -1327,7 +1327,7 @@ static void virtio_ccw_remove_irqfd(VirtioCcwDevice *dev, int n)
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
    int ret;

    ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, notifier,
    ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, notifier,
                                                dev->routes.gsi[n]);
    assert(ret == 0);
}
+8 −0
Original line number Diff line number Diff line
@@ -772,11 +772,19 @@ static void vfio_disconnect_container(VFIOGroup *group)

    if (QLIST_EMPTY(&container->group_list)) {
        VFIOAddressSpace *space = container->space;
        VFIOGuestIOMMU *giommu, *tmp;

        if (container->iommu_data.release) {
            container->iommu_data.release(container);
        }
        QLIST_REMOVE(container, next);

        QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) {
            memory_region_unregister_iommu_notifier(&giommu->n);
            QLIST_REMOVE(giommu, giommu_next);
            g_free(giommu);
        }

        trace_vfio_disconnect_container(container->fd);
        close(container->fd);
        g_free(container);
+35 −7
Original line number Diff line number Diff line
@@ -597,7 +597,7 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
        return;
    }

    if (kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->kvm_interrupt,
    if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt,
                                       NULL, virq) < 0) {
        kvm_irqchip_release_virq(kvm_state, virq);
        event_notifier_cleanup(&vector->kvm_interrupt);
@@ -609,7 +609,7 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,

static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
{
    kvm_irqchip_remove_irqfd_notifier(kvm_state, &vector->kvm_interrupt,
    kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt,
                                          vector->virq);
    kvm_irqchip_release_virq(kvm_state, vector->virq);
    vector->virq = -1;
@@ -939,7 +939,7 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
    };
    uint64_t size;
    off_t off = 0;
    size_t bytes;
    ssize_t bytes;

    if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {
        error_report("vfio: Error getting ROM info: %m");
@@ -2252,6 +2252,33 @@ static int vfio_early_setup_msix(VFIOPCIDevice *vdev)
    vdev->msix->pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK;
    vdev->msix->entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;

    /*
     * Test the size of the pba_offset variable and catch if it extends outside
     * of the specified BAR. If it is the case, we need to apply a hardware
     * specific quirk if the device is known or we have a broken configuration.
     */
    if (vdev->msix->pba_offset >=
        vdev->bars[vdev->msix->pba_bar].region.size) {

        PCIDevice *pdev = &vdev->pdev;
        uint16_t vendor = pci_get_word(pdev->config + PCI_VENDOR_ID);
        uint16_t device = pci_get_word(pdev->config + PCI_DEVICE_ID);

        /*
         * Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5
         * adapters. The T5 hardware returns an incorrect value of 0x8000 for
         * the VF PBA offset while the BAR itself is only 8k. The correct value
         * is 0x1000, so we hard code that here.
         */
        if (vendor == PCI_VENDOR_ID_CHELSIO && (device & 0xff00) == 0x5800) {
            vdev->msix->pba_offset = 0x1000;
        } else {
            error_report("vfio: Hardware reports invalid configuration, "
                         "MSIX PBA outside of specified BAR");
            return -EINVAL;
        }
    }

    trace_vfio_early_setup_msix(vdev->vbasedev.name, pos,
                                vdev->msix->table_bar,
                                vdev->msix->table_offset,
@@ -2388,7 +2415,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
     * potentially insert a direct-mapped subregion before and after it.
     */
    if (vdev->msix && vdev->msix->table_bar == nr) {
        size = vdev->msix->table_offset & qemu_host_page_mask;
        size = vdev->msix->table_offset & qemu_real_host_page_mask;
    }

    strncat(name, " mmap", sizeof(name) - strlen(name) - 1);
@@ -2401,8 +2428,9 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
    if (vdev->msix && vdev->msix->table_bar == nr) {
        uint64_t start;

        start = HOST_PAGE_ALIGN((uint64_t)vdev->msix->table_offset +
                                (vdev->msix->entries * PCI_MSIX_ENTRY_SIZE));
        start = REAL_HOST_PAGE_ALIGN((uint64_t)vdev->msix->table_offset +
                                     (vdev->msix->entries *
                                      PCI_MSIX_ENTRY_SIZE));

        size = start < bar->region.size ? bar->region.size - start : 0;
        strncat(name, " msix-hi", sizeof(name) - strlen(name) - 1);
Loading