[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [rebased][PATCH 2/4] build command line for pci-bridge device of qemu



format command line of qemu to add pci-bridge
like this: -device pci-bridge.
and also add a qemu capability to check if
qemu support pci-bridge device

Signed-off-by: liguang <lig fnst cn fujitsu com>
---
 src/qemu/qemu_capabilities.c |    6 ++-
 src/qemu/qemu_capabilities.h |    1 +
 src/qemu/qemu_command.c      |   70 ++++++++++++++++++++++++++++-------------
 3 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 29693c3..89ae2aa 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -200,9 +200,10 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
               "vmware-svga",
               "device-video-primary",
               "s390-sclp",
-
+ 
               "usb-serial", /* 125 */
-              "usb-net",
+              "usb-serial",
+              "pci-bridge"
 
     );
 
@@ -1351,6 +1352,7 @@ struct qemuCapsStringFlags qemuCapsObjectTypes[] = {
     { "cirrus-vga", QEMU_CAPS_DEVICE_CIRRUS_VGA },
     { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA },
     { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL},
+    { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE },
     { "usb-net", QEMU_CAPS_DEVICE_USB_NET},
 };
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 5279d07..c50bba8 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -165,6 +165,7 @@ enum qemuCapsFlags {
     QEMU_CAPS_SCLP_S390          = 124, /* -device sclp* */
     QEMU_CAPS_DEVICE_USB_SERIAL  = 125, /* -device usb-serial */
     QEMU_CAPS_DEVICE_USB_NET     = 126, /* -device usb-net */
+    QEMU_CAPS_DEVICE_PCI_BRIDGE  = 127, /* -device pci-bridge */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f6273c1..57dcb2c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -956,13 +956,6 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev)
 {
     char *addr;
 
-    if (dev->addr.pci.domain != 0 ||
-        dev->addr.pci.bus != 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Only PCI domain 0 and bus 0 are available"));
-        return NULL;
-    }
-
     if (virAsprintf(&addr, "%d:%d:%d.%d",
                     dev->addr.pci.domain,
                     dev->addr.pci.bus,
@@ -974,8 +967,24 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev)
     return addr;
 }
 
+static int qemuPciBridgeSupport(virDomainDefPtr def)
+{
+    int i, c = 0;
+
+    for (i = 0; i < def->ncontrollers; i++) {
+        virDomainControllerDefPtr controller = def->controllers[i];
+
+        if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE)
+            c++;
+    }
 
-static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
+    if (c > 1)
+        return 0;
+    else
+        return -1;
+}
+
+static int qemuCollectPCIAddress(virDomainDefPtr def,
                                  virDomainDeviceDefPtr device,
                                  virDomainDeviceInfoPtr info,
                                  void *opaque)
@@ -994,6 +1003,20 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
         return 0;
     }
 
+    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 && qemuPciBridgeSupport(def) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Only PCI device addresses with bus=0 are"
+                         " supported without pci-bridge support"));
+        return -1;
+    }
+
     addr = qemuPCIAddressAsString(info);
     if (!addr)
         goto cleanup;
@@ -1002,7 +1025,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
         if (info->addr.pci.function != 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("Attempted double use of PCI Address '%s' "
-                             "(may need \"multifunction='on'\" for device on function 0)"),
+                             "(may need \"multifunction='on'\" for "
+                             "device on function 0)"),
                            addr);
         } else {
             virReportError(VIR_ERR_XML_ERROR,
@@ -1037,7 +1061,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
                 goto cleanup;
             }
 
-            VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", addr);
+            VIR_DEBUG("Remembering PCI addr %s (multifunction=off"
+                      " for function 0)", addr);
             if (virHashAddEntry(addrs->used, addr, addr))
                 goto cleanup;
             addr = NULL;
@@ -1753,16 +1778,6 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
                           qemuCapsPtr caps)
 {
     if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        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) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Only PCI device addresses with bus=0 are supported"));
-            return -1;
-        }
         if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
             if (info->addr.pci.function > 7) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1777,6 +1792,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
                                  "are supported with this QEMU binary"));
                 return -1;
             }
+
             if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                _("'multifunction=on' is not supported with "
@@ -1787,11 +1803,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
 
         /* XXX
          * When QEMU grows support for > 1 PCI bus, then pci.0 changes
-         * to pci.1, pci.2, etc
+         * to pci.1, pci.2, etc, (e.g. when support pci-to-pci bridge)
          * 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 (qemuCapsGet(caps, QEMU_CAPS_DEVICE_PCI_BRIDGE))
+            virBufferAsprintf(buf, ",bus=pci.%d", info->addr.pci.bus);
+        else if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS))
             virBufferAsprintf(buf, ",bus=pci.0");
         else
             virBufferAsprintf(buf, ",bus=pci");
@@ -3072,6 +3090,12 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
     int model;
 
     switch (def->type) {
+    case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE:
+        virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d", def->idx+1);
+        virBufferAsprintf(&buf, ",id=pci.%d", def->idx);
+        if (def->idx == 0)
+            goto out;
+        break;
     case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
         model = def->model;
         if ((qemuSetScsiControllerModel(domainDef, caps, &model)) < 0)
@@ -3145,6 +3169,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
     if (qemuBuildDeviceAddressStr(&buf, &def->info, caps) < 0)
         goto error;
 
+out:
     if (virBufferError(&buf)) {
         virReportOOMError();
         goto error;
@@ -5080,6 +5105,7 @@ qemuBuildCommandLine(virConnectPtr conn,
         /* We don't add an explicit IDE or FD controller because the
          * provided PIIX4 device already includes one. It isn't possible to
          * remove the PIIX4. */
+        VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE,
         VIR_DOMAIN_CONTROLLER_TYPE_USB,
         VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
         VIR_DOMAIN_CONTROLLER_TYPE_SATA,
-- 
1.7.2.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]