[libvirt] [PATCH 5/5] conf: add pcie-root controller

Laine Stump laine at laine.org
Tue Jul 23 14:44:55 UTC 2013


This controller is implicit on q35 machinetypes. It provides 31 PCIe
(*not* PCI) slots as controller 0.

Currently there are no devices that can connect to pcie-root. For a
usable q35 system, we still need to add a "dmi-to-pci-bridge" pci
controller, which can connect to pcie-root, and provides pci slots.

This patch still requires a test case, which willbe coming up, but I
wanted to include it along with the previous patch to show that it's
simpler to add new controller types now.
---
 docs/formatdomain.html.in | 17 ++++++++++++++---
 src/conf/domain_conf.c    |  4 +++-
 src/conf/domain_conf.h    |  1 +
 src/qemu/qemu_command.c   | 17 +++++++++++++----
 src/qemu/qemu_command.h   |  2 ++
 src/qemu/qemu_domain.c    | 23 +++++++++++++++++------
 6 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 7601aaa..41e3e2a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2338,10 +2338,14 @@
 
     <p>
       PCI controllers have an optional <code>model</code> attribute with
-      possible values <code>pci-root</code> or <code>pci-bridge</code>.
-      For machine types which provide an implicit pci bus, the pci-root
+      possible values <code>pci-root</code>, <code>pcie-root</code>
+      or <code>pci-bridge</code>.
+      For machine types which provide an implicit PCI bus, the pci-root
       controller with index=0 is auto-added and required to use PCI devices.
-      PCI root has no address.
+      pci-root has no address.
+      For machine types which provide an implicit PCI Express (PCIe)
+      bus, the pcie-root controller with index=0 is auto-added and
+      required to use PCIe devices. pcie-root has also no address.
       PCI bridges are auto-added if there are too many devices to fit on
       the one bus provided by pci-root, or a PCI bus number greater than zero
       was specified.
@@ -2361,6 +2365,13 @@
   </devices>
   ...</pre>
 
+<pre>
+  ...
+  <devices>
+    <controller type='pci' index='0' model='pcie-root'/>
+  </devices>
+  ...</pre>
+
     <h4><a name="elementsLease">Device leases</a></h4>
 
     <p>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 10cb7f6..605f706 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -310,6 +310,7 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
 
 VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST,
               "pci-root",
+              "pcie-root",
               "pci-bridge")
 
 VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
@@ -5715,9 +5716,10 @@ virDomainControllerDefParseXML(xmlNodePtr node,
     case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
         switch (def->model) {
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
             if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
                 virReportError(VIR_ERR_XML_ERROR, "%s",
-                               _("pci-root controller should not "
+                               _("pci-root and pcie-root controllers should not "
                                  "have an address"));
                 goto error;
             }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index abf024c..68f36fd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -768,6 +768,7 @@ enum virDomainControllerType {
 
 typedef enum {
     VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT,
+    VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT,
     VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE,
 
     VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 64787b6..7fccb98 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1519,6 +1519,12 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
         bus->minSlot = 1;
         bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
         break;
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+        bus->flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
+                      QEMU_PCI_CONNECT_TYPE_PCIE);
+        bus->minSlot = 1;
+        bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
+        break;
     default:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Invalid PCI controller model %d"), model);
@@ -2277,7 +2283,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
     /* PCI controllers */
     for (i = 0; i < def->ncontrollers; i++) {
         if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
-            if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT)
+            if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
+                def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)
                 continue;
             if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
                 continue;
@@ -4211,8 +4218,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
                               def->idx, def->idx);
             break;
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("wrong function called for pci-root"));
+                           _("wrong function called for pci-root/pcie-root"));
             return NULL;
         }
         break;
@@ -7490,9 +7498,10 @@ qemuBuildCommandLine(virConnectPtr conn,
                     continue;
                 }
 
-                /* Skip pci-root */
+                /* Skip pci-root/pcie-root */
                 if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
-                    cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
+                    (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
+                     cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
                     continue;
                 }
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index ede67fe..a4574f2 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -233,6 +233,8 @@ typedef enum {
 
    QEMU_PCI_CONNECT_TYPE_PCI     = 1 << 2,
    /* PCI devices can connect to this bus */
+   QEMU_PCI_CONNECT_TYPE_PCIE    = 1 << 3,
+   /* PCI Express devices can connect to this bus */
 } qemuDomainPCIConnectFlags;
 
 /* a combination of all bit that describe the type of connections
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index da3b768..34fed56 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -700,6 +700,7 @@ qemuDomainDefPostParse(virDomainDefPtr def,
                        void *opaque ATTRIBUTE_UNUSED)
 {
     bool addPCIRoot = false;
+    bool addPCIeRoot = false;
 
     /* check for emulator and create a default one if needed */
     if (!def->emulator &&
@@ -712,10 +713,13 @@ qemuDomainDefPostParse(virDomainDefPtr def,
     case VIR_ARCH_X86_64:
         if (!def->os.machine)
             break;
-        if (STRPREFIX(def->os.machine, "pc-q35") ||
-            STREQ(def->os.machine, "q35") ||
-            STREQ(def->os.machine, "isapc"))
+        if (STREQ(def->os.machine, "isapc"))
             break;
+        if (STRPREFIX(def->os.machine, "pc-q35") ||
+            STREQ(def->os.machine, "q35")) {
+           addPCIeRoot = true;
+           break;
+        }
         if (!STRPREFIX(def->os.machine, "pc-0.") &&
             !STRPREFIX(def->os.machine, "pc-1.") &&
             !STRPREFIX(def->os.machine, "pc-i440") &&
@@ -743,6 +747,12 @@ qemuDomainDefPostParse(virDomainDefPtr def,
             VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
         return -1;
 
+    if (addPCIeRoot &&
+        virDomainDefMaybeAddController(
+            def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
+            VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) < 0)
+        return -1;
+
     return 0;
 }
 
@@ -1408,9 +1418,10 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
         }
 
         if (pci && pci->idx == 0 &&
-            pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
-            VIR_DEBUG("Removing default 'pci-root' from domain '%s'"
-                      " for migration compatibility", def->name);
+            (pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
+             pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
+            VIR_DEBUG("Removing default pci-root/pcie-root controller from "
+                      "domain '%s' for migration compatibility", def->name);
             toremove++;
         } else {
             pci = NULL;
-- 
1.7.11.7




More information about the libvir-list mailing list