43fe83
From 725fe06bebb3f2be2ff685064eccab320ff8aa4c Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <725fe06bebb3f2be2ff685064eccab320ff8aa4c.1380703761.git.jdenemar@redhat.com>
43fe83
From: Laine Stump <laine@laine.org>
43fe83
Date: Fri, 27 Sep 2013 05:19:41 -0600
43fe83
Subject: [PATCH] qemu: allow some PCI devices to be attached to PCIe slots
43fe83
43fe83
Part of the resolution to:
43fe83
43fe83
   https://bugzilla.redhat.com/show_bug.cgi?id=1003983
43fe83
43fe83
Although most devices available in qemu area defined as PCI devices,
43fe83
and strictly speaking should only be attached via a PCI slot, in
43fe83
practice qemu allows them to be attached to a PCIe slot and sometimes
43fe83
this makes sense.
43fe83
43fe83
For example, The UHCI and EHCI USB controllers are usually attached
43fe83
directly to the PCIe "root complex" (i.e. PCIe slots) on real
43fe83
hardware, so that should be possible for a Q35-based qemu virtual
43fe83
machine as well.
43fe83
43fe83
We still want to prefer a standard PCI slot when auto-assigning
43fe83
addresses, though, and in general to disallow attaching PCI devices
43fe83
via PCIe slots.
43fe83
43fe83
This patch makes that possible by adding a new
43fe83
QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG flag. Three things are done
43fe83
with this flag:
43fe83
43fe83
1) It is set for the "pcie-root" controller
43fe83
43fe83
2) qemuCollectPCIAddress() now has a set of nested switches that set
43fe83
this "EITHER" flag for devices that we want to allow connecting to
43fe83
pcie-root when specifically requested in the config.
43fe83
43fe83
3) qemuDomainPCIAddressFlagsCompatible() adds this new flag to the
43fe83
"flagsMatchMask" if the address being checked came from config rather
43fe83
than being newly auto-allocated by libvirt (this knowledge is
43fe83
conveniently already available in the "fromConfig" arg).
43fe83
43fe83
Now any device having the EITHER flag set can be connected to
43fe83
pcie-root if explicitly requested, but auto-allocated addresses for
43fe83
those devices will still be standard PCI slots instead.
43fe83
43fe83
This patch only loosens the restrictions on devices that have been
43fe83
specifically requested, but the setup is such that it should be fairly
43fe83
easy to add new devices.
43fe83
43fe83
(cherry picked from commit 07af519298996f4341f62542c31c1c01969eeceb)
43fe83
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/qemu/qemu_command.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---
43fe83
 src/qemu/qemu_command.h |  4 ++++
43fe83
 2 files changed, 51 insertions(+), 3 deletions(-)
43fe83
43fe83
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
43fe83
index 85eedd5..f025e8c 100644
43fe83
--- a/src/qemu/qemu_command.c
43fe83
+++ b/src/qemu/qemu_command.c
43fe83
@@ -1454,12 +1454,16 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
43fe83
 {
43fe83
     virErrorNumber errType = (fromConfig
43fe83
                               ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
43fe83
+    qemuDomainPCIConnectFlags flagsMatchMask = QEMU_PCI_CONNECT_TYPES_MASK;
43fe83
+
43fe83
+    if (fromConfig)
43fe83
+       flagsMatchMask |= QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG;
43fe83
 
43fe83
     /* If this bus doesn't allow the type of connection (PCI
43fe83
      * vs. PCIe) required by the device, or if the device requires
43fe83
      * hot-plug and this bus doesn't have it, return false.
43fe83
      */
43fe83
-    if (!(devFlags & busFlags & QEMU_PCI_CONNECT_TYPES_MASK)) {
43fe83
+    if (!(devFlags & busFlags & flagsMatchMask)) {
43fe83
         if (reportError) {
43fe83
             if (devFlags & QEMU_PCI_CONNECT_TYPE_PCI) {
43fe83
                 virReportError(errType,
43fe83
@@ -1578,8 +1582,12 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
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
+        /* slots 1 - 31, no hotplug, PCIe only unless the address was
43fe83
+         * specified in user config *and* the particular device being
43fe83
+         * attached also allows it
43fe83
+         */
43fe83
+        bus->flags = (QEMU_PCI_CONNECT_TYPE_PCIE |
43fe83
+                      QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
43fe83
         bus->minSlot = 1;
43fe83
         bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
43fe83
         break;
43fe83
@@ -1717,6 +1725,42 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
43fe83
              */
43fe83
             flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE;
43fe83
             break;
43fe83
+
43fe83
+        case VIR_DOMAIN_CONTROLLER_TYPE_USB:
43fe83
+           /* allow UHCI and EHCI controllers to be manually placed on
43fe83
+            * the PCIe bus (but don't put them there automatically)
43fe83
+            */
43fe83
+           switch (device->data.controller->model) {
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
43fe83
+              flags = (QEMU_PCI_CONNECT_TYPE_PCI |
43fe83
+                       QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
43fe83
+              break;
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
43fe83
+              /* should this be PCIE-only? Or do we need to allow PCI
43fe83
+               * for backward compatibility?
43fe83
+               */
43fe83
+              flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE;
43fe83
+              break;
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
43fe83
+           case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI:
43fe83
+              /* Allow these for PCI only */
43fe83
+              break;
43fe83
+           }
43fe83
+        }
43fe83
+        break;
43fe83
+
43fe83
+    case VIR_DOMAIN_DEVICE_SOUND:
43fe83
+        switch (device->data.sound->model) {
43fe83
+        case VIR_DOMAIN_SOUND_MODEL_ICH6:
43fe83
+            flags = (QEMU_PCI_CONNECT_TYPE_PCI |
43fe83
+                     QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
43fe83
+            break;
43fe83
         }
43fe83
         break;
43fe83
 
43fe83
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
43fe83
index a9854a3..47022e6 100644
43fe83
--- a/src/qemu/qemu_command.h
43fe83
+++ b/src/qemu/qemu_command.h
43fe83
@@ -246,6 +246,10 @@ typedef enum {
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
+   QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG = 1 << 4,
43fe83
+   /* PCI *and* PCIe devices allowed, if the address
43fe83
+    * was specified in the config by the user
43fe83
+    */
43fe83
 } qemuDomainPCIConnectFlags;
43fe83
 
43fe83
 /* a combination of all bit that describe the type of connections
43fe83
-- 
43fe83
1.8.3.2
43fe83