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