a41c76
From c9d4140df5d22a1bfc895eb1049cc714eaadc86c Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <c9d4140df5d22a1bfc895eb1049cc714eaadc86c@dist-git>
a41c76
From: Laine Stump <laine@redhat.com>
a41c76
Date: Sun, 26 Apr 2020 13:04:08 -0400
a41c76
Subject: [PATCH] qemu: hook up pcie-root-port hotplug='off' option
a41c76
a41c76
If a pcie-root-port or pcie-downstream-port has hotplug='off' in its
a41c76
<target> subelement, and if the qemu binary supports the hotplug=false
a41c76
option, then it will be added to the commandline for the pcie
a41c76
controller. This controller will then not allow any hotplug/unplug of
a41c76
devices while the guest is running (and the hotplug capability won't
a41c76
be advertised to the guest OS, so the guest OS also won't present
a41c76
unplugging of PCI devices as an option).
a41c76
a41c76
  <controller type='pci' model='pcie-root-port'>
a41c76
    <target hotplug='off'/>
a41c76
  </controller>
a41c76
a41c76
For any PCI controllers other than pcie-downstream-port and
a41c76
pcie-root-port, of for qemu binaries that don't support the hotplug
a41c76
commandline option, an error will be logged during validation.
a41c76
a41c76
Signed-off-by: Laine Stump <laine@redhat.com>
a41c76
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
a41c76
(cherry picked from commit 2d3cf60328c138f7a8fd5905eb345d5f48227ff8)
a41c76
a41c76
Conflicts:
a41c76
   src/qemu/qemu_domain.c:
a41c76
a41c76
     This file was modified in lieu of modifying qemu_validate.c
a41c76
     upstream - that file has been added upstream (and device
a41c76
     post-parse validation functions moved there) but not downstream.
a41c76
a41c76
   tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args:
a41c76
a41c76
     These files had CPU model info upstream, but not downstream. Is
a41c76
     this due to the plain "q35" machinetype data missing from the
a41c76
     caps.replies file? Need to check...
a41c76
a41c76
https://bugzilla.redhat.com/1802592
a41c76
Signed-off-by: Laine Stump <laine@redhat.com>
a41c76
Message-Id: <20200426170415.18328-6-laine@redhat.com>
a41c76
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_command.c                       |  4 ++
a41c76
 src/qemu/qemu_domain.c                        | 31 +++++++++++++
a41c76
 ...cie-root-port-nohotplug.x86_64-latest.args | 45 +++++++++++++++++++
a41c76
 tests/qemuxml2argvtest.c                      |  1 +
a41c76
 4 files changed, 81 insertions(+)
a41c76
 create mode 100644 tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args
a41c76
a41c76
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
a41c76
index 4653e6ac3c..ed5f60e82e 100644
a41c76
--- a/src/qemu/qemu_command.c
a41c76
+++ b/src/qemu/qemu_command.c
a41c76
@@ -3023,6 +3023,10 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
a41c76
             virBufferAsprintf(&buf, "%s,port=0x%x,chassis=%d,id=%s",
a41c76
                               modelName, pciopts->port,
a41c76
                               pciopts->chassis, def->info.alias);
a41c76
+            if (pciopts->hotplug != VIR_TRISTATE_SWITCH_ABSENT) {
a41c76
+                virBufferAsprintf(&buf, ",hotplug=%s",
a41c76
+                                  virTristateSwitchTypeToString(pciopts->hotplug));
a41c76
+            }
a41c76
             break;
a41c76
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
a41c76
             virBufferAsprintf(&buf, "%s,index=%d,id=%s",
a41c76
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
a41c76
index 8f746cdf13..1509e41021 100644
a41c76
--- a/src/qemu/qemu_domain.c
a41c76
+++ b/src/qemu/qemu_domain.c
a41c76
@@ -7932,6 +7932,37 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont,
a41c76
         virReportEnumRangeError(virDomainControllerModelPCI, cont->model);
a41c76
     }
a41c76
 
a41c76
+    /* hotplug */
a41c76
+    if (pciopts->hotplug != VIR_TRISTATE_SWITCH_ABSENT) {
a41c76
+        switch ((virDomainControllerModelPCI) cont->model) {
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
a41c76
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG)) {
a41c76
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
a41c76
+                               _("setting the hotplug property on a '%s' device is not supported by this QEMU binary"),
a41c76
+                               modelName);
a41c76
+                return -1;
a41c76
+            }
a41c76
+            break;
a41c76
+
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE:
a41c76
+            virReportControllerInvalidOption(cont, model, modelName, "hotplug");
a41c76
+            return -1;
a41c76
+
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT:
a41c76
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
a41c76
+        default:
a41c76
+            virReportEnumRangeError(virDomainControllerModelPCI, cont->model);
a41c76
+        }
a41c76
+    }
a41c76
+
a41c76
     /* QEMU device availability */
a41c76
     if (cap < 0) {
a41c76
         virReportError(VIR_ERR_INTERNAL_ERROR,
a41c76
diff --git a/tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args b/tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args
a41c76
new file mode 100644
a41c76
index 0000000000..73885eec24
a41c76
--- /dev/null
a41c76
+++ b/tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args
a41c76
@@ -0,0 +1,45 @@
a41c76
+LC_ALL=C \
a41c76
+PATH=/bin \
a41c76
+HOME=/tmp/lib/domain--1-guest \
a41c76
+USER=test \
a41c76
+LOGNAME=test \
a41c76
+XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
a41c76
+XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
a41c76
+XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
a41c76
+QEMU_AUDIO_DRV=none \
a41c76
+/usr/bin/qemu-system-x86_64 \
a41c76
+-name guest=guest,debug-threads=on \
a41c76
+-S \
a41c76
+-object secret,id=masterKey0,format=raw,\
a41c76
+file=/tmp/lib/domain--1-guest/master-key.aes \
a41c76
+-machine q35,accel=tcg,usb=off,dump-guest-core=off \
a41c76
+-m 2048 \
a41c76
+-overcommit mem-lock=off \
a41c76
+-smp 2,sockets=2,cores=1,threads=1 \
a41c76
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
a41c76
+-display none \
a41c76
+-no-user-config \
a41c76
+-nodefaults \
a41c76
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
a41c76
+-mon chardev=charmonitor,id=monitor,mode=control \
a41c76
+-rtc base=utc \
a41c76
+-no-shutdown \
a41c76
+-no-acpi \
a41c76
+-boot strict=on \
a41c76
+-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
a41c76
+addr=0x1 \
a41c76
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,hotplug=off,bus=pcie.0,\
a41c76
+addr=0x1.0x1 \
a41c76
+-device ioh3420,port=0xa,chassis=3,id=pci.3,hotplug=off,bus=pcie.0,\
a41c76
+addr=0x1.0x2 \
a41c76
+-device x3130-upstream,id=pci.4,bus=pci.1,addr=0x0 \
a41c76
+-device xio3130-downstream,port=0x0,chassis=5,id=pci.5,hotplug=off,bus=pci.4,\
a41c76
+addr=0x0 \
a41c76
+-device xio3130-downstream,port=0x1,chassis=6,id=pci.6,hotplug=on,bus=pci.4,\
a41c76
+addr=0x1 \
a41c76
+-device xio3130-downstream,port=0x2,chassis=7,id=pci.7,bus=pci.4,addr=0x2 \
a41c76
+-device xio3130-downstream,port=0x27,chassis=30,id=pci.8,bus=pci.4,addr=0x3 \
a41c76
+-device qemu-xhci,id=usb,bus=pci.2,addr=0x0 \
a41c76
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
a41c76
+resourcecontrol=deny \
a41c76
+-msg timestamp=on
a41c76
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
a41c76
index d6c5f436ae..ff92af606d 100644
a41c76
--- a/tests/qemuxml2argvtest.c
a41c76
+++ b/tests/qemuxml2argvtest.c
a41c76
@@ -2427,6 +2427,7 @@ mymain(void)
a41c76
             QEMU_CAPS_DEVICE_IOH3420);
a41c76
     DO_TEST("pcie-root-port-model-ioh3420",
a41c76
             QEMU_CAPS_DEVICE_IOH3420);
a41c76
+    DO_TEST_CAPS_LATEST("pcie-root-port-nohotplug");
a41c76
 
a41c76
     DO_TEST("autoindex",
a41c76
             QEMU_CAPS_DEVICE_PCI_BRIDGE,
a41c76
-- 
a41c76
2.26.2
a41c76