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
devices.
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(a)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 e7a9e6adda..7d60d277e8 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;
--
2.34.1