Move bus and domain checks from qemuPCIAddressAsString to a separate function and add a check for function and slot so that we can switch from a hash table to an array. Remove redundant checks in qemuBuildDeviceAddressStr. --- src/qemu/qemu_command.c | 111 +++++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8321dcd..a16d5f1 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1193,17 +1193,43 @@ struct _qemuDomainPCIAddressSet { }; +/* Check the PCI address + * Returns -1 if the address is unusable + * 0 if it's OK. + */ +static int qemuPCIAddressCheck(qemuDomainPCIAddressSetPtr addrs ATTRIBUTE_UNUSED, + virDevicePCIAddressPtr addr) +{ + if (addr->domain != 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Only PCI domain 0 is available")); + return -1; + } + if (addr->bus != 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Only PCI bus 0 is available")); + return -1; + } + if (addr->function >= QEMU_PCI_ADDRESS_LAST_FUNCTION) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address: function must be < %u"), + QEMU_PCI_ADDRESS_LAST_FUNCTION); + return -1; + } + if (addr->slot >= QEMU_PCI_ADDRESS_LAST_SLOT) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address: slot must be < %u"), + QEMU_PCI_ADDRESS_LAST_SLOT); + return -1; + } + return 0; +} + + static char *qemuPCIAddressAsString(virDevicePCIAddressPtr addr) { char *str; - if (addr->domain != 0 || - addr->bus != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Only PCI domain 0 and bus 0 are available")); - return NULL; - } - if (virAsprintf(&str, "%d:%d:%d.%d", addr->domain, addr->bus, @@ -1222,7 +1248,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, void *opaque) { int ret = -1; - char *addr = NULL; + char *str = NULL; + virDevicePCIAddressPtr addr = &info->addr.pci; qemuDomainPCIAddressSetPtr addrs = opaque; if ((info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) @@ -1235,57 +1262,60 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, return 0; } - addr = qemuPCIAddressAsString(&info->addr.pci); - if (!addr) + if (qemuPCIAddressCheck(addrs, addr) < 0) + return -1; + + str = qemuPCIAddressAsString(addr); + if (!str) goto cleanup; - if (virHashLookup(addrs->used, addr)) { + if (virHashLookup(addrs->used, str)) { if (info->addr.pci.function != 0) { virReportError(VIR_ERR_XML_ERROR, _("Attempted double use of PCI Address '%s' " "(may need \"multifunction='on'\" for device on function 0)"), - addr); + str); } else { virReportError(VIR_ERR_XML_ERROR, - _("Attempted double use of PCI Address '%s'"), addr); + _("Attempted double use of PCI Address '%s'"), str); } goto cleanup; } - VIR_DEBUG("Remembering PCI addr %s", addr); - if (virHashAddEntry(addrs->used, addr, addr) < 0) + VIR_DEBUG("Remembering PCI addr %s", str); + if (virHashAddEntry(addrs->used, str, str) < 0) goto cleanup; - addr = NULL; + str = NULL; if ((info->addr.pci.function == 0) && (info->addr.pci.multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON)) { /* a function 0 w/o multifunction=on must reserve the entire slot */ - virDevicePCIAddress tmp_addr = info->addr.pci; + virDevicePCIAddress tmp_addr = *addr; unsigned int *func = &tmp_addr.function; for (*func = 1; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) { - addr = qemuPCIAddressAsString(&tmp_addr); - if (!addr) + str = qemuPCIAddressAsString(&tmp_addr); + if (!str) goto cleanup; - if (virHashLookup(addrs->used, addr)) { + if (virHashLookup(addrs->used, str)) { virReportError(VIR_ERR_XML_ERROR, _("Attempted double use of PCI Address '%s' " "(need \"multifunction='off'\" for device " "on function 0)"), - addr); + str); goto cleanup; } - VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", addr); - if (virHashAddEntry(addrs->used, addr, addr)) + VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", str); + if (virHashAddEntry(addrs->used, str, str)) goto cleanup; - addr = NULL; + str = NULL; } } ret = 0; cleanup: - VIR_FREE(addr); + VIR_FREE(str); return ret; } @@ -1385,6 +1415,9 @@ static int qemuDomainPCIAddressCheckSlot(qemuDomainPCIAddressSetPtr addrs, virDevicePCIAddress tmp_addr = *addr; unsigned int *func = &(tmp_addr.function); + if (qemuPCIAddressCheck(addrs, addr) < 0) + return -1; + for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) { str = qemuPCIAddressAsString(&tmp_addr); if (!str) @@ -1406,6 +1439,9 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs, { char *str; + if (qemuPCIAddressCheck(addrs, addr) < 0) + return -1; + str = qemuPCIAddressAsString(addr); if (!str) return -1; @@ -1479,6 +1515,9 @@ int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs, char *str; int ret; + if (qemuPCIAddressCheck(addrs, addr) < 0) + return -1; + str = qemuPCIAddressAsString(addr); if (!str) return -1; @@ -1498,6 +1537,9 @@ int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, virDevicePCIAddress tmp_addr = *addr; unsigned int *func = &tmp_addr.function; + if (qemuPCIAddressCheck(addrs, addr) < 0) + return -1; + for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) { str = qemuPCIAddressAsString(&tmp_addr); if (!str) @@ -1965,24 +2007,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, virQEMUCapsPtr qemuCaps) { if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { - if (info->addr.pci.domain != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Only PCI device addresses with domain=0 are supported")); - return -1; - } - if (info->addr.pci.bus != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Only PCI device addresses with bus=0 are supported")); - return -1; - } - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) { - if (info->addr.pci.function > 7) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("The function of PCI device addresses must " - "be less than 8")); - return -1; - } - } else { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) { if (info->addr.pci.function != 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only PCI device addresses with function=0 " -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list