43fe83
From 484b6b06d7b1229836c6402591a7c047d62c95fd Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <484b6b06d7b1229836c6402591a7c047d62c95fd.1377873637.git.jdenemar@redhat.com>
43fe83
From: Laine Stump <laine@laine.org>
43fe83
Date: Tue, 6 Aug 2013 13:23:22 -0600
43fe83
Subject: [PATCH] qemu: add pcie-root controller
43fe83
43fe83
This patch is part of the resolution to:
43fe83
43fe83
   https://bugzilla.redhat.com/show_bug.cgi?id=819968
43fe83
43fe83
This controller is implicit on q35 machinetypes. It provides 31 PCIe
43fe83
(*not* PCI) slots as controller 0.
43fe83
43fe83
Currently there are no devices that can connect to pcie-root, and no
43fe83
implicit pci controller on a q35 machine, so q35 is still
43fe83
unusable. For a usable q35 system, we need to add a
43fe83
"dmi-to-pci-bridge" pci controller, which can connect to pcie-root,
43fe83
and provides standard pci slots that can be used to connect other
43fe83
devices.
43fe83
(cherry picked from commit 48a3f48ac59a335b95b445e69f7e47f3e10d930e)
43fe83
---
43fe83
 docs/formatdomain.html.in                          | 29 ++++++++++++++++------
43fe83
 docs/schemas/domaincommon.rng                      |  1 +
43fe83
 src/conf/domain_conf.c                             |  8 +++---
43fe83
 src/conf/domain_conf.h                             |  1 +
43fe83
 src/qemu/qemu_command.c                            | 23 ++++++++++++++---
43fe83
 src/qemu/qemu_command.h                            |  4 ++-
43fe83
 src/qemu/qemu_domain.c                             | 19 +++++++++++---
43fe83
 tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args |  4 +++
43fe83
 tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml  | 21 ++++++++++++++++
43fe83
 tests/qemuxml2argvtest.c                           |  2 ++
43fe83
 tests/qemuxml2xmltest.c                            |  1 +
43fe83
 11 files changed, 93 insertions(+), 20 deletions(-)
43fe83
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
43fe83
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml
43fe83
43fe83
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
43fe83
index 78e132e..55a6e71 100644
43fe83
--- a/docs/formatdomain.html.in
43fe83
+++ b/docs/formatdomain.html.in
43fe83
@@ -2338,29 +2338,42 @@
43fe83
 
43fe83
     

43fe83
       PCI controllers have an optional model attribute with
43fe83
-      possible values pci-root or pci-bridge.
43fe83
-      For machine types which provide an implicit pci bus, the pci-root
43fe83
+      possible values pci-root, pcie-root
43fe83
+      or pci-bridge.
43fe83
+      For machine types which provide an implicit PCI bus, the pci-root
43fe83
       controller with index=0 is auto-added and required to use PCI devices.
43fe83
-      PCI root has no address.
43fe83
-      PCI bridges are auto-added if there are too many devices to fit on
43fe83
-      the one bus provided by pci-root, or a PCI bus number greater than zero
43fe83
-      was specified.
43fe83
+      pci-root has no address.
43fe83
       PCI bridges can also be specified manually, but their addresses should
43fe83
       only refer to PCI buses provided by already specified PCI controllers.
43fe83
       Leaving gaps in the PCI controller indexes might lead to an invalid
43fe83
       configuration.
43fe83
-      (since 1.0.5)
43fe83
+      (pci-root and pci-bridge since 1.0.5)
43fe83
     

43fe83
 
43fe83
   ...
43fe83
   <devices>
43fe83
     <controller type='pci' index='0' model='pci-root'/>
43fe83
     <controller type='pci' index='1' model='pci-bridge'>
43fe83
-      <address type='pci' domain='0' bus='0' slot='5' function='0' multifunction=off'/>
43fe83
+      <address type='pci' domain='0' bus='0' slot='5' function='0' multifunction='off'/>
43fe83
     </controller>
43fe83
   </devices>
43fe83
   ...
43fe83
 
43fe83
+    

43fe83
+      For machine types which provide an implicit PCI Express (PCIe)
43fe83
+      bus (for example, the machine types based on the Q35 chipset),
43fe83
+      the pcie-root controller with index=0 is auto-added to the
43fe83
+      domain's configuration. pcie-root has also no address, provides
43fe83
+      31 slots (numbered 1-31) and can only be used to attach PCIe
43fe83
+      devices.  (since 1.1.2).
43fe83
+    

43fe83
+
43fe83
+  ...
43fe83
+  <devices>
43fe83
+    <controller type='pci' index='0' model='pcie-root'/>
43fe83
+  </devices>
43fe83
+  ...
43fe83
+
43fe83
     

Device leases

43fe83
 
43fe83
     

43fe83
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
43fe83
index 745b959..e04be12 100644
43fe83
--- a/docs/schemas/domaincommon.rng
43fe83
+++ b/docs/schemas/domaincommon.rng
43fe83
@@ -1538,6 +1538,7 @@
43fe83
             <attribute name="model">
43fe83
               <choice>
43fe83
                 <value>pci-root</value>
43fe83
+                <value>pcie-root</value>
43fe83
                 <value>pci-bridge</value>
43fe83
               </choice>
43fe83
             </attribute>
43fe83
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
43fe83
index 18c6acf..02f1cf6 100644
43fe83
--- a/src/conf/domain_conf.c
43fe83
+++ b/src/conf/domain_conf.c
43fe83
@@ -310,6 +310,7 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
43fe83
 
43fe83
 VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST,
43fe83
               "pci-root",
43fe83
+              "pcie-root",
43fe83
               "pci-bridge")
43fe83
 
43fe83
 VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
43fe83
@@ -5714,16 +5715,17 @@ virDomainControllerDefParseXML(xmlNodePtr node,
43fe83
     case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
43fe83
         switch (def->model) {
43fe83
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
43fe83
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
43fe83
             if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
43fe83
                 virReportError(VIR_ERR_XML_ERROR, "%s",
43fe83
-                               _("pci-root controller should not "
43fe83
+                               _("pci-root and pcie-root controllers should not "
43fe83
                                  "have an address"));
43fe83
                 goto error;
43fe83
             }
43fe83
             if (def->idx != 0) {
43fe83
                 virReportError(VIR_ERR_XML_ERROR, "%s",
43fe83
-                               _("pci-root controller should have "
43fe83
-                                 "index 0"));
43fe83
+                               _("pci-root and pcie-root controllers "
43fe83
+                                 "should have index 0"));
43fe83
                 goto error;
43fe83
             }
43fe83
 
43fe83
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
43fe83
index abf024c..68f36fd 100644
43fe83
--- a/src/conf/domain_conf.h
43fe83
+++ b/src/conf/domain_conf.h
43fe83
@@ -768,6 +768,7 @@ enum virDomainControllerType {
43fe83
 
43fe83
 typedef enum {
43fe83
     VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT,
43fe83
+    VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT,
43fe83
     VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE,
43fe83
 
43fe83
     VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
43fe83
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
43fe83
index 2886e01..8ac39ff 100644
43fe83
--- a/src/qemu/qemu_command.c
43fe83
+++ b/src/qemu/qemu_command.c
43fe83
@@ -1453,6 +1453,12 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
43fe83
                                  "device. Device requires a standard PCI slot, "
43fe83
                                  "which is not provided by this bus"),
43fe83
                                addr->domain, addr->bus);
43fe83
+            } else if (devFlags & QEMU_PCI_CONNECT_TYPE_PCIE) {
43fe83
+                virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
+                               _("PCI bus %.4x:%.2x is not compatible with the "
43fe83
+                                 "device. Device requires a PCI Express slot, "
43fe83
+                                 "which is not provided by this bus"),
43fe83
+                               addr->domain, addr->bus);
43fe83
             } else {
43fe83
                 /* this should never happen. If it does, there is a
43fe83
                  * bug in the code that sets the flag bits for devices.
43fe83
@@ -1549,6 +1555,12 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
43fe83
         bus->minSlot = 1;
43fe83
         bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
43fe83
         break;
43fe83
+    case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
43fe83
+        /* slots 1 - 31, PCIe devices only, no hotplug */
43fe83
+        bus->flags = QEMU_PCI_CONNECT_TYPE_PCIE;
43fe83
+        bus->minSlot = 1;
43fe83
+        bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
43fe83
+        break;
43fe83
     default:
43fe83
         virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
                        _("Invalid PCI controller model %d"), model);
43fe83
@@ -2350,7 +2362,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
43fe83
                 continue;
43fe83
             switch (def->controllers[i]->model) {
43fe83
             case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
43fe83
-                /* pci-root is implicit in the machine,
43fe83
+            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
43fe83
+                /* pci-root and pcie-root are implicit in the machine,
43fe83
                  * and needs no address */
43fe83
                 continue;
43fe83
             case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
43fe83
@@ -4339,8 +4352,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
43fe83
                               def->idx, def->idx);
43fe83
             break;
43fe83
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
43fe83
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
43fe83
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
-                           _("wrong function called for pci-root"));
43fe83
+                           _("wrong function called for pci-root/pcie-root"));
43fe83
             return NULL;
43fe83
         }
43fe83
         break;
43fe83
@@ -7618,9 +7632,10 @@ qemuBuildCommandLine(virConnectPtr conn,
43fe83
                     continue;
43fe83
                 }
43fe83
 
43fe83
-                /* Skip pci-root */
43fe83
+                /* Skip pci-root/pcie-root */
43fe83
                 if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
43fe83
-                    cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
43fe83
+                    (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
43fe83
+                     cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
43fe83
                     continue;
43fe83
                 }
43fe83
 
43fe83
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
43fe83
index bf4953a..e5111d2 100644
43fe83
--- a/src/qemu/qemu_command.h
43fe83
+++ b/src/qemu/qemu_command.h
43fe83
@@ -233,13 +233,15 @@ typedef enum {
43fe83
 
43fe83
    QEMU_PCI_CONNECT_TYPE_PCI     = 1 << 2,
43fe83
    /* PCI devices can connect to this bus */
43fe83
+   QEMU_PCI_CONNECT_TYPE_PCIE    = 1 << 3,
43fe83
+   /* PCI Express devices can connect to this bus */
43fe83
 } qemuDomainPCIConnectFlags;
43fe83
 
43fe83
 /* a combination of all bit that describe the type of connections
43fe83
  * allowed, e.g. PCI, PCIe, switch
43fe83
  */
43fe83
 # define QEMU_PCI_CONNECT_TYPES_MASK \
43fe83
-    QEMU_PCI_CONNECT_TYPE_PCI
43fe83
+   (QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE)
43fe83
 
43fe83
 
43fe83
 int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
43fe83
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
43fe83
index 648121a..40b813c 100644
43fe83
--- a/src/qemu/qemu_domain.c
43fe83
+++ b/src/qemu/qemu_domain.c
43fe83
@@ -701,6 +701,7 @@ qemuDomainDefPostParse(virDomainDefPtr def,
43fe83
 {
43fe83
     bool addDefaultUSB = true;
43fe83
     bool addPCIRoot = false;
43fe83
+    bool addPCIeRoot = false;
43fe83
 
43fe83
     /* check for emulator and create a default one if needed */
43fe83
     if (!def->emulator &&
43fe83
@@ -713,12 +714,16 @@ qemuDomainDefPostParse(virDomainDefPtr def,
43fe83
     case VIR_ARCH_X86_64:
43fe83
         if (!def->os.machine)
43fe83
             break;
43fe83
-        if (STRPREFIX(def->os.machine, "pc-q35") ||
43fe83
-            STREQ(def->os.machine, "q35") ||
43fe83
-            STREQ(def->os.machine, "isapc")) {
43fe83
+        if (STREQ(def->os.machine, "isapc")) {
43fe83
             addDefaultUSB = false;
43fe83
             break;
43fe83
         }
43fe83
+        if (STRPREFIX(def->os.machine, "pc-q35") ||
43fe83
+            STREQ(def->os.machine, "q35")) {
43fe83
+           addPCIeRoot = true;
43fe83
+           addDefaultUSB = false;
43fe83
+           break;
43fe83
+        }
43fe83
         if (!STRPREFIX(def->os.machine, "pc-0.") &&
43fe83
             !STRPREFIX(def->os.machine, "pc-1.") &&
43fe83
             !STRPREFIX(def->os.machine, "pc-i440") &&
43fe83
@@ -755,6 +760,12 @@ qemuDomainDefPostParse(virDomainDefPtr def,
43fe83
             VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
43fe83
         return -1;
43fe83
 
43fe83
+    if (addPCIeRoot &&
43fe83
+        virDomainDefMaybeAddController(
43fe83
+            def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
43fe83
+            VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) < 0)
43fe83
+        return -1;
43fe83
+
43fe83
     return 0;
43fe83
 }
43fe83
 
43fe83
@@ -1421,7 +1432,7 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
43fe83
 
43fe83
         if (pci && pci->idx == 0 &&
43fe83
             pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
43fe83
-            VIR_DEBUG("Removing default 'pci-root' from domain '%s'"
43fe83
+            VIR_DEBUG("Removing default pci-root from domain '%s'"
43fe83
                       " for migration compatibility", def->name);
43fe83
             toremove++;
43fe83
         } else {
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
43fe83
new file mode 100644
43fe83
index 0000000..e937189
43fe83
--- /dev/null
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.args
43fe83
@@ -0,0 +1,4 @@
43fe83
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/libexec/qemu-kvm \
43fe83
+-S -M q35 -m 2048 -smp 2 -nographic -nodefaults \
43fe83
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
43fe83
+-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.1,addr=0x1 -usb
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml
43fe83
new file mode 100644
43fe83
index 0000000..1aa5455
43fe83
--- /dev/null
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcie-root.xml
43fe83
@@ -0,0 +1,21 @@
43fe83
+<domain type='qemu'>
43fe83
+  <name>q35-test</name>
43fe83
+  <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
43fe83
+  <memory unit='KiB'>2097152</memory>
43fe83
+  <currentMemory unit='KiB'>2097152</currentMemory>
43fe83
+  <vcpu placement='static' cpuset='0-1'>2</vcpu>
43fe83
+  <os>
43fe83
+    <type arch='x86_64' machine='q35'>hvm</type>
43fe83
+    <boot dev='hd'/>
43fe83
+  </os>
43fe83
+  <clock offset='utc'/>
43fe83
+  <on_poweroff>destroy</on_poweroff>
43fe83
+  <on_reboot>restart</on_reboot>
43fe83
+  <on_crash>destroy</on_crash>
43fe83
+  <devices>
43fe83
+    <emulator>/usr/libexec/qemu-kvm</emulator>
43fe83
+    <controller type='pci' index='0' model='pcie-root'/>
43fe83
+    <controller type='usb' index='0'/>
43fe83
+    <memballoon model='none'/>
43fe83
+  </devices>
43fe83
+</domain>
43fe83
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
43fe83
index b7485fc..57c6989 100644
43fe83
--- a/tests/qemuxml2argvtest.c
43fe83
+++ b/tests/qemuxml2argvtest.c
43fe83
@@ -994,6 +994,8 @@ mymain(void)
43fe83
     DO_TEST("pci-autoadd-idx", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
43fe83
     DO_TEST("pci-bridge-many-disks",
43fe83
             QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
43fe83
+    DO_TEST("pcie-root",
43fe83
+            QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
43fe83
 
43fe83
     DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_DRIVE,
43fe83
             QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
43fe83
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
43fe83
index 66be40e..ea511b8 100644
43fe83
--- a/tests/qemuxml2xmltest.c
43fe83
+++ b/tests/qemuxml2xmltest.c
43fe83
@@ -294,6 +294,7 @@ mymain(void)
43fe83
     DO_TEST_DIFFERENT("pci-bridge-many-disks");
43fe83
     DO_TEST_DIFFERENT("pci-autoadd-addr");
43fe83
     DO_TEST_DIFFERENT("pci-autoadd-idx");
43fe83
+    DO_TEST("pcie-root");
43fe83
 
43fe83
     DO_TEST("hostdev-scsi-lsi");
43fe83
     DO_TEST("hostdev-scsi-virtio-scsi");
43fe83
-- 
43fe83
1.8.3.2
43fe83