Blame SOURCES/libvirt-qemu-conf-set-HOTPLUGGABLE-connect-flag-during-PCI-address-set-init.patch

fbe740
From 351bb3a04c1eb6de11efad54f809a6f3e3a868c8 Mon Sep 17 00:00:00 2001
fbe740
Message-Id: <351bb3a04c1eb6de11efad54f809a6f3e3a868c8@dist-git>
fbe740
From: Laine Stump <laine@redhat.com>
fbe740
Date: Sun, 26 Apr 2020 13:17:01 -0400
fbe740
Subject: [PATCH] qemu/conf: set HOTPLUGGABLE connect flag during PCI address
fbe740
 set init
fbe740
fbe740
virDomainPCIAddressBusSetModel() is called for each PCI controller
fbe740
when building an address set prior to assiging PCI addresses to
fbe740
devices.
fbe740
fbe740
This patch adds a new argument, allowHotplug, to that function that
fbe740
can be set to false if we know for certain that a particular
fbe740
controller won't support hotplug
fbe740
fbe740
The most interesting case is in qemuDomainPCIAddressSetCreate(), where
fbe740
the config of each existing controller is available while building the
fbe740
address set, so we can appropriately set allowHotplug = false when the
fbe740
user has "hotplug='off'" in the config of a controller that normally
fbe740
would support hotplug. In all other cases, it is set to true or false
fbe740
in accordance with the capability of the controller model.
fbe740
fbe740
So far we aren't doing anything with this bus flag in the address set.
fbe740
fbe740
Signed-off-by: Laine Stump <laine@redhat.com>
fbe740
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
fbe740
(cherry picked from commit aa15e9259f1f246e69fb9742581ced720c88695d)
fbe740
fbe740
https://bugzilla.redhat.com/1802592
fbe740
Signed-off-by: Laine Stump <laine@redhat.com>
fbe740
Message-Id: <20200426171703.18808-1-laine@redhat.com>
fbe740
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
fbe740
---
fbe740
 src/conf/domain_addr.c         | 31 +++++++++++++++++++++----------
fbe740
 src/conf/domain_addr.h         |  3 ++-
fbe740
 src/qemu/qemu_domain_address.c | 10 +++++++---
fbe740
 3 files changed, 30 insertions(+), 14 deletions(-)
fbe740
fbe740
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
fbe740
index 05f036e3e6..cc45a0bbf1 100644
fbe740
--- a/src/conf/domain_addr.c
fbe740
+++ b/src/conf/domain_addr.c
fbe740
@@ -495,31 +495,40 @@ virDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
fbe740
 
fbe740
 int
fbe740
 virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
fbe740
-                               virDomainControllerModelPCI model)
fbe740
+                               virDomainControllerModelPCI model,
fbe740
+                               bool allowHotplug)
fbe740
 {
fbe740
     /* set flags for what can be connected *downstream* from each
fbe740
      * bus.
fbe740
      */
fbe740
+    virDomainPCIConnectFlags hotplugFlag = 0;
fbe740
+
fbe740
+    if (allowHotplug)
fbe740
+        hotplugFlag = VIR_PCI_CONNECT_HOTPLUGGABLE;
fbe740
+
fbe740
     switch (model) {
fbe740
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
fbe740
         bus->flags = (VIR_PCI_CONNECT_AUTOASSIGN |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCI_DEVICE |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCI_BRIDGE |
fbe740
-                      VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS);
fbe740
+                      VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS |
fbe740
+                      hotplugFlag);
fbe740
         bus->minSlot = 1;
fbe740
         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
fbe740
         break;
fbe740
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
fbe740
         bus->flags = (VIR_PCI_CONNECT_AUTOASSIGN |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCI_DEVICE |
fbe740
-                      VIR_PCI_CONNECT_TYPE_PCI_BRIDGE);
fbe740
+                      VIR_PCI_CONNECT_TYPE_PCI_BRIDGE |
fbe740
+                      hotplugFlag);
fbe740
         bus->minSlot = 1;
fbe740
         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
fbe740
         break;
fbe740
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS:
fbe740
         bus->flags = (VIR_PCI_CONNECT_AUTOASSIGN |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCI_DEVICE |
fbe740
-                      VIR_PCI_CONNECT_TYPE_PCI_BRIDGE);
fbe740
+                      VIR_PCI_CONNECT_TYPE_PCI_BRIDGE |
fbe740
+                      hotplugFlag);
fbe740
         bus->minSlot = 0;
fbe740
         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
fbe740
         break;
fbe740
@@ -550,7 +559,8 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
fbe740
          * the first of which is not usable because of the SHPC */
fbe740
         bus->flags = (VIR_PCI_CONNECT_AUTOASSIGN |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCI_DEVICE |
fbe740
-                      VIR_PCI_CONNECT_TYPE_PCI_BRIDGE);
fbe740
+                      VIR_PCI_CONNECT_TYPE_PCI_BRIDGE |
fbe740
+                      hotplugFlag);
fbe740
         bus->minSlot = 1;
fbe740
         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
fbe740
         break;
fbe740
@@ -562,7 +572,8 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
fbe740
         bus->flags = (VIR_PCI_CONNECT_AUTOASSIGN |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCIE_DEVICE |
fbe740
                       VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT |
fbe740
-                      VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE);
fbe740
+                      VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE |
fbe740
+                      hotplugFlag);
fbe740
         bus->minSlot = 0;
fbe740
         bus->maxSlot = 0;
fbe740
         break;
fbe740
@@ -759,7 +770,7 @@ virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
fbe740
          * rest are of the requested type
fbe740
          */
fbe740
         if (virDomainPCIAddressBusSetModel(&addrs->buses[i++],
fbe740
-                                           VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE) < 0) {
fbe740
+                                           VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE, false) < 0) {
fbe740
             return -1;
fbe740
         }
fbe740
     }
fbe740
@@ -776,20 +787,20 @@ virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
fbe740
          * will be allocated for the dummy PCIe device later on.
fbe740
          */
fbe740
         if (virDomainPCIAddressBusSetModel(&addrs->buses[i],
fbe740
-                                           VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT) < 0) {
fbe740
+                                           VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT, true) < 0) {
fbe740
             return -1;
fbe740
         }
fbe740
         addrs->buses[i].flags = VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE;
fbe740
         i++;
fbe740
 
fbe740
         if (virDomainPCIAddressBusSetModel(&addrs->buses[i++],
fbe740
-                                           VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE) < 0) {
fbe740
+                                           VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE, true) < 0) {
fbe740
             return -1;
fbe740
         }
fbe740
     }
fbe740
 
fbe740
     for (; i < addrs->nbuses; i++) {
fbe740
-        if (virDomainPCIAddressBusSetModel(&addrs->buses[i], model) < 0)
fbe740
+        if (virDomainPCIAddressBusSetModel(&addrs->buses[i], model, true) < 0)
fbe740
             return -1;
fbe740
     }
fbe740
 
fbe740
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
fbe740
index 40738ddb72..c1363c1490 100644
fbe740
--- a/src/conf/domain_addr.h
fbe740
+++ b/src/conf/domain_addr.h
fbe740
@@ -148,7 +148,8 @@ bool virDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
fbe740
 
fbe740
 
fbe740
 int virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
fbe740
-                                   virDomainControllerModelPCI model)
fbe740
+                                   virDomainControllerModelPCI model,
fbe740
+                                   bool allowHotplug)
fbe740
     ATTRIBUTE_NONNULL(1);
fbe740
 
fbe740
 bool virDomainPCIAddressBusIsFullyReserved(virDomainPCIAddressBusPtr bus)
fbe740
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
fbe740
index e81585bc6c..2ae1724696 100644
fbe740
--- a/src/qemu/qemu_domain_address.c
fbe740
+++ b/src/qemu/qemu_domain_address.c
fbe740
@@ -1645,6 +1645,7 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
fbe740
     for (i = 0; i < def->ncontrollers; i++) {
fbe740
         virDomainControllerDefPtr cont = def->controllers[i];
fbe740
         size_t idx = cont->idx;
fbe740
+        bool allowHotplug = false;
fbe740
 
fbe740
         if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI)
fbe740
             continue;
fbe740
@@ -1656,7 +1657,10 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
fbe740
             goto error;
fbe740
         }
fbe740
 
fbe740
-        if (virDomainPCIAddressBusSetModel(&addrs->buses[idx], cont->model) < 0)
fbe740
+        if (cont->opts.pciopts.hotplug != VIR_TRISTATE_SWITCH_OFF)
fbe740
+            allowHotplug = true;
fbe740
+
fbe740
+        if (virDomainPCIAddressBusSetModel(&addrs->buses[idx], cont->model, allowHotplug) < 0)
fbe740
             goto error;
fbe740
 
fbe740
         /* Forward the information about isolation groups */
fbe740
@@ -1674,7 +1678,7 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
fbe740
          * assigning addresses to devices.
fbe740
          */
fbe740
         if (virDomainPCIAddressBusSetModel(&addrs->buses[0],
fbe740
-                                           VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
fbe740
+                                           VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT, true) < 0)
fbe740
             goto error;
fbe740
     }
fbe740
 
fbe740
@@ -1696,7 +1700,7 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
fbe740
         if (addrs->buses[i].model)
fbe740
             continue;
fbe740
 
fbe740
-        if (virDomainPCIAddressBusSetModel(&addrs->buses[i], defaultModel) < 0)
fbe740
+        if (virDomainPCIAddressBusSetModel(&addrs->buses[i], defaultModel, true) < 0)
fbe740
             goto error;
fbe740
 
fbe740
         VIR_DEBUG("Auto-adding <controller type='pci' model='%s' index='%zu'/>",
fbe740
-- 
fbe740
2.26.2
fbe740