[PATCH 22/33] qemu_domain_address.c: change pnv-phb3 minimal downstream slot

Daniel Henrique Barboza danielhb413 at gmail.com
Thu Jan 20 13:52:25 UTC 2022

The PowerNV PHB3 bus has minimal slot zero. In fact, at this moment, the
root complex accepts only a single device, at slot 0x0, due to firmware
limitations. The single device restriction is subject to change in
upstream QEMU and it's not worth adding this limitation to Libvirt.

However, the minimal slot presents a problem. When setting a
pnv-phb3-root-port address with slot=0x0, Libvirt changes it to 0x1.
This happens because the pnv-phb3 controller is a PCIE_ROOT model, and
this model is being set with 'bus->minSlot=1' in domain_addr.c,
virDomainPCIAddressBusSetModel(). This means that the root-port is
launched with 'addr=0x1' in the QEMU command line and it's not usable by
the domain.

It is not worth to create a new controller model, replicating all the
already existing logic for PCIE_ROOT controllers, just to have a similar
PCIE_ROOT bus with minSlots=0. Changing the existing PCIE_ROOT min slot to 0
doesn't make sense either - we would change existing behavior of existing

This patch works around this situation by adding a verification in
qemuDomainPCIAddressSetCreate() to change the minBus values of the
pnv-phb3 devices right before virDomainDeviceInfoIterate(). This is
enough to allow for a root port to be added in slot 0 of a pnv-phb3
bus while not being intrusive with existing devices.

Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
 src/qemu/qemu_domain_address.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 7ffdfa6478..5d65049c34 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1628,6 +1628,17 @@ qemuDomainCollectPCIAddressExtension(virDomainDef *def G_GNUC_UNUSED,
     return virDomainPCIAddressExtensionReserveAddr(addrs, addr);
+static void
+qemuDomainTunePowerNVPhbBuses(virDomainPCIAddressSet *addrs)
+    size_t i;
+    for (i = 0; i < addrs->nbuses; i++) {
+        if (addrs->buses[i].model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)
+            addrs->buses[i].minSlot = 0;
+    }
 static virDomainPCIAddressSet *
 qemuDomainPCIAddressSetCreate(virDomainDef *def,
                               virQEMUCaps *qemuCaps,
@@ -1720,6 +1731,9 @@ qemuDomainPCIAddressSetCreate(virDomainDef *def,
                   virDomainControllerModelPCITypeToString(defaultModel), i);
+    if (qemuDomainIsPowerNV(def))
+        qemuDomainTunePowerNVPhbBuses(addrs);
     if (virDomainDeviceInfoIterate(def, qemuDomainCollectPCIAddress, addrs) < 0)
         goto error;

More information about the libvir-list mailing list