]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
qemu: add pcie-root controller
authorLaine Stump <laine@laine.org>
Wed, 10 Jul 2013 19:19:32 +0000 (15:19 -0400)
committerLaine Stump <laine@laine.org>
Mon, 5 Aug 2013 19:13:56 +0000 (15:13 -0400)
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, and no
implicit pci controller on a q35 machine, so q35 is still
unusable. For a usable q35 system, we need to add a
"dmi-to-pci-bridge" pci controller, which can connect to pcie-root,
and provides standard pci slots that can be used to connect other
devices.

docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_domain.c
tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmltest.c

index 49c7c8d71c4aa5b922c6da81e1e451d98afa6ba1..6a2e121f4280aea0a70a34a7e60de23cfd8477e4 100644 (file)
 
     <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 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.
+      pci-root has no address.
       PCI bridges can also be specified manually, but their addresses should
       only refer to PCI buses provided by already specified PCI controllers.
       Leaving gaps in the PCI controller indexes might lead to an invalid
       configuration.
-      (<span class="since">since 1.0.5</span>)
+      (pci-root and pci-bridge <span class="since">since 1.0.5</span>)
     </p>
 <pre>
   ...
   &lt;devices&gt;
     &lt;controller type='pci' index='0' model='pci-root'/&gt;
     &lt;controller type='pci' index='1' model='pci-bridge'&gt;
-      &lt;address type='pci' domain='0' bus='0' slot='5' function='0' multifunction=off'/&gt;
+      &lt;address type='pci' domain='0' bus='0' slot='5' function='0' multifunction='off'/&gt;
     &lt;/controller&gt;
   &lt;/devices&gt;
+  ...</pre>
+
+    <p>
+      For machine types which provide an implicit PCI Express (PCIe)
+      bus (for example, the machine types based on the Q35 chipset),
+      the pcie-root controller with index=0 is auto-added to the
+      domain's configuration. pcie-root has also no address, provides
+      31 slots (numbered 1-31) and can only be used to attach PCIe
+      devices.  (<span class="since">since 1.1.2</span>).
+    </p>
+<pre>
+  ...
+  &lt;devices&gt;
+    &lt;controller type='pci' index='0' model='pcie-root'/&gt;
+  &lt;/devices&gt;
   ...</pre>
 
     <h4><a name="elementsLease">Device leases</a></h4>
index 745b959a8f09f43f1abe40e9cc2681a539c7183a..e04be12337eaa023b27ab6dbb4c068405cb8fa3f 100644 (file)
             <attribute name="model">
               <choice>
                 <value>pci-root</value>
+                <value>pcie-root</value>
                 <value>pci-bridge</value>
               </choice>
             </attribute>
index 63350b6eb0df37857fc5a89b4dbf3ffd5be6ca4b..59a96f2d106ce9ca12ee873c553179f8bf559924 100644 (file)
@@ -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,
@@ -5714,16 +5715,17 @@ 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;
             }
             if (def->idx != 0) {
                 virReportError(VIR_ERR_XML_ERROR, "%s",
-                               _("pci-root controller should have "
-                                 "index 0"));
+                               _("pci-root and pcie-root controllers "
+                                 "should have index 0"));
                 goto error;
             }
 
index de3b59c690f583a2f505372c593fce67e324b7cf..63a14447800c1a73bd77fd1b03e8978029ab80b9 100644 (file)
@@ -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
index 2886e013cb1b3e2ef920efb82ffbc5bbb1f05188..8ac39ff9cc435817e2ce2d9f3aa029fd5eac8c6c 100644 (file)
@@ -1453,6 +1453,12 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
                                  "device. Device requires a standard PCI slot, "
                                  "which is not provided by this bus"),
                                addr->domain, addr->bus);
+            } else if (devFlags & QEMU_PCI_CONNECT_TYPE_PCIE) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("PCI bus %.4x:%.2x is not compatible with the "
+                                 "device. Device requires a PCI Express slot, "
+                                 "which is not provided by this bus"),
+                               addr->domain, addr->bus);
             } else {
                 /* this should never happen. If it does, there is a
                  * bug in the code that sets the flag bits for devices.
@@ -1549,6 +1555,12 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
         bus->minSlot = 1;
         bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
         break;
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+        /* slots 1 - 31, PCIe devices only, no hotplug */
+        bus->flags = 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);
@@ -2350,7 +2362,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
                 continue;
             switch (def->controllers[i]->model) {
             case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
-                /* pci-root is implicit in the machine,
+            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+                /* pci-root and pcie-root are implicit in the machine,
                  * and needs no address */
                 continue;
             case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
@@ -4339,8 +4352,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;
@@ -7618,9 +7632,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;
                 }
 
index bf4953aeaff854229202947022a6511886c68e60..e5111d203e90c0056de6d27f282fb1e7b19dbe33 100644 (file)
@@ -233,13 +233,15 @@ 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
  * allowed, e.g. PCI, PCIe, switch
  */
 # define QEMU_PCI_CONNECT_TYPES_MASK \
-    QEMU_PCI_CONNECT_TYPE_PCI
+   (QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE)
 
 
 int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
index d3da6669b921bbf05855589a9f86548ab859e6f0..4d04609a42c7be34d36790b8c9db19a0c53bdfe0 100644 (file)
@@ -701,6 +701,7 @@ qemuDomainDefPostParse(virDomainDefPtr def,
 {
     bool addDefaultUSB = true;
     bool addPCIRoot = false;
+    bool addPCIeRoot = false;
 
     /* check for emulator and create a default one if needed */
     if (!def->emulator &&
@@ -713,12 +714,16 @@ 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")) {
             addDefaultUSB = false;
             break;
         }
+        if (STRPREFIX(def->os.machine, "pc-q35") ||
+            STREQ(def->os.machine, "q35")) {
+           addPCIeRoot = true;
+           addDefaultUSB = false;
+           break;
+        }
         if (!STRPREFIX(def->os.machine, "pc-0.") &&
             !STRPREFIX(def->os.machine, "pc-1.") &&
             !STRPREFIX(def->os.machine, "pc-i440") &&
@@ -755,6 +760,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;
 }
 
@@ -1421,7 +1432,7 @@ 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'"
+            VIR_DEBUG("Removing default pci-root from domain '%s'"
                       " for migration compatibility", def->name);
             toremove++;
         } else {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
new file mode 100644 (file)
index 0000000..e937189
--- /dev/null
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/libexec/qemu-kvm \
+-S -M q35 -m 2048 -smp 2 -nographic -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.1,addr=0x1 -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml
new file mode 100644 (file)
index 0000000..1aa5455
--- /dev/null
@@ -0,0 +1,21 @@
+<domain type='qemu'>
+  <name>q35-test</name>
+  <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+  <memory unit='KiB'>2097152</memory>
+  <currentMemory unit='KiB'>2097152</currentMemory>
+  <vcpu placement='static' cpuset='0-1'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/libexec/qemu-kvm</emulator>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <controller type='usb' index='0'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
index b7485fc992a41005172b1419ca519ea090552d57..57c6989e32c3e459764a9dda2d5efa7fcf3ab690 100644 (file)
@@ -994,6 +994,8 @@ mymain(void)
     DO_TEST("pci-autoadd-idx", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
     DO_TEST("pci-bridge-many-disks",
             QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
+    DO_TEST("pcie-root",
+            QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
 
     DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_DRIVE,
             QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
index 66be40e648972420f1317fd23986d299e73580c0..ea511b8565aeafb8a30fec7c53ef740bd270007e 100644 (file)
@@ -294,6 +294,7 @@ mymain(void)
     DO_TEST_DIFFERENT("pci-bridge-many-disks");
     DO_TEST_DIFFERENT("pci-autoadd-addr");
     DO_TEST_DIFFERENT("pci-autoadd-idx");
+    DO_TEST("pcie-root");
 
     DO_TEST("hostdev-scsi-lsi");
     DO_TEST("hostdev-scsi-virtio-scsi");