From c9d4140df5d22a1bfc895eb1049cc714eaadc86c Mon Sep 17 00:00:00 2001 Message-Id: From: Laine Stump 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 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). 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 Reviewed-by: Michal Privoznik (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 Message-Id: <20200426170415.18328-6-laine@redhat.com> Reviewed-by: Michal Privoznik --- 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