Index: sys/dev/virtio/pci/virtio_pci.c =================================================================== --- sys/dev/virtio/pci/virtio_pci.c +++ sys/dev/virtio/pci/virtio_pci.c @@ -67,6 +67,7 @@ struct vtpci_softc { device_t vtpci_dev; + int vtpci_res_type; struct resource *vtpci_res; struct resource *vtpci_msix_res; uint64_t vtpci_features; @@ -275,20 +276,31 @@ static int vtpci_attach(device_t dev) { + const int res_types[] = { SYS_RES_IOPORT, SYS_RES_MEMORY }; struct vtpci_softc *sc; device_t child; int rid; + int i; sc = device_get_softc(dev); sc->vtpci_dev = dev; pci_enable_busmaster(dev); - rid = PCIR_BAR(0); - sc->vtpci_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, - RF_ACTIVE); + /* + * Most hypervisors export the common configuration structure in IO + * space, but some use memory space; try both. + */ + for (i = 0; nitems(res_types); i++) { + rid = PCIR_BAR(0); + sc->vtpci_res_type = res_types[i]; + sc->vtpci_res = bus_alloc_resource_any(dev, res_types[i], &rid, + RF_ACTIVE); + if (sc->vtpci_res != NULL) + break; + } if (sc->vtpci_res == NULL) { - device_printf(dev, "cannot map I/O space\n"); + device_printf(dev, "cannot map I/O nor memory space\n"); return (ENXIO); } @@ -347,7 +359,7 @@ } if (sc->vtpci_res != NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), + bus_release_resource(dev, sc->vtpci_res_type, PCIR_BAR(0), sc->vtpci_res); sc->vtpci_res = NULL; }