generally, root pci-bridge refers to bus 0, 'id=pci-bridge0',
then the following devices sitting on this bus will
set 'bus=pci-bridge0', subordinate bus has 'id=pci-birdge1',
and devices sitting on it will set 'bus=pci-bridge1',
and so forth.
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_command.c | 52 +++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 04a9512..e98b6c9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1762,13 +1762,15 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
virDomainDeviceInfoPtr info,
qemuCapsPtr caps)
{
- if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
+ info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCIBRIDGE) {
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) {
+ if (info->addr.pci.bus != 0 &&
+ info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCIBRIDGE) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Only PCI device addresses with bus=0 are
supported"));
return -1;
@@ -1801,10 +1803,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
* When QEMU grows support for > 1 PCI domain, then pci.0 change
* to pciNN.0 where NN is the domain number
*/
- if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS))
+ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCIBRIDGE) {
+ virBufferAsprintf(buf, ",bus=pci-bridge%d",
info->addr.pci.bus);
+ } else if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS)) {
virBufferAsprintf(buf, ",bus=pci.0");
- else
+ } else {
virBufferAsprintf(buf, ",bus=pci");
+ }
if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON)
virBufferAddLit(buf, ",multifunction=on");
else if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_OFF)
@@ -3455,6 +3460,32 @@ error:
return NULL;
}
+char *
+qemuBuildPCIbridgeDevStr(virDomainPCIbridgeDefPtr dev,
+ qemuCapsPtr caps, int idx)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAsprintf(&buf, "pci-bridge,chassis_nr=1");
+
+ if ((dev->type != VIR_DOMAIN_PCIBRIDGE_TYPE_ROOT) &&
+ (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0))
+ goto error;
+ else
+ virBufferAsprintf(&buf, ",id=pci-bridge%d" , idx);
+
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto error;
+ }
+
+ return virBufferContentAndReset(&buf);
+
+error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+
+}
char *
qemuBuildSoundDevStr(virDomainSoundDefPtr sound,
@@ -5604,6 +5635,19 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArgList(cmd, "-bootloader", def->os.bootloader, NULL);
}
+ for (i = 0; i < def->npcibridges; i++) {
+ virDomainPCIbridgeDefPtr pbdg = def->pcibridges[i];
+
+ if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) {
+ char *optstr;
+ virCommandAddArg(cmd, "-device");
+ if (!(optstr = qemuBuildPCIbridgeDevStr(pbdg, caps, i)))
+ goto error;
+ virCommandAddArg(cmd, optstr);
+ VIR_FREE(optstr);
+ }
+ }
+
for (i = 0 ; i < def->ndisks ; i++) {
virDomainDiskDefPtr disk = def->disks[i];
--
1.7.2.5