diff options
Diffstat (limited to 'hw/pci')
-rw-r--r-- | hw/pci/msix.c | 30 | ||||
-rw-r--r-- | hw/pci/pci.c | 43 |
2 files changed, 33 insertions, 40 deletions
diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 031eaab..9935f98 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -295,29 +295,37 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, { int ret; char *name; + uint32_t bar_size = 4096; + uint32_t bar_pba_offset = bar_size / 2; + uint32_t bar_pba_size = (nentries / 8 + 1) * 8; /* * Migration compatibility dictates that this remains a 4k * BAR with the vector table in the lower half and PBA in - * the upper half. Do not use these elsewhere! + * the upper half for nentries which is lower or equal to 128. + * No need to care about using more than 65 entries for legacy + * machine types who has at most 64 queues. */ -#define MSIX_EXCLUSIVE_BAR_SIZE 4096 -#define MSIX_EXCLUSIVE_BAR_TABLE_OFFSET 0 -#define MSIX_EXCLUSIVE_BAR_PBA_OFFSET (MSIX_EXCLUSIVE_BAR_SIZE / 2) -#define MSIX_EXCLUSIVE_CAP_OFFSET 0 + if (nentries * PCI_MSIX_ENTRY_SIZE > bar_pba_offset) { + bar_pba_offset = nentries * PCI_MSIX_ENTRY_SIZE; + } - if (nentries * PCI_MSIX_ENTRY_SIZE > MSIX_EXCLUSIVE_BAR_PBA_OFFSET) { - return -EINVAL; + if (bar_pba_offset + bar_pba_size > 4096) { + bar_size = bar_pba_offset + bar_pba_size; + } + + if (bar_size & (bar_size - 1)) { + bar_size = 1 << qemu_fls(bar_size); } name = g_strdup_printf("%s-msix", dev->name); - memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, MSIX_EXCLUSIVE_BAR_SIZE); + memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, bar_size); g_free(name); ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr, - MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar, - bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET, - MSIX_EXCLUSIVE_CAP_OFFSET); + 0, &dev->msix_exclusive_bar, + bar_nr, bar_pba_offset, + 0); if (ret) { return ret; } diff --git a/hw/pci/pci.c b/hw/pci/pci.c index f5c7a99..48f19a3 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1615,28 +1615,32 @@ static const char * const pci_nic_names[] = { }; /* Initialize a PCI NIC. */ -static PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, +PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, const char *default_model, - const char *default_devaddr, - Error **errp) + const char *default_devaddr) { const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr; Error *err = NULL; PCIBus *bus; - int devfn; PCIDevice *pci_dev; DeviceState *dev; + int devfn; int i; + if (qemu_show_nic_models(nd->model, pci_nic_models)) { + exit(0); + } + i = qemu_find_nic_model(nd, pci_nic_models, default_model); - if (i < 0) - return NULL; + if (i < 0) { + exit(1); + } bus = pci_get_bus_devfn(&devfn, rootbus, devaddr); if (!bus) { error_report("Invalid PCI device address %s for device %s", devaddr, pci_nic_names[i]); - return NULL; + exit(1); } pci_dev = pci_create(bus, devfn, pci_nic_names[i]); @@ -1645,31 +1649,12 @@ static PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, object_property_set_bool(OBJECT(dev), true, "realized", &err); if (err) { - error_propagate(errp, err); + error_report_err(err); object_unparent(OBJECT(dev)); - return NULL; - } - return pci_dev; -} - -PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, - const char *default_model, - const char *default_devaddr) -{ - Error *err = NULL; - PCIDevice *res; - - if (qemu_show_nic_models(nd->model, pci_nic_models)) - exit(0); - - res = pci_nic_init(nd, rootbus, default_model, default_devaddr, &err); - if (!res) { - if (err) { - error_report_err(err); - } exit(1); } - return res; + + return pci_dev; } PCIDevice *pci_vga_init(PCIBus *bus) |