[libvirt] [PATCH v4 2/3] qemu: extract common PCI handling functions

Roman Bogorodskiy bogorodskiy at gmail.com
Sun May 11 06:48:16 UTC 2014


Move sharable PCI handling functions to domain_addr.[ch], and
change theirs prefix from 'qemu' to 'vir':

 - virDomainPCIAddressAsString;
 - virDomainPCIAddressBusSetModel;
 - virDomainPCIAddressEnsureAddr;
 - virDomainPCIAddressFlagsCompatible;
 - virDomainPCIAddressGetNextSlot;
 - virDomainPCIAddressReleaseSlot;
 - virDomainPCIAddressReserveAddr;
 - virDomainPCIAddressReserveNextSlot;
 - virDomainPCIAddressReserveSlot;
 - virDomainPCIAddressSetFree;
 - virDomainPCIAddressSetGrow;
 - virDomainPCIAddressSlotInUse;
 - virDomainPCIAddressValidate;

The only change here is function names, the implementation itself
stays untouched.

Extract common allocation code from DomainPCIAddressSetCreate
into virDomainPCIAddressSetAlloc.
---
 po/POTFILES.in           |   1 +
 src/conf/domain_addr.c   | 542 ++++++++++++++++++++++++++++++++++++++
 src/conf/domain_addr.h   |  70 +++++
 src/libvirt_private.syms |  17 ++
 src/qemu/qemu_command.c  | 671 ++++++-----------------------------------------
 src/qemu/qemu_command.h  |  18 +-
 src/qemu/qemu_domain.c   |   3 +-
 src/qemu/qemu_hotplug.c  |   8 +-
 src/qemu/qemu_process.c  |   2 +-
 9 files changed, 718 insertions(+), 614 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index e35eb82..6e8d465 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,6 +14,7 @@ src/bhyve/bhyve_process.c
 src/conf/capabilities.c
 src/conf/cpu_conf.c
 src/conf/device_conf.c
+src/conf/domain_addr.c
 src/conf/domain_conf.c
 src/conf/domain_event.c
 src/conf/interface_conf.c
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 73e17aa..34a3fac 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -22,3 +22,545 @@
  */
 
 #include <config.h>
+
+#include "viralloc.h"
+#include "virlog.h"
+#include "virstring.h"
+#include "domain_addr.h"
+
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
+VIR_LOG_INIT("conf.domain_addr");
+
+bool
+virDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
+                                   const char *addrStr,
+                                   virDomainPCIConnectFlags busFlags,
+                                   virDomainPCIConnectFlags devFlags,
+                                   bool reportError,
+                                   bool fromConfig)
+{
+    virErrorNumber errType = (fromConfig
+                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
+    virDomainPCIConnectFlags flagsMatchMask = VIR_PCI_CONNECT_TYPES_MASK;
+
+    if (fromConfig)
+       flagsMatchMask |= VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG;
+
+    /* If this bus doesn't allow the type of connection (PCI
+     * vs. PCIe) required by the device, or if the device requires
+     * hot-plug and this bus doesn't have it, return false.
+     */
+    if (!(devFlags & busFlags & flagsMatchMask)) {
+        if (reportError) {
+            if (devFlags & VIR_PCI_CONNECT_TYPE_PCI) {
+                virReportError(errType,
+                               _("PCI bus is not compatible with the device "
+                                 "at %s. Device requires a standard PCI slot, "
+                                 "which is not provided by bus %.4x:%.2x"),
+                               addrStr, addr->domain, addr->bus);
+            } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE) {
+                virReportError(errType,
+                               _("PCI bus is not compatible with the device "
+                                 "at %s. Device requires a PCI Express slot, "
+                                 "which is not provided by bus %.4x:%.2x"),
+                               addrStr, addr->domain, addr->bus);
+            } else {
+                /* this should never happen. If it does, there is a
+                 * bug in the code that sets the flag bits for devices.
+                 */
+                virReportError(errType,
+                           _("The device information for %s has no PCI "
+                             "connection types listed"), addrStr);
+            }
+        }
+        return false;
+    }
+    if ((devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) &&
+        !(busFlags & VIR_PCI_CONNECT_HOTPLUGGABLE)) {
+        if (reportError) {
+            virReportError(errType,
+                           _("PCI bus is not compatible with the device "
+                             "at %s. Device requires hot-plug capability, "
+                             "which is not provided by bus %.4x:%.2x"),
+                           addrStr, addr->domain, addr->bus);
+        }
+        return false;
+    }
+    return true;
+}
+
+
+/* Verify that the address is in bounds for the chosen bus, and
+ * that the bus is of the correct type for the device (via
+ * comparing the flags).
+ */
+bool
+virDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
+                            virDevicePCIAddressPtr addr,
+                            const char *addrStr,
+                            virDomainPCIConnectFlags flags,
+                            bool fromConfig)
+{
+    virDomainPCIAddressBusPtr bus;
+    virErrorNumber errType = (fromConfig
+                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
+
+    if (addrs->nbuses == 0) {
+        virReportError(errType, "%s", _("No PCI buses available"));
+        return false;
+    }
+    if (addr->domain != 0) {
+        virReportError(errType,
+                       _("Invalid PCI address %s. "
+                         "Only PCI domain 0 is available"),
+                       addrStr);
+        return false;
+    }
+    if (addr->bus >= addrs->nbuses) {
+        virReportError(errType,
+                       _("Invalid PCI address %s. "
+                         "Only PCI buses up to %zu are available"),
+                       addrStr, addrs->nbuses - 1);
+        return false;
+    }
+
+    bus = &addrs->buses[addr->bus];
+
+    /* assure that at least one of the requested connection types is
+     * provided by this bus
+     */
+    if (!virDomainPCIAddressFlagsCompatible(addr, addrStr, bus->flags,
+                                            flags, true, fromConfig))
+        return false;
+
+    /* some "buses" are really just a single port */
+    if (bus->minSlot && addr->slot < bus->minSlot) {
+        virReportError(errType,
+                       _("Invalid PCI address %s. slot must be >= %zu"),
+                       addrStr, bus->minSlot);
+        return false;
+    }
+    if (addr->slot > bus->maxSlot) {
+        virReportError(errType,
+                       _("Invalid PCI address %s. slot must be <= %zu"),
+                       addrStr, bus->maxSlot);
+        return false;
+    }
+    if (addr->function > VIR_PCI_ADDRESS_FUNCTION_LAST) {
+        virReportError(errType,
+                       _("Invalid PCI address %s. function must be <= %u"),
+                       addrStr, VIR_PCI_ADDRESS_FUNCTION_LAST);
+        return false;
+    }
+    return true;
+}
+
+
+int
+virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
+                               virDomainControllerModelPCI model)
+{
+    switch (model) {
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+        bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
+                      VIR_PCI_CONNECT_TYPE_PCI);
+        bus->minSlot = 1;
+        bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
+        break;
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+        /* slots 1 - 31, no hotplug, PCIe only unless the address was
+         * specified in user config *and* the particular device being
+         * attached also allows it
+         */
+        bus->flags = (VIR_PCI_CONNECT_TYPE_PCIE |
+                      VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
+        bus->minSlot = 1;
+        bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
+        break;
+    case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+        /* slots 1 - 31, standard PCI slots,
+         * but *not* hot-pluggable */
+        bus->flags = VIR_PCI_CONNECT_TYPE_PCI;
+        bus->minSlot = 1;
+        bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
+        break;
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Invalid PCI controller model %d"), model);
+        return -1;
+    }
+
+    bus->model = model;
+    return 0;
+}
+
+
+/* Ensure addr fits in the address set, by expanding it if needed.
+ * This will only grow if the flags say that we need a normal
+ * hot-pluggable PCI slot. If we need a different type of slot, it
+ * will fail.
+ *
+ * Return value:
+ * -1 = OOM
+ *  0 = no action performed
+ * >0 = number of buses added
+ */
+int
+virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
+                           virDevicePCIAddressPtr addr,
+                           virDomainPCIConnectFlags flags)
+{
+    int add;
+    size_t i;
+
+    add = addr->bus - addrs->nbuses + 1;
+    i = addrs->nbuses;
+    if (add <= 0)
+        return 0;
+
+    /* auto-grow only works when we're adding plain PCI devices */
+    if (!(flags & VIR_PCI_CONNECT_TYPE_PCI)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot automatically add a new PCI bus for a "
+                         "device requiring a slot other than standard PCI."));
+        return -1;
+    }
+
+    if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, add) < 0)
+        return -1;
+
+    for (; i < addrs->nbuses; i++) {
+        /* Any time we auto-add a bus, we will want a multi-slot
+         * bus. Currently the only type of bus we will auto-add is a
+         * pci-bridge, which is hot-pluggable and provides standard
+         * PCI slots.
+         */
+        virDomainPCIAddressBusSetModel(&addrs->buses[i],
+                                       VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
+    }
+    return add;
+}
+
+
+char *
+virDomainPCIAddressAsString(virDevicePCIAddressPtr addr)
+{
+    char *str;
+
+    ignore_value(virAsprintf(&str, "%.4x:%.2x:%.2x.%.1x",
+                             addr->domain,
+                             addr->bus,
+                             addr->slot,
+                             addr->function));
+    return str;
+}
+
+
+/*
+ * Check if the PCI slot is used by another device.
+ */
+bool
+virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs,
+                             virDevicePCIAddressPtr addr)
+{
+    return !!addrs->buses[addr->bus].slots[addr->slot];
+}
+
+
+/*
+ * Reserve a slot (or just one function) for a device. If
+ * reserveEntireSlot is true, all functions for the slot are reserved,
+ * otherwise only one. If fromConfig is true, the address being
+ * requested came directly from the config and errors should be worded
+ * appropriately. If fromConfig is false, the address was
+ * automatically created by libvirt, so it is an internal error (not
+ * XML).
+ */
+int
+virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
+                               virDevicePCIAddressPtr addr,
+                               virDomainPCIConnectFlags flags,
+                               bool reserveEntireSlot,
+                               bool fromConfig)
+{
+    int ret = -1;
+    char *addrStr = NULL;
+    virDomainPCIAddressBusPtr bus;
+    virErrorNumber errType = (fromConfig
+                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
+
+    if (!(addrStr = virDomainPCIAddressAsString(addr)))
+        goto cleanup;
+
+    /* Add an extra bus if necessary */
+    if (addrs->dryRun && virDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
+        goto cleanup;
+    /* Check that the requested bus exists, is the correct type, and we
+     * are asking for a valid slot
+     */
+    if (!virDomainPCIAddressValidate(addrs, addr, addrStr, flags, fromConfig))
+        goto cleanup;
+
+    bus = &addrs->buses[addr->bus];
+
+    if (reserveEntireSlot) {
+        if (bus->slots[addr->slot]) {
+            virReportError(errType,
+                           _("Attempted double use of PCI slot %s "
+                             "(may need \"multifunction='on'\" for "
+                             "device on function 0)"), addrStr);
+            goto cleanup;
+        }
+        bus->slots[addr->slot] = 0xFF; /* reserve all functions of slot */
+        VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr);
+    } else {
+        if (bus->slots[addr->slot] & (1 << addr->function)) {
+            if (addr->function == 0) {
+                virReportError(errType,
+                               _("Attempted double use of PCI Address %s"),
+                               addrStr);
+            } else {
+                virReportError(errType,
+                               _("Attempted double use of PCI Address %s "
+                                 "(may need \"multifunction='on'\" "
+                                 "for device on function 0)"), addrStr);
+            }
+            goto cleanup;
+        }
+        bus->slots[addr->slot] |= (1 << addr->function);
+        VIR_DEBUG("Reserving PCI address %s", addrStr);
+    }
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(addrStr);
+    return ret;
+}
+
+
+int
+virDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
+                               virDevicePCIAddressPtr addr,
+                               virDomainPCIConnectFlags flags)
+{
+    return virDomainPCIAddressReserveAddr(addrs, addr, flags, true, false);
+}
+
+int
+virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
+                              virDomainDeviceInfoPtr dev)
+{
+    int ret = -1;
+    char *addrStr = NULL;
+    /* Flags should be set according to the particular device,
+     * but only the caller knows the type of device. Currently this
+     * function is only used for hot-plug, though, and hot-plug is
+     * only supported for standard PCI devices, so we can safely use
+     * the setting below */
+    virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
+                                      VIR_PCI_CONNECT_TYPE_PCI);
+
+    if (!(addrStr = virDomainPCIAddressAsString(&dev->addr.pci)))
+        goto cleanup;
+
+    if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+        /* We do not support hotplug multi-function PCI device now, so we should
+         * reserve the whole slot. The function of the PCI device must be 0.
+         */
+        if (dev->addr.pci.function != 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Only PCI device addresses with function=0"
+                             " are supported"));
+            goto cleanup;
+        }
+
+        if (!virDomainPCIAddressValidate(addrs, &dev->addr.pci,
+                                          addrStr, flags, true))
+            goto cleanup;
+
+        ret = virDomainPCIAddressReserveSlot(addrs, &dev->addr.pci, flags);
+    } else {
+        ret = virDomainPCIAddressReserveNextSlot(addrs, dev, flags);
+    }
+
+ cleanup:
+    VIR_FREE(addrStr);
+    return ret;
+}
+
+
+int
+virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
+                               virDevicePCIAddressPtr addr)
+{
+    addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function);
+    return 0;
+}
+
+int
+virDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs,
+                               virDevicePCIAddressPtr addr)
+{
+    /* permit any kind of connection type in validation, since we
+     * already had it, and are giving it back.
+     */
+    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPES_MASK;
+    int ret = -1;
+    char *addrStr = NULL;
+
+    if (!(addrStr = virDomainPCIAddressAsString(addr)))
+        goto cleanup;
+
+    if (!virDomainPCIAddressValidate(addrs, addr, addrStr, flags, false))
+        goto cleanup;
+
+    addrs->buses[addr->bus].slots[addr->slot] = 0;
+    ret = 0;
+ cleanup:
+    VIR_FREE(addrStr);
+    return ret;
+}
+
+
+virDomainPCIAddressSetPtr
+virDomainPCIAddressSetAlloc(unsigned int nbuses)
+{
+    virDomainPCIAddressSetPtr addrs;
+
+    if (VIR_ALLOC(addrs) < 0)
+        goto error;
+
+    if (VIR_ALLOC_N(addrs->buses, nbuses) < 0)
+        goto error;
+
+    addrs->nbuses = nbuses;
+    return addrs;
+
+ error:
+    virDomainPCIAddressSetFree(addrs);
+    return NULL;
+}
+
+
+void
+virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs)
+{
+    if (!addrs)
+        return;
+
+    VIR_FREE(addrs->buses);
+    VIR_FREE(addrs);
+}
+
+
+int
+virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
+                               virDevicePCIAddressPtr next_addr,
+                               virDomainPCIConnectFlags flags)
+{
+    /* default to starting the search for a free slot from
+     * 0000:00:00.0
+     */
+    virDevicePCIAddress a = { 0, 0, 0, 0, false };
+    char *addrStr = NULL;
+
+    /* except if this search is for the exact same type of device as
+     * last time, continue the search from the previous match
+     */
+    if (flags == addrs->lastFlags)
+        a = addrs->lastaddr;
+
+    if (addrs->nbuses == 0) {
+        virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
+        goto error;
+    }
+
+    /* Start the search at the last used bus and slot */
+    for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
+        if (!(addrStr = virDomainPCIAddressAsString(&a)))
+            goto error;
+        if (!virDomainPCIAddressFlagsCompatible(&a, addrStr,
+                                                addrs->buses[a.bus].flags,
+                                                flags, false, false)) {
+            VIR_FREE(addrStr);
+            VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
+                      a.domain, a.bus);
+            continue;
+        }
+        for (; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
+            if (!virDomainPCIAddressSlotInUse(addrs, &a))
+                goto success;
+
+            VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
+                      a.domain, a.bus, a.slot);
+        }
+        a.slot = 1;
+        VIR_FREE(addrStr);
+    }
+
+    /* There were no free slots after the last used one */
+    if (addrs->dryRun) {
+        /* a is already set to the first new bus and slot 1 */
+        if (virDomainPCIAddressSetGrow(addrs, &a, flags) < 0)
+            goto error;
+        goto success;
+    } else if (flags == addrs->lastFlags) {
+        /* Check the buses from 0 up to the last used one */
+        for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
+            addrStr = NULL;
+            if (!(addrStr = virDomainPCIAddressAsString(&a)))
+                goto error;
+            if (!virDomainPCIAddressFlagsCompatible(&a, addrStr,
+                                                    addrs->buses[a.bus].flags,
+                                                    flags, false, false)) {
+                VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
+                          a.domain, a.bus);
+                continue;
+            }
+            for (a.slot = 1; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
+                if (!virDomainPCIAddressSlotInUse(addrs, &a))
+                    goto success;
+
+                VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
+                          a.domain, a.bus, a.slot);
+            }
+        }
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR,
+                   "%s", _("No more available PCI slots"));
+ error:
+    VIR_FREE(addrStr);
+    return -1;
+
+ success:
+    VIR_DEBUG("Found free PCI slot %.4x:%.2x:%.2x",
+              a.domain, a.bus, a.slot);
+    *next_addr = a;
+    VIR_FREE(addrStr);
+    return 0;
+}
+
+int
+virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
+                                   virDomainDeviceInfoPtr dev,
+                                   virDomainPCIConnectFlags flags)
+{
+    virDevicePCIAddress addr;
+    if (virDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0)
+        return -1;
+
+    if (virDomainPCIAddressReserveSlot(addrs, &addr, flags) < 0)
+        return -1;
+
+    if (!addrs->dryRun) {
+        dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+        dev->addr.pci = addr;
+    }
+
+    addrs->lastaddr = addr;
+    addrs->lastFlags = flags;
+    return 0;
+}
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
index f5a5199..c59ef85 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -76,4 +76,74 @@ typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr;
 # define VIR_PCI_CONNECT_TYPES_MASK \
    (VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE)
 
+char *virDomainPCIAddressAsString(virDevicePCIAddressPtr addr)
+      ATTRIBUTE_NONNULL(1);
+
+virDomainPCIAddressSetPtr virDomainPCIAddressSetAlloc(unsigned int nbuses);
+
+void virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs);
+
+bool virDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
+                                        const char *addrStr,
+                                        virDomainPCIConnectFlags busFlags,
+                                        virDomainPCIConnectFlags devFlags,
+                                        bool reportError,
+                                        bool fromConfig)
+     ATTRIBUTE_NONNULL(1);
+
+bool virDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
+                                 virDevicePCIAddressPtr addr,
+                                 const char *addrStr,
+                                 virDomainPCIConnectFlags flags,
+                                 bool fromConfig)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+
+int virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
+                                   virDomainControllerModelPCI model)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+bool virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs,
+                                  virDevicePCIAddressPtr addr)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
+                               virDevicePCIAddressPtr addr,
+                               virDomainPCIConnectFlags flags)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
+                                   virDevicePCIAddressPtr addr,
+                                   virDomainPCIConnectFlags flags,
+                                   bool reserveEntireSlot,
+                                   bool fromConfig)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
+                                   virDevicePCIAddressPtr addr,
+                                   virDomainPCIConnectFlags flags)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
+                                  virDomainDeviceInfoPtr dev)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
+                                   virDevicePCIAddressPtr addr)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs,
+                                   virDevicePCIAddressPtr addr)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
+                                   virDevicePCIAddressPtr next_addr,
+                                   virDomainPCIConnectFlags flags)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
+                                       virDomainDeviceInfoPtr dev,
+                                       virDomainPCIConnectFlags flags)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 #endif /* __DOMAIN_ADDR_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b4dd338..0a5fb14 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -85,6 +85,23 @@ virDevicePCIAddressIsValid;
 virDevicePCIAddressParseXML;
 
 
+# conf/domain_addr.h
+virDomainPCIAddressAsString;
+virDomainPCIAddressBusSetModel;
+virDomainPCIAddressEnsureAddr;
+virDomainPCIAddressFlagsCompatible;
+virDomainPCIAddressGetNextSlot;
+virDomainPCIAddressReleaseSlot;
+virDomainPCIAddressReserveAddr;
+virDomainPCIAddressReserveNextSlot;
+virDomainPCIAddressReserveSlot;
+virDomainPCIAddressSetAlloc;
+virDomainPCIAddressSetFree;
+virDomainPCIAddressSetGrow;
+virDomainPCIAddressSlotInUse;
+virDomainPCIAddressValidate;
+
+
 # conf/domain_audit.h
 virDomainAuditCgroup;
 virDomainAuditCgroupMajor;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ebf17a8..aeaadbd 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1240,7 +1240,7 @@ void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs)
 static qemuDomainCCWAddressSetPtr
 qemuDomainCCWAddressSetCreate(void)
 {
-     qemuDomainCCWAddressSetPtr addrs = NULL;
+    qemuDomainCCWAddressSetPtr addrs = NULL;
 
     if (VIR_ALLOC(addrs) < 0)
         goto error;
@@ -1445,232 +1445,6 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
 }
 
 
-static bool
-qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
-                                    const char *addrStr,
-                                    virDomainPCIConnectFlags busFlags,
-                                    virDomainPCIConnectFlags devFlags,
-                                    bool reportError,
-                                    bool fromConfig)
-{
-    virErrorNumber errType = (fromConfig
-                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
-    virDomainPCIConnectFlags flagsMatchMask = VIR_PCI_CONNECT_TYPES_MASK;
-
-    if (fromConfig)
-       flagsMatchMask |= VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG;
-
-    /* If this bus doesn't allow the type of connection (PCI
-     * vs. PCIe) required by the device, or if the device requires
-     * hot-plug and this bus doesn't have it, return false.
-     */
-    if (!(devFlags & busFlags & flagsMatchMask)) {
-        if (reportError) {
-            if (devFlags & VIR_PCI_CONNECT_TYPE_PCI) {
-                virReportError(errType,
-                               _("PCI bus is not compatible with the device "
-                                 "at %s. Device requires a standard PCI slot, "
-                                 "which is not provided by bus %.4x:%.2x"),
-                               addrStr, addr->domain, addr->bus);
-            } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE) {
-                virReportError(errType,
-                               _("PCI bus is not compatible with the device "
-                                 "at %s. Device requires a PCI Express slot, "
-                                 "which is not provided by bus %.4x:%.2x"),
-                               addrStr, addr->domain, addr->bus);
-            } else {
-                /* this should never happen. If it does, there is a
-                 * bug in the code that sets the flag bits for devices.
-                 */
-                virReportError(errType,
-                           _("The device information for %s has no PCI "
-                             "connection types listed"), addrStr);
-            }
-        }
-        return false;
-    }
-    if ((devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) &&
-        !(busFlags & VIR_PCI_CONNECT_HOTPLUGGABLE)) {
-        if (reportError) {
-            virReportError(errType,
-                           _("PCI bus is not compatible with the device "
-                             "at %s. Device requires hot-plug capability, "
-                             "which is not provided by bus %.4x:%.2x"),
-                           addrStr, addr->domain, addr->bus);
-        }
-        return false;
-    }
-    return true;
-}
-
-
-/* Verify that the address is in bounds for the chosen bus, and
- * that the bus is of the correct type for the device (via
- * comparing the flags).
- */
-static bool
-qemuDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
-                             virDevicePCIAddressPtr addr,
-                             const char *addrStr,
-                             virDomainPCIConnectFlags flags,
-                             bool fromConfig)
-{
-    virDomainPCIAddressBusPtr bus;
-    virErrorNumber errType = (fromConfig
-                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
-
-    if (addrs->nbuses == 0) {
-        virReportError(errType, "%s", _("No PCI buses available"));
-        return false;
-    }
-    if (addr->domain != 0) {
-        virReportError(errType,
-                       _("Invalid PCI address %s. "
-                         "Only PCI domain 0 is available"),
-                       addrStr);
-        return false;
-    }
-    if (addr->bus >= addrs->nbuses) {
-        virReportError(errType,
-                       _("Invalid PCI address %s. "
-                         "Only PCI buses up to %zu are available"),
-                       addrStr, addrs->nbuses - 1);
-        return false;
-    }
-
-    bus = &addrs->buses[addr->bus];
-
-    /* assure that at least one of the requested connection types is
-     * provided by this bus
-     */
-    if (!qemuDomainPCIAddressFlagsCompatible(addr, addrStr, bus->flags,
-                                             flags, true, fromConfig))
-        return false;
-
-    /* some "buses" are really just a single port */
-    if (bus->minSlot && addr->slot < bus->minSlot) {
-        virReportError(errType,
-                       _("Invalid PCI address %s. slot must be >= %zu"),
-                       addrStr, bus->minSlot);
-        return false;
-    }
-    if (addr->slot > bus->maxSlot) {
-        virReportError(errType,
-                       _("Invalid PCI address %s. slot must be <= %zu"),
-                       addrStr, bus->maxSlot);
-        return false;
-    }
-    if (addr->function > VIR_PCI_ADDRESS_FUNCTION_LAST) {
-        virReportError(errType,
-                       _("Invalid PCI address %s. function must be <= %u"),
-                       addrStr, VIR_PCI_ADDRESS_FUNCTION_LAST);
-        return false;
-    }
-    return true;
-}
-
-
-static int
-qemuDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
-                                virDomainControllerModelPCI model)
-{
-    switch (model) {
-    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
-    case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
-        bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
-                      VIR_PCI_CONNECT_TYPE_PCI);
-        bus->minSlot = 1;
-        bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
-        break;
-    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
-        /* slots 1 - 31, no hotplug, PCIe only unless the address was
-         * specified in user config *and* the particular device being
-         * attached also allows it
-         */
-        bus->flags = (VIR_PCI_CONNECT_TYPE_PCIE |
-                      VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
-        bus->minSlot = 1;
-        bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
-        break;
-    case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
-        /* slots 1 - 31, standard PCI slots,
-         * but *not* hot-pluggable */
-        bus->flags = VIR_PCI_CONNECT_TYPE_PCI;
-        bus->minSlot = 1;
-        bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
-        break;
-    default:
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Invalid PCI controller model %d"), model);
-        return -1;
-    }
-
-    bus->model = model;
-    return 0;
-}
-
-
-/* Ensure addr fits in the address set, by expanding it if needed.
- * This will only grow if the flags say that we need a normal
- * hot-pluggable PCI slot. If we need a different type of slot, it
- * will fail.
- *
- * Return value:
- * -1 = OOM
- *  0 = no action performed
- * >0 = number of buses added
- */
-static int
-qemuDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
-                            virDevicePCIAddressPtr addr,
-                            virDomainPCIConnectFlags flags)
-{
-    int add;
-    size_t i;
-
-    add = addr->bus - addrs->nbuses + 1;
-    i = addrs->nbuses;
-    if (add <= 0)
-        return 0;
-
-    /* auto-grow only works when we're adding plain PCI devices */
-    if (!(flags & VIR_PCI_CONNECT_TYPE_PCI)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Cannot automatically add a new PCI bus for a "
-                         "device requiring a slot other than standard PCI."));
-        return -1;
-    }
-
-    if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, add) < 0)
-        return -1;
-
-    for (; i < addrs->nbuses; i++) {
-        /* Any time we auto-add a bus, we will want a multi-slot
-         * bus. Currently the only type of bus we will auto-add is a
-         * pci-bridge, which is hot-pluggable and provides standard
-         * PCI slots.
-         */
-        qemuDomainPCIAddressBusSetModel(&addrs->buses[i],
-                                        VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
-    }
-    return add;
-}
-
-
-static char *
-qemuDomainPCIAddressAsString(virDevicePCIAddressPtr addr)
-{
-    char *str;
-
-    ignore_value(virAsprintf(&str, "%.4x:%.2x:%.2x.%.1x",
-                             addr->domain,
-                             addr->bus,
-                             addr->slot,
-                             addr->function));
-    return str;
-}
-
-
 static int
 qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
                       virDomainDeviceDefPtr device,
@@ -1816,8 +1590,8 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
     entireSlot = (addr->function == 0 &&
                   addr->multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON);
 
-    if (qemuDomainPCIAddressReserveAddr(addrs, addr, flags,
-                                        entireSlot, true) < 0)
+    if (virDomainPCIAddressReserveAddr(addrs, addr, flags,
+                                       entireSlot, true) < 0)
         goto cleanup;
 
     ret = 0;
@@ -1872,7 +1646,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
             if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
                 goto cleanup;
             /* Reserve 1 extra slot for a (potential) bridge */
-            if (qemuDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0)
+            if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0)
                 goto cleanup;
 
             for (i = 1; i < addrs->nbuses; i++) {
@@ -1883,12 +1657,12 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
                          i, bus->model)) < 0)
                     goto cleanup;
                 /* If we added a new bridge, we will need one more address */
-                if (rv > 0 && qemuDomainPCIAddressReserveNextSlot(addrs, &info,
-                                                                  flags) < 0)
+                if (rv > 0 && virDomainPCIAddressReserveNextSlot(addrs, &info,
+                                                                 flags) < 0)
                         goto cleanup;
             }
             nbuses = addrs->nbuses;
-            qemuDomainPCIAddressSetFree(addrs);
+            virDomainPCIAddressSetFree(addrs);
             addrs = NULL;
 
         } else if (max_idx > 0) {
@@ -1911,7 +1685,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
         priv = obj->privateData;
         if (addrs) {
             /* if this is the live domain object, we persist the PCI addresses*/
-            qemuDomainPCIAddressSetFree(priv->pciaddrs);
+            virDomainPCIAddressSetFree(priv->pciaddrs);
             priv->persistentAddrs = 1;
             priv->pciaddrs = addrs;
             addrs = NULL;
@@ -1923,7 +1697,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
     ret = 0;
 
  cleanup:
-    qemuDomainPCIAddressSetFree(addrs);
+    virDomainPCIAddressSetFree(addrs);
 
     return ret;
 }
@@ -1958,11 +1732,8 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
     virDomainPCIAddressSetPtr addrs;
     size_t i;
 
-    if (VIR_ALLOC(addrs) < 0)
-        goto error;
-
-    if (VIR_ALLOC_N(addrs->buses, nbuses) < 0)
-        goto error;
+    if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL)
+        return NULL;
 
     addrs->nbuses = nbuses;
     addrs->dryRun = dryRun;
@@ -1975,11 +1746,11 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
      *
      */
     if (nbuses > 0)
-       qemuDomainPCIAddressBusSetModel(&addrs->buses[0],
-                                       VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT);
+       virDomainPCIAddressBusSetModel(&addrs->buses[0],
+                                      VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT);
     for (i = 1; i < nbuses; i++) {
-        qemuDomainPCIAddressBusSetModel(&addrs->buses[i],
-                                        VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
+        virDomainPCIAddressBusSetModel(&addrs->buses[i],
+                                       VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
     }
 
     for (i = 0; i < def->ncontrollers; i++) {
@@ -1995,8 +1766,8 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
             goto error;
         }
 
-        if (qemuDomainPCIAddressBusSetModel(&addrs->buses[idx],
-                                            def->controllers[i]->model) < 0)
+        if (virDomainPCIAddressBusSetModel(&addrs->buses[idx],
+                                           def->controllers[i]->model) < 0)
             goto error;
         }
 
@@ -2006,292 +1777,10 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
     return addrs;
 
  error:
-    qemuDomainPCIAddressSetFree(addrs);
+    virDomainPCIAddressSetFree(addrs);
     return NULL;
 }
 
-/*
- * Check if the PCI slot is used by another device.
- */
-static bool qemuDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs,
-                                          virDevicePCIAddressPtr addr)
-{
-    return !!addrs->buses[addr->bus].slots[addr->slot];
-}
-
-
-/*
- * Reserve a slot (or just one function) for a device. If
- * reserveEntireSlot is true, all functions for the slot are reserved,
- * otherwise only one. If fromConfig is true, the address being
- * requested came directly from the config and errors should be worded
- * appropriately. If fromConfig is false, the address was
- * automatically created by libvirt, so it is an internal error (not
- * XML).
- */
-int
-qemuDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
-                                virDevicePCIAddressPtr addr,
-                                virDomainPCIConnectFlags flags,
-                                bool reserveEntireSlot,
-                                bool fromConfig)
-{
-    int ret = -1;
-    char *addrStr = NULL;
-    virDomainPCIAddressBusPtr bus;
-    virErrorNumber errType = (fromConfig
-                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
-
-    if (!(addrStr = qemuDomainPCIAddressAsString(addr)))
-        goto cleanup;
-
-    /* Add an extra bus if necessary */
-    if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
-        goto cleanup;
-    /* Check that the requested bus exists, is the correct type, and we
-     * are asking for a valid slot
-     */
-    if (!qemuDomainPCIAddressValidate(addrs, addr, addrStr, flags, fromConfig))
-        goto cleanup;
-
-    bus = &addrs->buses[addr->bus];
-
-    if (reserveEntireSlot) {
-        if (bus->slots[addr->slot]) {
-            virReportError(errType,
-                           _("Attempted double use of PCI slot %s "
-                             "(may need \"multifunction='on'\" for "
-                             "device on function 0)"), addrStr);
-            goto cleanup;
-        }
-        bus->slots[addr->slot] = 0xFF; /* reserve all functions of slot */
-        VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr);
-    } else {
-        if (bus->slots[addr->slot] & (1 << addr->function)) {
-            if (addr->function == 0) {
-                virReportError(errType,
-                               _("Attempted double use of PCI Address %s"),
-                               addrStr);
-            } else {
-                virReportError(errType,
-                               _("Attempted double use of PCI Address %s "
-                                 "(may need \"multifunction='on'\" "
-                                 "for device on function 0)"), addrStr);
-            }
-            goto cleanup;
-        }
-        bus->slots[addr->slot] |= (1 << addr->function);
-        VIR_DEBUG("Reserving PCI address %s", addrStr);
-    }
-
-    ret = 0;
- cleanup:
-    VIR_FREE(addrStr);
-    return ret;
-}
-
-
-int
-qemuDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
-                                virDevicePCIAddressPtr addr,
-                                virDomainPCIConnectFlags flags)
-{
-    return qemuDomainPCIAddressReserveAddr(addrs, addr, flags, true, false);
-}
-
-int qemuDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
-                                   virDomainDeviceInfoPtr dev)
-{
-    int ret = -1;
-    char *addrStr = NULL;
-    /* Flags should be set according to the particular device,
-     * but only the caller knows the type of device. Currently this
-     * function is only used for hot-plug, though, and hot-plug is
-     * only supported for standard PCI devices, so we can safely use
-     * the setting below */
-    virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
-                                      VIR_PCI_CONNECT_TYPE_PCI);
-
-    if (!(addrStr = qemuDomainPCIAddressAsString(&dev->addr.pci)))
-        goto cleanup;
-
-    if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        /* We do not support hotplug multi-function PCI device now, so we should
-         * reserve the whole slot. The function of the PCI device must be 0.
-         */
-        if (dev->addr.pci.function != 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Only PCI device addresses with function=0"
-                             " are supported"));
-            goto cleanup;
-        }
-
-        if (!qemuDomainPCIAddressValidate(addrs, &dev->addr.pci,
-                                          addrStr, flags, true))
-            goto cleanup;
-
-        ret = qemuDomainPCIAddressReserveSlot(addrs, &dev->addr.pci, flags);
-    } else {
-        ret = qemuDomainPCIAddressReserveNextSlot(addrs, dev, flags);
-    }
-
- cleanup:
-    VIR_FREE(addrStr);
-    return ret;
-}
-
-
-int qemuDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
-                                    virDevicePCIAddressPtr addr)
-{
-    addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function);
-    return 0;
-}
-
-static int
-qemuDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs,
-                                virDevicePCIAddressPtr addr)
-{
-    /* permit any kind of connection type in validation, since we
-     * already had it, and are giving it back.
-     */
-    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPES_MASK;
-    int ret = -1;
-    char *addrStr = NULL;
-
-    if (!(addrStr = qemuDomainPCIAddressAsString(addr)))
-        goto cleanup;
-
-    if (!qemuDomainPCIAddressValidate(addrs, addr, addrStr, flags, false))
-        goto cleanup;
-
-    addrs->buses[addr->bus].slots[addr->slot] = 0;
-    ret = 0;
- cleanup:
-    VIR_FREE(addrStr);
-    return ret;
-}
-
-void qemuDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs)
-{
-    if (!addrs)
-        return;
-
-    VIR_FREE(addrs->buses);
-    VIR_FREE(addrs);
-}
-
-
-static int
-qemuDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
-                                virDevicePCIAddressPtr next_addr,
-                                virDomainPCIConnectFlags flags)
-{
-    /* default to starting the search for a free slot from
-     * 0000:00:00.0
-     */
-    virDevicePCIAddress a = { 0, 0, 0, 0, false };
-    char *addrStr = NULL;
-
-    /* except if this search is for the exact same type of device as
-     * last time, continue the search from the previous match
-     */
-    if (flags == addrs->lastFlags)
-        a = addrs->lastaddr;
-
-    if (addrs->nbuses == 0) {
-        virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
-        goto error;
-    }
-
-    /* Start the search at the last used bus and slot */
-    for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
-        if (!(addrStr = qemuDomainPCIAddressAsString(&a)))
-            goto error;
-        if (!qemuDomainPCIAddressFlagsCompatible(&a, addrStr,
-                                                 addrs->buses[a.bus].flags,
-                                                 flags, false, false)) {
-            VIR_FREE(addrStr);
-            VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
-                      a.domain, a.bus);
-            continue;
-        }
-        for (; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
-            if (!qemuDomainPCIAddressSlotInUse(addrs, &a))
-                goto success;
-
-            VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
-                      a.domain, a.bus, a.slot);
-        }
-        a.slot = 1;
-        VIR_FREE(addrStr);
-    }
-
-    /* There were no free slots after the last used one */
-    if (addrs->dryRun) {
-        /* a is already set to the first new bus and slot 1 */
-        if (qemuDomainPCIAddressSetGrow(addrs, &a, flags) < 0)
-            goto error;
-        goto success;
-    } else if (flags == addrs->lastFlags) {
-        /* Check the buses from 0 up to the last used one */
-        for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
-            addrStr = NULL;
-            if (!(addrStr = qemuDomainPCIAddressAsString(&a)))
-                goto error;
-            if (!qemuDomainPCIAddressFlagsCompatible(&a, addrStr,
-                                                     addrs->buses[a.bus].flags,
-                                                     flags, false, false)) {
-                VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
-                          a.domain, a.bus);
-                continue;
-            }
-            for (a.slot = 1; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
-                if (!qemuDomainPCIAddressSlotInUse(addrs, &a))
-                    goto success;
-
-                VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
-                          a.domain, a.bus, a.slot);
-            }
-        }
-    }
-
-    virReportError(VIR_ERR_INTERNAL_ERROR,
-                   "%s", _("No more available PCI slots"));
- error:
-    VIR_FREE(addrStr);
-    return -1;
-
- success:
-    VIR_DEBUG("Found free PCI slot %.4x:%.2x:%.2x",
-              a.domain, a.bus, a.slot);
-    *next_addr = a;
-    VIR_FREE(addrStr);
-    return 0;
-}
-
-int
-qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
-                                    virDomainDeviceInfoPtr dev,
-                                    virDomainPCIConnectFlags flags)
-{
-    virDevicePCIAddress addr;
-    if (qemuDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0)
-        return -1;
-
-    if (qemuDomainPCIAddressReserveSlot(addrs, &addr, flags) < 0)
-        return -1;
-
-    if (!addrs->dryRun) {
-        dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
-        dev->addr.pci = addr;
-    }
-
-    addrs->lastaddr = addr;
-    addrs->lastFlags = flags;
-    return 0;
-}
-
 
 void
 qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
@@ -2311,8 +1800,8 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
                  NULLSTR(devstr));
     else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
              virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
-             qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
-                                             &info->addr.pci) < 0)
+             virDomainPCIAddressReleaseSlot(priv->pciaddrs,
+                                            &info->addr.pci) < 0)
         VIR_WARN("Unable to release PCI address on %s",
                  NULLSTR(devstr));
 }
@@ -2388,7 +1877,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
     if (addrs->nbuses) {
         memset(&tmp_addr, 0, sizeof(tmp_addr));
         tmp_addr.slot = 1;
-        if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
+        if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
             goto cleanup;
     }
 
@@ -2404,17 +1893,17 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
             memset(&tmp_addr, 0, sizeof(tmp_addr));
             tmp_addr.slot = 2;
 
-            if (!(addrStr = qemuDomainPCIAddressAsString(&tmp_addr)))
+            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
                 goto cleanup;
-            if (!qemuDomainPCIAddressValidate(addrs, &tmp_addr,
-                                              addrStr, flags, false))
+            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
+                                             addrStr, flags, false))
                 goto cleanup;
 
-            if (qemuDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
                 if (qemuDeviceVideoUsable) {
-                    if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                            &primaryVideo->info,
-                                                            flags) < 0)
+                    if (virDomainPCIAddressReserveNextSlot(addrs,
+                                                           &primaryVideo->info,
+                                                           flags) < 0)
                         goto cleanup;
                 } else {
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -2423,7 +1912,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
                     goto cleanup;
                 }
             } else {
-                if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
+                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
                     goto cleanup;
                 primaryVideo->info.addr.pci = tmp_addr;
                 primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
@@ -2444,12 +1933,12 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
         memset(&tmp_addr, 0, sizeof(tmp_addr));
         tmp_addr.slot = 2;
 
-        if (qemuDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
             VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video"
                       " device will not be possible without manual"
                       " intervention");
             virResetLastError();
-        } else if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
+        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
             goto cleanup;
         }
     }
@@ -2527,9 +2016,9 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
                 */
                 memset(&tmp_addr, 0, sizeof(tmp_addr));
                 tmp_addr.slot = 0x1E;
-                if (!qemuDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
-                    if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr,
-                                                        flags, true, false) < 0)
+                if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+                    if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
+                                                       flags, true, false) < 0)
                         goto cleanup;
                     def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                     def->controllers[i]->info.addr.pci.domain = 0;
@@ -2552,13 +2041,13 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
         tmp_addr.slot = 0x1F;
         tmp_addr.function = 0;
         tmp_addr.multi = 1;
-        if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
-                                            false, false) < 0)
+        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
+                                           false, false) < 0)
            goto cleanup;
         tmp_addr.function = 3;
         tmp_addr.multi = 0;
-        if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
-                                            false, false) < 0)
+        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
+                                           false, false) < 0)
            goto cleanup;
     }
 
@@ -2574,17 +2063,17 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
             memset(&tmp_addr, 0, sizeof(tmp_addr));
             tmp_addr.slot = 1;
 
-            if (!(addrStr = qemuDomainPCIAddressAsString(&tmp_addr)))
+            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
                 goto cleanup;
-            if (!qemuDomainPCIAddressValidate(addrs, &tmp_addr,
-                                              addrStr, flags, false))
+            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
+                                             addrStr, flags, false))
                 goto cleanup;
 
-            if (qemuDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
                 if (qemuDeviceVideoUsable) {
-                    if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                            &primaryVideo->info,
-                                                            flags) < 0)
+                    if (virDomainPCIAddressReserveNextSlot(addrs,
+                                                           &primaryVideo->info,
+                                                           flags) < 0)
                         goto cleanup;
                 } else {
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -2593,7 +2082,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
                     goto cleanup;
                 }
             } else {
-                if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
+                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
                     goto cleanup;
                 primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                 primaryVideo->info.addr.pci = tmp_addr;
@@ -2614,12 +2103,12 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
         memset(&tmp_addr, 0, sizeof(tmp_addr));
         tmp_addr.slot = 1;
 
-        if (qemuDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
             VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video"
                       " device will not be possible without manual"
                       " intervention");
             virResetLastError();
-        } else if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
+        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
             goto cleanup;
         }
     }
@@ -2712,9 +2201,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
                 flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
                 break;
             }
-            if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                    &def->controllers[i]->info,
-                                                    flags) < 0)
+            if (virDomainPCIAddressReserveNextSlot(addrs,
+                                                   &def->controllers[i]->info,
+                                                   flags) < 0)
                 goto error;
         }
     }
@@ -2727,8 +2216,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
 
         /* Only support VirtIO-9p-pci so far. If that changes,
          * we might need to skip devices here */
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2742,8 +2231,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
             (def->nets[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)) {
             continue;
         }
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2756,8 +2245,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
             def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_PCSPK)
             continue;
 
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2819,7 +2308,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
             if (addr.slot == 0) {
                 /* This is the first part of the controller, so need
                  * to find a free slot & then reserve a function */
-                if (qemuDomainPCIAddressGetNextSlot(addrs, &tmp_addr, flags) < 0)
+                if (virDomainPCIAddressGetNextSlot(addrs, &tmp_addr, flags) < 0)
                     goto error;
 
                 addr.bus = tmp_addr.bus;
@@ -2830,16 +2319,16 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
                 addrs->lastaddr.multi = 0;
             }
             /* Finally we can reserve the slot+function */
-            if (qemuDomainPCIAddressReserveAddr(addrs, &addr, flags,
-                                                false, false) < 0)
+            if (virDomainPCIAddressReserveAddr(addrs, &addr, flags,
+                                               false, false) < 0)
                 goto error;
 
             def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
             def->controllers[i]->info.addr.pci = addr;
         } else {
-            if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                    &def->controllers[i]->info,
-                                                    flags) < 0)
+            if (virDomainPCIAddressReserveNextSlot(addrs,
+                                                   &def->controllers[i]->info,
+                                                   flags) < 0)
                 goto error;
         }
     }
@@ -2864,8 +2353,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
             goto error;
         }
 
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->disks[i]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->disks[i]->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2877,9 +2366,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
             def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
             continue;
 
-        if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                def->hostdevs[i]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs,
+                                               def->hostdevs[i]->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2887,9 +2376,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
     if (def->memballoon &&
         def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
         def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-        if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                &def->memballoon->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs,
+                                               &def->memballoon->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2897,8 +2386,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
     if (def->rng &&
         def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
         def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-        if (qemuDomainPCIAddressReserveNextSlot(addrs,
-                                                &def->rng->info, flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs,
+                                               &def->rng->info, flags) < 0)
             goto error;
     }
 
@@ -2906,8 +2395,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
     if (def->watchdog &&
         def->watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_IB700 &&
         def->watchdog->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->watchdog->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->watchdog->info,
+                                               flags) < 0)
             goto error;
     }
 
@@ -2915,8 +2404,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
      * assigned address. */
     if (def->nvideos > 0 &&
         def->videos[0]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->videos[0]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[0]->info,
+                                               flags) < 0)
             goto error;
     }
     /* Further non-primary video cards which have to be qxl type */
@@ -2928,8 +2417,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
         }
         if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
             continue;
-        if (qemuDomainPCIAddressReserveNextSlot(addrs, &def->videos[i]->info,
-                                                flags) < 0)
+        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[i]->info,
+                                               flags) < 0)
             goto error;
     }
     for (i = 0; i < def->ninputs; i++) {
@@ -2976,7 +2465,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
         const char *contAlias = NULL;
         size_t i;
 
-        if (!(devStr = qemuDomainPCIAddressAsString(&info->addr.pci)))
+        if (!(devStr = virDomainPCIAddressAsString(&info->addr.pci)))
             goto cleanup;
         for (i = 0; i < domainDef->ncontrollers; i++) {
             virDomainControllerDefPtr cont = domainDef->controllers[i];
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 29da1ca..afbd6ff 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -242,23 +242,7 @@ int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
 virDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
                                                         unsigned int nbuses,
                                                         bool dryRun);
-int qemuDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
-                                    virDevicePCIAddressPtr addr,
-                                    virDomainPCIConnectFlags flags);
-int qemuDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
-                                    virDevicePCIAddressPtr addr,
-                                    virDomainPCIConnectFlags flags,
-                                    bool reserveEntireSlot,
-                                    bool fromConfig);
-int qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
-                                        virDomainDeviceInfoPtr dev,
-                                        virDomainPCIConnectFlags flags);
-int qemuDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
-                                   virDomainDeviceInfoPtr dev);
-int qemuDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
-                                    virDevicePCIAddressPtr addr);
-
-void qemuDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs);
+
 int  qemuAssignDevicePCISlots(virDomainDefPtr def,
                               virQEMUCapsPtr qemuCaps,
                               virDomainPCIAddressSetPtr addrs);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 34cc736..8415f1a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -34,6 +34,7 @@
 #include "cpu/cpu.h"
 #include "viruuid.h"
 #include "virfile.h"
+#include "domain_addr.h"
 #include "domain_event.h"
 #include "virtime.h"
 #include "virstoragefile.h"
@@ -245,7 +246,7 @@ qemuDomainObjPrivateFree(void *data)
     virObjectUnref(priv->qemuCaps);
 
     virCgroupFree(&priv->cgroup);
-    qemuDomainPCIAddressSetFree(priv->pciaddrs);
+    virDomainPCIAddressSetFree(priv->pciaddrs);
     qemuDomainCCWAddressSetFree(priv->ccwaddrs);
     virDomainChrSourceDefFree(priv->monConfig);
     qemuDomainObjFreeJob(priv);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7c8830e..125a2db 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -284,7 +284,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
                 goto error;
         } else if (!disk->info.type ||
                     disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-            if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
+            if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
                 goto error;
         }
         releaseaddr = true;
@@ -386,7 +386,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
 
         if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
             controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-            if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
+            if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
                 goto cleanup;
         } else if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
             if (qemuDomainCCWAddressAssign(&controller->info, priv->ccwaddrs,
@@ -940,7 +940,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                         _("virtio-s390 net device cannot be hotplugged."));
     else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
-             qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
+             virDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
              goto cleanup;
 
     releaseaddr = true;
@@ -1230,7 +1230,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
             goto error;
-        if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
+        if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
             goto error;
         releaseaddr = true;
         if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 592e3b7..606478e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4390,7 +4390,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     virDomainDefClearDeviceAliases(vm->def);
     if (!priv->persistentAddrs) {
         virDomainDefClearPCIAddresses(vm->def);
-        qemuDomainPCIAddressSetFree(priv->pciaddrs);
+        virDomainPCIAddressSetFree(priv->pciaddrs);
         priv->pciaddrs = NULL;
         virDomainDefClearCCWAddresses(vm->def);
         qemuDomainCCWAddressSetFree(priv->ccwaddrs);
-- 
1.9.0




More information about the libvir-list mailing list