Index: sys/dev/virtio/pci/virtio_pci.c =================================================================== --- sys/dev/virtio/pci/virtio_pci.c +++ sys/dev/virtio/pci/virtio_pci.c @@ -278,10 +278,12 @@ { struct vtpci_softc *sc; device_t child; + int msix_load; int rid; sc = device_get_softc(dev); sc->vtpci_dev = dev; + msix_load = 0; pci_enable_busmaster(dev); @@ -306,19 +308,36 @@ sc->vtpci_flags |= VTPCI_FLAG_NO_MSI; if (pci_find_cap(dev, PCIY_MSIX, NULL) == 0) { - int table_bar; + int table_rid; + + rid = table_rid = pci_msix_table_bar(dev); + if (table_rid != PCIR_BAR(0)) { + sc->vtpci_msix_table_res = bus_alloc_resource_any( + dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (sc->vtpci_msix_table_res != NULL) + msix_load++; + } else + msix_load++; - rid = table_bar = pci_msix_table_bar(dev); - sc->vtpci_msix_table_res = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); rid = pci_msix_pba_bar(dev); - if (rid != table_bar) - sc->vtpci_msix_pba_res = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (rid != table_rid) { + sc->vtpci_msix_pba_res = bus_alloc_resource_any( + dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (sc->vtpci_msix_pba_res != NULL) + msix_load++; + } else + msix_load++; } - if (sc->vtpci_msix_table_res == NULL) + if (msix_load != 2) { sc->vtpci_flags |= VTPCI_FLAG_NO_MSIX; + if (sc->vtpci_msix_table_res) { + bus_release_resource(dev, SYS_RES_MEMORY, + rman_get_rid(sc->vtpci_msix_table_res), + sc->vtpci_msix_table_res); + sc->vtpci_msix_table_res = NULL; + } + } vtpci_reset(sc);