render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
Blob Blame History Raw
From c9d4140df5d22a1bfc895eb1049cc714eaadc86c Mon Sep 17 00:00:00 2001
Message-Id: <c9d4140df5d22a1bfc895eb1049cc714eaadc86c@dist-git>
From: Laine Stump <laine@redhat.com>
Date: Sun, 26 Apr 2020 13:04:08 -0400
Subject: [PATCH] qemu: hook up pcie-root-port hotplug='off' option

If a pcie-root-port or pcie-downstream-port has hotplug='off' in its
<target> subelement, and if the qemu binary supports the hotplug=false
option, then it will be added to the commandline for the pcie
controller. This controller will then not allow any hotplug/unplug of
devices while the guest is running (and the hotplug capability won't
be advertised to the guest OS, so the guest OS also won't present
unplugging of PCI devices as an option).

  <controller type='pci' model='pcie-root-port'>
    <target hotplug='off'/>
  </controller>

For any PCI controllers other than pcie-downstream-port and
pcie-root-port, of for qemu binaries that don't support the hotplug
commandline option, an error will be logged during validation.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 2d3cf60328c138f7a8fd5905eb345d5f48227ff8)

Conflicts:
   src/qemu/qemu_domain.c:

     This file was modified in lieu of modifying qemu_validate.c
     upstream - that file has been added upstream (and device
     post-parse validation functions moved there) but not downstream.

   tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args:

     These files had CPU model info upstream, but not downstream. Is
     this due to the plain "q35" machinetype data missing from the
     caps.replies file? Need to check...

https://bugzilla.redhat.com/1802592
Signed-off-by: Laine Stump <laine@redhat.com>
Message-Id: <20200426170415.18328-6-laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
 src/qemu/qemu_command.c                       |  4 ++
 src/qemu/qemu_domain.c                        | 31 +++++++++++++
 ...cie-root-port-nohotplug.x86_64-latest.args | 45 +++++++++++++++++++
 tests/qemuxml2argvtest.c                      |  1 +
 4 files changed, 81 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4653e6ac3c..ed5f60e82e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3023,6 +3023,10 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
             virBufferAsprintf(&buf, "%s,port=0x%x,chassis=%d,id=%s",
                               modelName, pciopts->port,
                               pciopts->chassis, def->info.alias);
+            if (pciopts->hotplug != VIR_TRISTATE_SWITCH_ABSENT) {
+                virBufferAsprintf(&buf, ",hotplug=%s",
+                                  virTristateSwitchTypeToString(pciopts->hotplug));
+            }
             break;
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
             virBufferAsprintf(&buf, "%s,index=%d,id=%s",
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8f746cdf13..1509e41021 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7932,6 +7932,37 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont,
         virReportEnumRangeError(virDomainControllerModelPCI, cont->model);
     }
 
+    /* hotplug */
+    if (pciopts->hotplug != VIR_TRISTATE_SWITCH_ABSENT) {
+        switch ((virDomainControllerModelPCI) cont->model) {
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("setting the hotplug property on a '%s' device is not supported by this QEMU binary"),
+                               modelName);
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
+        case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE:
+            virReportControllerInvalidOption(cont, model, modelName, "hotplug");
+            return -1;
+
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT:
+        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
+        default:
+            virReportEnumRangeError(virDomainControllerModelPCI, cont->model);
+        }
+    }
+
     /* QEMU device availability */
     if (cap < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args b/tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args
new file mode 100644
index 0000000000..73885eec24
--- /dev/null
+++ b/tests/qemuxml2argvdata/pcie-root-port-nohotplug.x86_64-latest.args
@@ -0,0 +1,45 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-guest \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=guest,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-guest/master-key.aes \
+-machine q35,accel=tcg,usb=off,dump-guest-core=off \
+-m 2048 \
+-overcommit mem-lock=off \
+-smp 2,sockets=2,cores=1,threads=1 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
+addr=0x1 \
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,hotplug=off,bus=pcie.0,\
+addr=0x1.0x1 \
+-device ioh3420,port=0xa,chassis=3,id=pci.3,hotplug=off,bus=pcie.0,\
+addr=0x1.0x2 \
+-device x3130-upstream,id=pci.4,bus=pci.1,addr=0x0 \
+-device xio3130-downstream,port=0x0,chassis=5,id=pci.5,hotplug=off,bus=pci.4,\
+addr=0x0 \
+-device xio3130-downstream,port=0x1,chassis=6,id=pci.6,hotplug=on,bus=pci.4,\
+addr=0x1 \
+-device xio3130-downstream,port=0x2,chassis=7,id=pci.7,bus=pci.4,addr=0x2 \
+-device xio3130-downstream,port=0x27,chassis=30,id=pci.8,bus=pci.4,addr=0x3 \
+-device qemu-xhci,id=usb,bus=pci.2,addr=0x0 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index d6c5f436ae..ff92af606d 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2427,6 +2427,7 @@ mymain(void)
             QEMU_CAPS_DEVICE_IOH3420);
     DO_TEST("pcie-root-port-model-ioh3420",
             QEMU_CAPS_DEVICE_IOH3420);
+    DO_TEST_CAPS_LATEST("pcie-root-port-nohotplug");
 
     DO_TEST("autoindex",
             QEMU_CAPS_DEVICE_PCI_BRIDGE,
-- 
2.26.2