From 64645b78a4ecb728c37ae6d769c550bf3c74819d Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Mon, 29 May 2017 17:18:35 +0200 Subject: [PATCH] qemu: Use PHBs when extending the guest PCI topology When looking for slots suitable for a PCI device, libvirt might need to add an extra PCI controller: for pSeries guests, we want that extra controller to be a PHB (pci-root) rather than a PCI bridge. Signed-off-by: Andrea Bolognani Reviewed-by: Laine Stump --- src/conf/domain_addr.c | 56 ++++++++------- src/conf/domain_addr.h | 2 + src/qemu/qemu_domain_address.c | 4 ++ .../qemuxml2argv-pseries-hostdevs-2.args | 8 +-- .../qemuxml2argv-pseries-hostdevs-3.args | 8 +-- .../qemuxml2argv-pseries-many-buses-1.args | 4 +- .../qemuxml2argv-pseries-many-devices.args | 66 ++++++++--------- tests/qemuxml2argvtest.c | 4 -- .../qemuxml2xmlout-pseries-hostdevs-2.xml | 9 ++- .../qemuxml2xmlout-pseries-hostdevs-3.xml | 16 ++--- .../qemuxml2xmlout-pseries-many-buses-1.xml | 7 +- .../qemuxml2xmlout-pseries-many-devices.xml | 71 +++++++++---------- tests/qemuxml2xmltest.c | 4 -- 13 files changed, 129 insertions(+), 130 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index fd3f342097..362e9966d0 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -397,33 +397,39 @@ virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs, */ if (flags & VIR_PCI_CONNECT_TYPE_PCI_DEVICE) { - model = VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE; + if (addrs->multipleRootsSupported) { + /* Use a pci-root controller to expand the guest's PCI + * topology if it supports having more than one */ + model = VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT; + } else { + model = VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE; - /* if there aren't yet any buses that will accept a - * pci-bridge, and the caller is asking for one, we'll need to - * add a dmi-to-pci-bridge first. - */ - needDMIToPCIBridge = true; - for (i = 0; i < addrs->nbuses; i++) { - if (addrs->buses[i].flags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) { - needDMIToPCIBridge = false; - break; - } - } - if (needDMIToPCIBridge && add == 1) { - /* We need to add a single pci-bridge to provide the bus - * our legacy PCI device will be plugged into; however, we - * have also determined that there isn't yet any proper - * place to connect that pci-bridge we're about to add (on - * a system with pcie-root, that "proper place" would be a - * dmi-to-pci-bridge". So, to give the pci-bridge a place - * to connect, we increase the count of buses to add, - * while also incrementing the bus number in the address - * for the device (since the pci-bridge will now be at an - * index 1 higher than the caller had anticipated). + /* if there aren't yet any buses that will accept a + * pci-bridge, and the caller is asking for one, we'll need to + * add a dmi-to-pci-bridge first. */ - add++; - addr->bus++; + needDMIToPCIBridge = true; + for (i = 0; i < addrs->nbuses; i++) { + if (addrs->buses[i].flags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) { + needDMIToPCIBridge = false; + break; + } + } + if (needDMIToPCIBridge && add == 1) { + /* We need to add a single pci-bridge to provide the bus + * our legacy PCI device will be plugged into; however, we + * have also determined that there isn't yet any proper + * place to connect that pci-bridge we're about to add (on + * a system with pcie-root, that "proper place" would be a + * dmi-to-pci-bridge". So, to give the pci-bridge a place + * to connect, we increase the count of buses to add, + * while also incrementing the bus number in the address + * for the device (since the pci-bridge will now be at an + * index 1 higher than the caller had anticipated). + */ + add++; + addr->bus++; + } } } else if (flags & VIR_PCI_CONNECT_TYPE_PCI_BRIDGE && addrs->buses[0].model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) { diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 7b2c4d21f0..c53dceb1e8 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -108,6 +108,8 @@ struct _virDomainPCIAddressSet { size_t nbuses; bool dryRun; /* on a dry run, new buses are auto-added and addresses aren't saved in device infos */ + /* If true, the guest can have multiple pci-root controllers */ + bool multipleRootsSupported; }; typedef struct _virDomainPCIAddressSet virDomainPCIAddressSet; typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 0fe0d188af..44d0a5b1af 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1061,6 +1061,10 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def, addrs->dryRun = dryRun; + /* pSeries domains support multiple pci-root controllers */ + if (qemuDomainIsPSeries(def)) + addrs->multipleRootsSupported = true; + for (i = 0; i < def->ncontrollers; i++) { virDomainControllerDefPtr cont = def->controllers[i]; size_t idx = cont->idx; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-2.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-2.args index c43e15d456..83d4306036 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-2.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-2.args @@ -18,7 +18,7 @@ QEMU_AUDIO_DRV=none \ server,nowait \ -mon chardev=charmonitor,id=monitor,mode=readline \ -boot c \ --device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x1 \ --device virtio-scsi-pci,id=scsi0,bus=pci.1,addr=0x1 \ --device vfio-pci,host=0001:01:00.0,id=hostdev0,bus=pci.1,addr=0x2 \ --device vfio-pci,host=0005:90:01.0,id=hostdev1,bus=pci.0,addr=0x2 +-device spapr-pci-host-bridge,index=1,id=pci.1 \ +-device virtio-scsi-pci,id=scsi0,bus=pci.1.0,addr=0x1 \ +-device vfio-pci,host=0001:01:00.0,id=hostdev0,bus=pci.1.0,addr=0x2 \ +-device vfio-pci,host=0005:90:01.0,id=hostdev1,bus=pci.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-3.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-3.args index 99df2e71c9..eda6cc73ac 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-3.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-hostdevs-3.args @@ -18,7 +18,7 @@ QEMU_AUDIO_DRV=none \ server,nowait \ -mon chardev=charmonitor,id=monitor,mode=readline \ -boot c \ --device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x1 \ --device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.0,addr=0x2 \ --device vfio-pci,host=0001:01:00.0,id=hostdev0,bus=pci.2,addr=0x1 \ --device vfio-pci,host=0001:01:00.1,id=hostdev1,bus=pci.0,addr=0x3 +-device spapr-pci-host-bridge,index=1,id=pci.1 \ +-device spapr-pci-host-bridge,index=2,id=pci.2 \ +-device vfio-pci,host=0001:01:00.0,id=hostdev0,bus=pci.2.0,addr=0x1 \ +-device vfio-pci,host=0001:01:00.1,id=hostdev1,bus=pci.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-buses-1.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-buses-1.args index bf78fc19a4..eb5ccbd3a4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-buses-1.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-buses-1.args @@ -18,5 +18,5 @@ QEMU_AUDIO_DRV=none \ server,nowait \ -mon chardev=charmonitor,id=monitor,mode=readline \ -boot c \ --device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x1 \ --device virtio-scsi-pci,id=scsi0,bus=pci.1,addr=0x1 +-device spapr-pci-host-bridge,index=1,id=pci.1 \ +-device virtio-scsi-pci,id=scsi0,bus=pci.1.0,addr=0x1 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-devices.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-devices.args index 1db4533bf0..f20bc52f7c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-devices.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-many-devices.args @@ -18,36 +18,36 @@ QEMU_AUDIO_DRV=none \ server,nowait \ -mon chardev=charmonitor,id=monitor,mode=readline \ -boot c \ --device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x1 \ --device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x2 \ --device virtio-scsi-pci,id=scsi1,bus=pci.0,addr=0x3 \ --device virtio-scsi-pci,id=scsi2,bus=pci.0,addr=0x4 \ --device virtio-scsi-pci,id=scsi3,bus=pci.0,addr=0x5 \ --device virtio-scsi-pci,id=scsi4,bus=pci.0,addr=0x6 \ --device virtio-scsi-pci,id=scsi5,bus=pci.0,addr=0x7 \ --device virtio-scsi-pci,id=scsi6,bus=pci.0,addr=0x8 \ --device virtio-scsi-pci,id=scsi7,bus=pci.0,addr=0x9 \ --device virtio-scsi-pci,id=scsi8,bus=pci.0,addr=0xa \ --device virtio-scsi-pci,id=scsi9,bus=pci.0,addr=0xb \ --device virtio-scsi-pci,id=scsi10,bus=pci.0,addr=0xc \ --device virtio-scsi-pci,id=scsi11,bus=pci.0,addr=0xd \ --device virtio-scsi-pci,id=scsi12,bus=pci.0,addr=0xe \ --device virtio-scsi-pci,id=scsi13,bus=pci.0,addr=0xf \ --device virtio-scsi-pci,id=scsi14,bus=pci.0,addr=0x10 \ --device virtio-scsi-pci,id=scsi15,bus=pci.0,addr=0x11 \ --device virtio-scsi-pci,id=scsi16,bus=pci.0,addr=0x12 \ --device virtio-scsi-pci,id=scsi17,bus=pci.0,addr=0x13 \ --device virtio-scsi-pci,id=scsi18,bus=pci.0,addr=0x14 \ --device virtio-scsi-pci,id=scsi19,bus=pci.0,addr=0x15 \ --device virtio-scsi-pci,id=scsi20,bus=pci.0,addr=0x16 \ --device virtio-scsi-pci,id=scsi21,bus=pci.0,addr=0x17 \ --device virtio-scsi-pci,id=scsi22,bus=pci.0,addr=0x18 \ --device virtio-scsi-pci,id=scsi23,bus=pci.0,addr=0x19 \ --device virtio-scsi-pci,id=scsi24,bus=pci.0,addr=0x1a \ --device virtio-scsi-pci,id=scsi25,bus=pci.0,addr=0x1b \ --device virtio-scsi-pci,id=scsi26,bus=pci.0,addr=0x1c \ --device virtio-scsi-pci,id=scsi27,bus=pci.0,addr=0x1d \ --device virtio-scsi-pci,id=scsi28,bus=pci.0,addr=0x1e \ --device virtio-scsi-pci,id=scsi29,bus=pci.0,addr=0x1f \ --device virtio-scsi-pci,id=scsi30,bus=pci.1,addr=0x1 \ --device virtio-scsi-pci,id=scsi31,bus=pci.1,addr=0x2 +-device spapr-pci-host-bridge,index=1,id=pci.1 \ +-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x1 \ +-device virtio-scsi-pci,id=scsi1,bus=pci.0,addr=0x2 \ +-device virtio-scsi-pci,id=scsi2,bus=pci.0,addr=0x3 \ +-device virtio-scsi-pci,id=scsi3,bus=pci.0,addr=0x4 \ +-device virtio-scsi-pci,id=scsi4,bus=pci.0,addr=0x5 \ +-device virtio-scsi-pci,id=scsi5,bus=pci.0,addr=0x6 \ +-device virtio-scsi-pci,id=scsi6,bus=pci.0,addr=0x7 \ +-device virtio-scsi-pci,id=scsi7,bus=pci.0,addr=0x8 \ +-device virtio-scsi-pci,id=scsi8,bus=pci.0,addr=0x9 \ +-device virtio-scsi-pci,id=scsi9,bus=pci.0,addr=0xa \ +-device virtio-scsi-pci,id=scsi10,bus=pci.0,addr=0xb \ +-device virtio-scsi-pci,id=scsi11,bus=pci.0,addr=0xc \ +-device virtio-scsi-pci,id=scsi12,bus=pci.0,addr=0xd \ +-device virtio-scsi-pci,id=scsi13,bus=pci.0,addr=0xe \ +-device virtio-scsi-pci,id=scsi14,bus=pci.0,addr=0xf \ +-device virtio-scsi-pci,id=scsi15,bus=pci.0,addr=0x10 \ +-device virtio-scsi-pci,id=scsi16,bus=pci.0,addr=0x11 \ +-device virtio-scsi-pci,id=scsi17,bus=pci.0,addr=0x12 \ +-device virtio-scsi-pci,id=scsi18,bus=pci.0,addr=0x13 \ +-device virtio-scsi-pci,id=scsi19,bus=pci.0,addr=0x14 \ +-device virtio-scsi-pci,id=scsi20,bus=pci.0,addr=0x15 \ +-device virtio-scsi-pci,id=scsi21,bus=pci.0,addr=0x16 \ +-device virtio-scsi-pci,id=scsi22,bus=pci.0,addr=0x17 \ +-device virtio-scsi-pci,id=scsi23,bus=pci.0,addr=0x18 \ +-device virtio-scsi-pci,id=scsi24,bus=pci.0,addr=0x19 \ +-device virtio-scsi-pci,id=scsi25,bus=pci.0,addr=0x1a \ +-device virtio-scsi-pci,id=scsi26,bus=pci.0,addr=0x1b \ +-device virtio-scsi-pci,id=scsi27,bus=pci.0,addr=0x1c \ +-device virtio-scsi-pci,id=scsi28,bus=pci.0,addr=0x1d \ +-device virtio-scsi-pci,id=scsi29,bus=pci.0,addr=0x1e \ +-device virtio-scsi-pci,id=scsi30,bus=pci.0,addr=0x1f \ +-device virtio-scsi-pci,id=scsi31,bus=pci.1.0,addr=0x1 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 35c06ef247..b95ea46be0 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1757,12 +1757,10 @@ mymain(void) DO_TEST("pseries-many-devices", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI); DO_TEST("pseries-many-buses-1", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI); DO_TEST("pseries-many-buses-2", QEMU_CAPS_NODEFCONFIG, @@ -1778,14 +1776,12 @@ mymain(void) QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_HOST_PCI_MULTIDOMAIN, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("pseries-hostdevs-3", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_HOST_PCI_MULTIDOMAIN, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VFIO_PCI); diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-2.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-2.xml index 62bead5032..17ff4c8537 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-2.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-2.xml @@ -22,10 +22,9 @@ - - - -
+ + + @@ -39,7 +38,7 @@
-
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-3.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-3.xml index 77c09094ff..58023ecd72 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-3.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-hostdevs-3.xml @@ -19,15 +19,13 @@ - - - -
+ + + - - - -
+ + + @@ -41,7 +39,7 @@
-
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-buses-1.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-buses-1.xml index 9044936635..eb7bb80541 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-buses-1.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-buses-1.xml @@ -22,10 +22,9 @@ - - - -
+ + + diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-devices.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-devices.xml index b596fe6891..ff7a08fec1 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-devices.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pseries-many-devices.xml @@ -15,110 +15,109 @@ /usr/bin/qemu-system-ppc64 -
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
- - - -
+ + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index a948a61d8e..5e4b1d17f6 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -676,12 +676,10 @@ mymain(void) DO_TEST("pseries-many-devices", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI); DO_TEST("pseries-many-buses-1", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI); DO_TEST("pseries-many-buses-2", QEMU_CAPS_NODEFCONFIG, @@ -697,14 +695,12 @@ mymain(void) QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_HOST_PCI_MULTIDOMAIN, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST("pseries-hostdevs-3", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_HOST_PCI_MULTIDOMAIN, - QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VFIO_PCI);