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