This change introduces a new libvirt sub-element <pci> under <features> that
can be used to configure all pci related features.
Currently the only sub-sub element supported by this sub-element is
'acpi-bridge-hotplug' as shown below:
<features>
<pci>
<acpi-bridge-hotplug state='on|off'/>
</pci>
</features>
The above option is only available for qemu driver and that too for x86 guests
only. It is a global option.
'acpi-bridge-hotplug' option enables or disables ACPI hotplug support for
cold-plugged pci bridges. Examples of bridges include PCI-PCI bridge
(pci-bridge controller) or PCIe-PCI bridges for pc machines and
pcie-root-port controller for q35 machines. Being global option, no other
bridge specific option are required. For pc machine type in x86, this option
is available in qemu for a long time, from version 2.1.
Please see the following changes in qemu repo:
9e047b982452c6 ("piix4: add acpi pci hotplug support")
133a2da488062e ("pc: acpi: generate AML only for PCI0 devices if PCI bridge hotplug is disabled")
For q35 machine type, this was introduced in qemu 6.1 with the following
changes in qemu repo:
(a) c0e427d6eb5fef ("hw/acpi/ich9: Enable ACPI PCI hot-plug")
(b) 17858a16950860 ("hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35")
The reasons for enabling ACPI based hotplug for PCIe (q35) based machines (as
opposed to native hotplug) are outlined in (b). There are use cases where users
would still want to use native hotplug. Therefore, this config option
enables users to choose either ACPI based hotplug or native hotplug for bridges
(for example for pcie root port controller in q35 machines).
Qemu capability validation checks have also been added along with related unit
tests to exercise the new conf option.
Signed-off-by: Ani Sinha <ani@anisinha.ca>
---
docs/formatdomain.rst | 11 +++
docs/schemas/domaincommon.rng | 15 ++++
src/conf/domain_conf.c | 89 ++++++++++++++++++-
src/conf/domain_conf.h | 9 ++
src/qemu/qemu_validate.c | 46 ++++++++++
.../aarch64-acpi-hotplug-bridge-disable.xml | 33 +++++++
.../pc-i440fx-acpi-hotplug-bridge-disable.xml | 33 +++++++
.../pc-i440fx-acpi-hotplug-bridge-enable.xml | 33 +++++++
.../q35-acpi-hotplug-bridge-disable.xml | 47 ++++++++++
.../q35-acpi-hotplug-bridge-enable.xml | 47 ++++++++++
.../pc-i440fx-acpi-hotplug-bridge-disable.xml | 1 +
.../pc-i440fx-acpi-hotplug-bridge-enable.xml | 1 +
.../q35-acpi-hotplug-bridge-disable.xml | 1 +
.../q35-acpi-hotplug-bridge-enable.xml | 1 +
tests/qemuxml2xmltest.c | 14 +++
15 files changed, 380 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
create mode 100644 tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
create mode 100644 tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
create mode 100644 tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
create mode 100644 tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
create mode 120000 tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
create mode 120000 tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
create mode 120000 tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
create mode 120000 tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index a02802a954..8d916eefa6 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1847,6 +1847,9 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
<e820_host state='on'/>
<passthrough state='on' mode='share_pt'/>
</xen>
+ <pci>
+ <acpi-bridge-hotplug state="on"/>
+ </pci>
<pvspinlock state='on'/>
<gic version='2'/>
<ioapic driver='qemu'/>
@@ -1942,6 +1945,14 @@ are:
passthrough Enable IOMMU mappings allowing PCI passthrough on, off; mode - optional string sync_pt or share_pt :since:`6.3.0`
=========== ============================================== =================================================== ==============
+``pci``
+ Various PCI bus related features of the hypervisor.
+ ==================== ======================================================================================== ======= ============================
+ Feature Description Value Since
+ ==================== ======================================================================================== ======= ============================
+ acpi-bridge-hotplug Enable ACPI based hotplug on the cold-plugged PCI bridges (pc) and pcie-root-ports (q35) on, off :since:`7.8.0 (QEMU 6.1.0)`
+ ==================== ======================================================================================== ======= ============================
+
``pmu``
Depending on the ``state`` attribute (values ``on``, ``off``, default ``on``)
enable or disable the performance monitoring unit for the guest.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index ec5bd91740..6f33d1e774 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -6169,6 +6169,9 @@
<optional>
<ref name="ioapic"/>
</optional>
+ <optional>
+ <ref name="pci"/>
+ </optional>
<optional>
<ref name="hpt"/>
</optional>
@@ -6400,6 +6403,18 @@
</element>
</define>
+ <define name="pci">
+ <element name="pci">
+ <interleave>
+ <optional>
+ <element name="acpi-bridge-hotplug">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
<define name="ioapic">
<element name="ioapic">
<attribute name="driver">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b8370f6950..229b75fecc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -172,6 +172,7 @@ VIR_ENUM_IMPL(virDomainFeature,
"cfpc",
"sbbc",
"ibs",
+ "pci",
);
VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
@@ -212,6 +213,11 @@ VIR_ENUM_IMPL(virDomainXen,
"passthrough",
);
+VIR_ENUM_IMPL(virDomainPCI,
+ VIR_DOMAIN_PCI_LAST,
+ "acpi-bridge-hotplug",
+);
+
VIR_ENUM_IMPL(virDomainXenPassthroughMode,
VIR_DOMAIN_XEN_PASSTHROUGH_MODE_LAST,
"default",
@@ -17536,6 +17542,36 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
return 0;
}
+static int
+virDomainFeaturesPCIDefParse(virDomainDef *def,
+ xmlNodePtr node)
+{
+ def->features[VIR_DOMAIN_FEATURE_PCI] = VIR_TRISTATE_SWITCH_ON;
+
+ node = xmlFirstElementChild(node);
+ while (node) {
+ int feature;
+ virTristateSwitch value;
+
+ feature = virDomainPCITypeFromString((const char *)node->name);
+ if (feature < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported PCI feature: %s"),
+ node->name);
+ return -1;
+ }
+
+ if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
+ &value) < 0)
+ return -1;
+
+ def->pci_features[feature] = value;
+
+ node = xmlNextElementSibling(node);
+ }
+
+ return 0;
+}
static int
virDomainFeaturesXENDefParse(virDomainDef *def,
@@ -17835,6 +17871,10 @@ virDomainFeaturesDefParse(virDomainDef *def,
break;
}
+ case VIR_DOMAIN_FEATURE_PCI:
+ if (virDomainFeaturesPCIDefParse(def, nodes[i]) < 0)
+ return -1;
+
case VIR_DOMAIN_FEATURE_LAST:
break;
}
@@ -17843,7 +17883,6 @@ virDomainFeaturesDefParse(virDomainDef *def,
return 0;
}
-
static int
virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDef *def)
{
@@ -21521,6 +21560,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_FEATURE_HTM:
case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST:
+ case VIR_DOMAIN_FEATURE_PCI:
if (src->features[i] != dst->features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of feature '%s' differs: "
@@ -21777,6 +21817,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
}
}
+ /* pci */
+ if (src->features[VIR_DOMAIN_FEATURE_PCI] == VIR_TRISTATE_SWITCH_ON) {
+ for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
+ switch ((virDomainPCI) i) {
+ case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
+ if (src->pci_features[i] != dst->pci_features[i]) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("State of PCI feature '%s' differs: "
+ "source: '%s', destination: '%s'"),
+ virDomainPCITypeToString(i),
+ virTristateSwitchTypeToString(src->pci_features[i]),
+ virTristateSwitchTypeToString(dst->pci_features[i]));
+ return false;
+ }
+
+ break;
+
+ case VIR_DOMAIN_PCI_LAST:
+ break;
+ }
+ }
+ }
+
/* smm */
if (src->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
if (src->tseg_specified != dst->tseg_specified) {
@@ -27932,6 +27995,30 @@ virDomainDefFormatFeatures(virBuffer *buf,
virDomainIBSTypeToString(def->features[i]));
break;
+ case VIR_DOMAIN_FEATURE_PCI:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
+ break;
+
+ virBufferAddLit(&childBuf, "<pci>\n");
+ virBufferAdjustIndent(&childBuf, 2);
+ for (j = 0; j < VIR_DOMAIN_PCI_LAST; j++) {
+ switch ((virDomainPCI) j) {
+ case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
+ if (def->pci_features[j])
+ virBufferAsprintf(&childBuf, "<%s state='%s'/>\n",
+ virDomainPCITypeToString(j),
+ virTristateSwitchTypeToString(
+ def->pci_features[j]));
+ break;
+
+ case VIR_DOMAIN_PCI_LAST:
+ break;
+ }
+ }
+ virBufferAdjustIndent(&childBuf, -2);
+ virBufferAddLit(&childBuf, "</pci>\n");
+ break;
+
case VIR_DOMAIN_FEATURE_LAST:
break;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e054c1508e..e9902a473d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2043,6 +2043,7 @@ typedef enum {
VIR_DOMAIN_FEATURE_CFPC,
VIR_DOMAIN_FEATURE_SBBC,
VIR_DOMAIN_FEATURE_IBS,
+ VIR_DOMAIN_FEATURE_PCI,
VIR_DOMAIN_FEATURE_LAST
} virDomainFeature;
@@ -2068,6 +2069,12 @@ typedef enum {
VIR_DOMAIN_HYPERV_LAST
} virDomainHyperv;
+typedef enum {
+ VIR_DOMAIN_PCI_ACPI_BRIDGE_HP = 0,
+
+ VIR_DOMAIN_PCI_LAST
+} virDomainPCI;
+
typedef enum {
VIR_DOMAIN_KVM_HIDDEN = 0,
VIR_DOMAIN_KVM_DEDICATED,
@@ -2800,6 +2807,7 @@ struct _virDomainDef {
int features[VIR_DOMAIN_FEATURE_LAST];
int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
+ int pci_features[VIR_DOMAIN_PCI_LAST];
int kvm_features[VIR_DOMAIN_KVM_LAST];
int msrs_features[VIR_DOMAIN_MSRS_LAST];
int xen_features[VIR_DOMAIN_XEN_LAST];
@@ -3923,6 +3931,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode);
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode);
VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy);
VIR_ENUM_DECL(virDomainHyperv);
+VIR_ENUM_DECL(virDomainPCI);
VIR_ENUM_DECL(virDomainKVM);
VIR_ENUM_DECL(virDomainXen);
VIR_ENUM_DECL(virDomainXenPassthroughMode);
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index c84508cb64..e0e3ca0b10 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -173,6 +173,48 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
return 0;
}
+static int
+qemuValidateDomainDefPCIFeature(const virDomainDef *def,
+ virQEMUCaps *qemuCaps,
+ int feature)
+{
+ size_t i;
+ bool q35Dom = qemuDomainIsQ35(def);
+ bool q35cap = q35Dom && virQEMUCapsGet(qemuCaps,
+ QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
+
+ if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
+ return 0;
+
+ for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
+ if (def->pci_features[i] == VIR_TRISTATE_SWITCH_ABSENT)
+ continue;
+
+ switch ((virDomainPCI) i) {
+ case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
+ if (!ARCH_IS_X86(def->os.arch)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("acpi-bridge-hotplug is not available "
+ "for architecture '%s'"),
+ virArchToString(def->os.arch));
+ return -1;
+ }
+ if (!q35cap &&
+ !virQEMUCapsGet(qemuCaps,
+ QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("acpi-bridge-hotplug is not available "
+ "with this QEMU binary"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_PCI_LAST:
+ break;
+ }
+ }
+ return 0;
+}
static int
qemuValidateDomainDefFeatures(const virDomainDef *def,
@@ -294,6 +336,10 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
}
break;
+ case VIR_DOMAIN_FEATURE_PCI:
+ if (qemuValidateDomainDefPCIFeature(def, qemuCaps, i) < 0)
+ return -1;
+ break;
case VIR_DOMAIN_FEATURE_SMM:
case VIR_DOMAIN_FEATURE_KVM:
case VIR_DOMAIN_FEATURE_XEN:
diff --git a/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
new file mode 100644
index 0000000000..0d5f945bd7
--- /dev/null
+++ b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>i440fx</name>
+ <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <pci>
+ <acpi-bridge-hotplug state='off'/>
+ </pci>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
new file mode 100644
index 0000000000..4482825858
--- /dev/null
+++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>i440fx</name>
+ <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <pci>
+ <acpi-bridge-hotplug state='off'/>
+ </pci>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
new file mode 100644
index 0000000000..8215ee0d50
--- /dev/null
+++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>i440fx</name>
+ <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <pci>
+ <acpi-bridge-hotplug state='on'/>
+ </pci>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
new file mode 100644
index 0000000000..2ef3a7231f
--- /dev/null
+++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
@@ -0,0 +1,47 @@
+<domain type='qemu'>
+ <name>q35</name>
+ <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <pci>
+ <acpi-bridge-hotplug state='off'/>
+ </pci>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='dmi-to-pci-bridge'>
+ <model name='i82801b11-bridge'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
+ </controller>
+ <controller type='pci' index='2' model='pci-bridge'>
+ <model name='pci-bridge'/>
+ <target chassisNr='2'/>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='3' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
new file mode 100644
index 0000000000..2e1b31b0f8
--- /dev/null
+++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
@@ -0,0 +1,47 @@
+<domain type='qemu'>
+ <name>q35</name>
+ <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <pci>
+ <acpi-bridge-hotplug state='on'/>
+ </pci>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='dmi-to-pci-bridge'>
+ <model name='i82801b11-bridge'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
+ </controller>
+ <controller type='pci' index='2' model='pci-bridge'>
+ <model name='pci-bridge'/>
+ <target chassisNr='2'/>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='pci' index='3' model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='3' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
new file mode 120000
index 0000000000..8154897401
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
new file mode 120000
index 0000000000..6b9e5492f8
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
new file mode 120000
index 0000000000..77719b1325
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
new file mode 120000
index 0000000000..3cd8ee569e
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 69363ef85c..2e622c002f 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -428,6 +428,20 @@ mymain(void)
QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
DO_TEST("pc-i440fx-acpi-root-hotplug-enable",
QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
+ DO_TEST("pc-i440fx-acpi-hotplug-bridge-disable",
+ QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
+ DO_TEST("pc-i440fx-acpi-hotplug-bridge-enable",
+ QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
+ DO_TEST("q35-acpi-hotplug-bridge-disable",
+ QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
+ DO_TEST("q35-acpi-hotplug-bridge-enable",
+ QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
DO_TEST("misc-disable-suspends",
QEMU_CAPS_PIIX_DISABLE_S3,
QEMU_CAPS_PIIX_DISABLE_S4);
--
2.25.1
On 10/5/21 1:51 AM, Ani Sinha wrote:
> This change introduces a new libvirt sub-element <pci> under <features> that
> can be used to configure all pci related features.
> Currently the only sub-sub element supported by this sub-element is
> 'acpi-bridge-hotplug' as shown below:
>
> <features>
> <pci>
> <acpi-bridge-hotplug state='on|off'/>
> </pci>
> </features>
I guess this is as good a place as any other. Any other opinions?
>
> The above option is only available for qemu driver and that too for x86 guests
> only. It is a global option.
>
> 'acpi-bridge-hotplug' option enables or disables ACPI hotplug support for
> cold-plugged pci bridges. Examples of bridges include PCI-PCI bridge
> (pci-bridge controller) or PCIe-PCI bridges for pc machines and
> pcie-root-port controller for q35 machines. Being global option, no other
> bridge specific option are required. For pc machine type in x86, this option
> is available in qemu for a long time, from version 2.1.
> Please see the following changes in qemu repo:
>
> 9e047b982452c6 ("piix4: add acpi pci hotplug support")
> 133a2da488062e ("pc: acpi: generate AML only for PCI0 devices if PCI bridge hotplug is disabled")
>
> For q35 machine type, this was introduced in qemu 6.1 with the following
> changes in qemu repo:
>
> (a) c0e427d6eb5fef ("hw/acpi/ich9: Enable ACPI PCI hot-plug")
> (b) 17858a16950860 ("hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35")
>
> The reasons for enabling ACPI based hotplug for PCIe (q35) based machines (as
> opposed to native hotplug) are outlined in (b). There are use cases where users
> would still want to use native hotplug. Therefore, this config option
> enables users to choose either ACPI based hotplug or native hotplug for bridges
> (for example for pcie root port controller in q35 machines).
>
> Qemu capability validation checks have also been added along with related unit
> tests to exercise the new conf option.
>
> Signed-off-by: Ani Sinha <ani@anisinha.ca>
> ---
> docs/formatdomain.rst | 11 +++
> docs/schemas/domaincommon.rng | 15 ++++
> src/conf/domain_conf.c | 89 ++++++++++++++++++-
> src/conf/domain_conf.h | 9 ++
> src/qemu/qemu_validate.c | 46 ++++++++++
> .../aarch64-acpi-hotplug-bridge-disable.xml | 33 +++++++
> .../pc-i440fx-acpi-hotplug-bridge-disable.xml | 33 +++++++
> .../pc-i440fx-acpi-hotplug-bridge-enable.xml | 33 +++++++
> .../q35-acpi-hotplug-bridge-disable.xml | 47 ++++++++++
> .../q35-acpi-hotplug-bridge-enable.xml | 47 ++++++++++
> .../pc-i440fx-acpi-hotplug-bridge-disable.xml | 1 +
> .../pc-i440fx-acpi-hotplug-bridge-enable.xml | 1 +
> .../q35-acpi-hotplug-bridge-disable.xml | 1 +
> .../q35-acpi-hotplug-bridge-enable.xml | 1 +
> tests/qemuxml2xmltest.c | 14 +++
> 15 files changed, 380 insertions(+), 1 deletion(-)
> create mode 100644 tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> create mode 100644 tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> create mode 100644 tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> create mode 100644 tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> create mode 100644 tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> create mode 120000 tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> create mode 120000 tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> create mode 120000 tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> create mode 120000 tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
>
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index a02802a954..8d916eefa6 100644
> --- a/docs/formatdomain.rst
> +++ b/docs/formatdomain.rst
> @@ -1847,6 +1847,9 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
> <e820_host state='on'/>
> <passthrough state='on' mode='share_pt'/>
> </xen>
> + <pci>
> + <acpi-bridge-hotplug state="on"/>
> + </pci>
> <pvspinlock state='on'/>
> <gic version='2'/>
> <ioapic driver='qemu'/>
> @@ -1942,6 +1945,14 @@ are:
> passthrough Enable IOMMU mappings allowing PCI passthrough on, off; mode - optional string sync_pt or share_pt :since:`6.3.0`
> =========== ============================================== =================================================== ==============
>
> +``pci``
> + Various PCI bus related features of the hypervisor.
> + ==================== ======================================================================================== ======= ============================
> + Feature Description Value Since
> + ==================== ======================================================================================== ======= ============================
> + acpi-bridge-hotplug Enable ACPI based hotplug on the cold-plugged PCI bridges (pc) and pcie-root-ports (q35) on, off :since:`7.8.0 (QEMU 6.1.0)`
> + ==================== ======================================================================================== ======= ============================
> +
> ``pmu``
> Depending on the ``state`` attribute (values ``on``, ``off``, default ``on``)
> enable or disable the performance monitoring unit for the guest.
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index ec5bd91740..6f33d1e774 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -6169,6 +6169,9 @@
> <optional>
> <ref name="ioapic"/>
> </optional>
> + <optional>
> + <ref name="pci"/>
> + </optional>
> <optional>
> <ref name="hpt"/>
> </optional>
> @@ -6400,6 +6403,18 @@
> </element>
> </define>
>
> + <define name="pci">
> + <element name="pci">
> + <interleave>
> + <optional>
> + <element name="acpi-bridge-hotplug">
> + <ref name="featurestate"/>
> + </element>
> + </optional>
> + </interleave>
> + </element>
> + </define>
> +
> <define name="ioapic">
> <element name="ioapic">
> <attribute name="driver">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index b8370f6950..229b75fecc 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -172,6 +172,7 @@ VIR_ENUM_IMPL(virDomainFeature,
> "cfpc",
> "sbbc",
> "ibs",
> + "pci",
> );
>
> VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
> @@ -212,6 +213,11 @@ VIR_ENUM_IMPL(virDomainXen,
> "passthrough",
> );
>
> +VIR_ENUM_IMPL(virDomainPCI,
> + VIR_DOMAIN_PCI_LAST,
> + "acpi-bridge-hotplug",
> +);
> +
> VIR_ENUM_IMPL(virDomainXenPassthroughMode,
> VIR_DOMAIN_XEN_PASSTHROUGH_MODE_LAST,
> "default",
> @@ -17536,6 +17542,36 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
> return 0;
> }
>
> +static int
> +virDomainFeaturesPCIDefParse(virDomainDef *def,
> + xmlNodePtr node)
> +{
> + def->features[VIR_DOMAIN_FEATURE_PCI] = VIR_TRISTATE_SWITCH_ON;
> +
> + node = xmlFirstElementChild(node);
> + while (node) {
> + int feature;
> + virTristateSwitch value;
> +
> + feature = virDomainPCITypeFromString((const char *)node->name);
> + if (feature < 0) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("unsupported PCI feature: %s"),
> + node->name);
> + return -1;
> + }
> +
> + if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
> + &value) < 0)
> + return -1;
> +
> + def->pci_features[feature] = value;
> +
> + node = xmlNextElementSibling(node);
> + }
> +
> + return 0;
> +}
Hmm. On one hand, this is adding a new case of manually iterating
through the nodes of an XML document, which I thought we were trying to
get rid of. On the other hand, it was obviously based on the existing
code for the other subelements of the <features> element (which are the
only other remaining uses of xmlFirstElementChild()) so either that code
was purposefully left that way (and not reworked to use all of Tim's
nice helper functions) in order to detect unknown subelements at parse
time (which we usually don't do (and which has always kind of bothered
me)), or there was some issue that required more thought so it was left
as an exercise for later, in which case this new function could be
redone at the same time as the others.
So unless someone else has a problem with it, I'm okay with putting it in.
Reviewed-by: Laine Stump <laine@redhat.com>
(as long as there are no objections to the name of the element in the
XML, and adding a new function that uses the "old" parsing method).
>
> static int
> virDomainFeaturesXENDefParse(virDomainDef *def,
> @@ -17835,6 +17871,10 @@ virDomainFeaturesDefParse(virDomainDef *def,
> break;
> }
>
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (virDomainFeaturesPCIDefParse(def, nodes[i]) < 0)
> + return -1;
> +
> case VIR_DOMAIN_FEATURE_LAST:
> break;
> }
> @@ -17843,7 +17883,6 @@ virDomainFeaturesDefParse(virDomainDef *def,
> return 0;
> }
>
> -
> static int
> virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDef *def)
> {
> @@ -21521,6 +21560,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
> case VIR_DOMAIN_FEATURE_HTM:
> case VIR_DOMAIN_FEATURE_NESTED_HV:
> case VIR_DOMAIN_FEATURE_CCF_ASSIST:
> + case VIR_DOMAIN_FEATURE_PCI:
> if (src->features[i] != dst->features[i]) {
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> _("State of feature '%s' differs: "
> @@ -21777,6 +21817,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
> }
> }
>
> + /* pci */
> + if (src->features[VIR_DOMAIN_FEATURE_PCI] == VIR_TRISTATE_SWITCH_ON) {
> + for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
> + switch ((virDomainPCI) i) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (src->pci_features[i] != dst->pci_features[i]) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("State of PCI feature '%s' differs: "
> + "source: '%s', destination: '%s'"),
> + virDomainPCITypeToString(i),
> + virTristateSwitchTypeToString(src->pci_features[i]),
> + virTristateSwitchTypeToString(dst->pci_features[i]));
> + return false;
> + }
> +
> + break;
> +
> + case VIR_DOMAIN_PCI_LAST:
> + break;
> + }
> + }
> + }
> +
> /* smm */
> if (src->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
> if (src->tseg_specified != dst->tseg_specified) {
> @@ -27932,6 +27995,30 @@ virDomainDefFormatFeatures(virBuffer *buf,
> virDomainIBSTypeToString(def->features[i]));
> break;
>
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
> + break;
> +
> + virBufferAddLit(&childBuf, "<pci>\n");
> + virBufferAdjustIndent(&childBuf, 2);
> + for (j = 0; j < VIR_DOMAIN_PCI_LAST; j++) {
> + switch ((virDomainPCI) j) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (def->pci_features[j])
> + virBufferAsprintf(&childBuf, "<%s state='%s'/>\n",
> + virDomainPCITypeToString(j),
> + virTristateSwitchTypeToString(
> + def->pci_features[j]));
> + break;
> +
> + case VIR_DOMAIN_PCI_LAST:
> + break;
> + }
> + }
> + virBufferAdjustIndent(&childBuf, -2);
> + virBufferAddLit(&childBuf, "</pci>\n");
> + break;
> +
> case VIR_DOMAIN_FEATURE_LAST:
> break;
> }
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index e054c1508e..e9902a473d 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2043,6 +2043,7 @@ typedef enum {
> VIR_DOMAIN_FEATURE_CFPC,
> VIR_DOMAIN_FEATURE_SBBC,
> VIR_DOMAIN_FEATURE_IBS,
> + VIR_DOMAIN_FEATURE_PCI,
>
> VIR_DOMAIN_FEATURE_LAST
> } virDomainFeature;
> @@ -2068,6 +2069,12 @@ typedef enum {
> VIR_DOMAIN_HYPERV_LAST
> } virDomainHyperv;
>
> +typedef enum {
> + VIR_DOMAIN_PCI_ACPI_BRIDGE_HP = 0,
With so many other identifiers being so long and verbose, I think we can
go ahead and call this one VIR_DOMAIN_PCI_ACPI_BRIDGE_HOTPLUG. Assuming
no other problems, I can change this before pushing.
> +
> + VIR_DOMAIN_PCI_LAST
> +} virDomainPCI;
> +
> typedef enum {
> VIR_DOMAIN_KVM_HIDDEN = 0,
> VIR_DOMAIN_KVM_DEDICATED,
> @@ -2800,6 +2807,7 @@ struct _virDomainDef {
> int features[VIR_DOMAIN_FEATURE_LAST];
> int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
> int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
> + int pci_features[VIR_DOMAIN_PCI_LAST];
> int kvm_features[VIR_DOMAIN_KVM_LAST];
> int msrs_features[VIR_DOMAIN_MSRS_LAST];
> int xen_features[VIR_DOMAIN_XEN_LAST];
> @@ -3923,6 +3931,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode);
> VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode);
> VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy);
> VIR_ENUM_DECL(virDomainHyperv);
> +VIR_ENUM_DECL(virDomainPCI);
> VIR_ENUM_DECL(virDomainKVM);
> VIR_ENUM_DECL(virDomainXen);
> VIR_ENUM_DECL(virDomainXenPassthroughMode);
> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> index c84508cb64..e0e3ca0b10 100644
> --- a/src/qemu/qemu_validate.c
> +++ b/src/qemu/qemu_validate.c
> @@ -173,6 +173,48 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
> return 0;
> }
>
> +static int
> +qemuValidateDomainDefPCIFeature(const virDomainDef *def,
> + virQEMUCaps *qemuCaps,
> + int feature)
> +{
> + size_t i;
> + bool q35Dom = qemuDomainIsQ35(def);
> + bool q35cap = q35Dom && virQEMUCapsGet(qemuCaps,
> + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> +
> + if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
> + return 0;
> +
> + for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
> + if (def->pci_features[i] == VIR_TRISTATE_SWITCH_ABSENT)
> + continue;
> +
> + switch ((virDomainPCI) i) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (!ARCH_IS_X86(def->os.arch)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("acpi-bridge-hotplug is not available "
> + "for architecture '%s'"),
> + virArchToString(def->os.arch));
> + return -1;
> + }
> + if (!q35cap &&
> + !virQEMUCapsGet(qemuCaps,
> + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("acpi-bridge-hotplug is not available "
> + "with this QEMU binary"));
> + return -1;
> + }
> + break;
> +
> + case VIR_DOMAIN_PCI_LAST:
> + break;
> + }
> + }
> + return 0;
> +}
>
> static int
> qemuValidateDomainDefFeatures(const virDomainDef *def,
> @@ -294,6 +336,10 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
> }
> break;
>
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (qemuValidateDomainDefPCIFeature(def, qemuCaps, i) < 0)
> + return -1;
> + break;
> case VIR_DOMAIN_FEATURE_SMM:
> case VIR_DOMAIN_FEATURE_KVM:
> case VIR_DOMAIN_FEATURE_XEN:
> diff --git a/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> new file mode 100644
> index 0000000000..0d5f945bd7
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1,33 @@
> +<domain type='qemu'>
> + <name>i440fx</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='aarch64' machine='virt'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='off'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-aarch64</emulator>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> new file mode 100644
> index 0000000000..4482825858
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1,33 @@
> +<domain type='qemu'>
> + <name>i440fx</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='off'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> new file mode 100644
> index 0000000000..8215ee0d50
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1,33 @@
> +<domain type='qemu'>
> + <name>i440fx</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='on'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> new file mode 100644
> index 0000000000..2ef3a7231f
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1,47 @@
> +<domain type='qemu'>
> + <name>q35</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='off'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='sata' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pcie-root'/>
> + <controller type='pci' index='1' model='dmi-to-pci-bridge'>
> + <model name='i82801b11-bridge'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
> + </controller>
> + <controller type='pci' index='2' model='pci-bridge'>
> + <model name='pci-bridge'/>
> + <target chassisNr='2'/>
> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
> + </controller>
> + <controller type='pci' index='3' model='pcie-root-port'>
> + <model name='ioh3420'/>
> + <target chassis='3' port='0x8'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
> + </controller>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> new file mode 100644
> index 0000000000..2e1b31b0f8
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1,47 @@
> +<domain type='qemu'>
> + <name>q35</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='on'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='sata' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pcie-root'/>
> + <controller type='pci' index='1' model='dmi-to-pci-bridge'>
> + <model name='i82801b11-bridge'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
> + </controller>
> + <controller type='pci' index='2' model='pci-bridge'>
> + <model name='pci-bridge'/>
> + <target chassisNr='2'/>
> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
> + </controller>
> + <controller type='pci' index='3' model='pcie-root-port'>
> + <model name='ioh3420'/>
> + <target chassis='3' port='0x8'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
> + </controller>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> new file mode 120000
> index 0000000000..8154897401
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> new file mode 120000
> index 0000000000..6b9e5492f8
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> new file mode 120000
> index 0000000000..77719b1325
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> new file mode 120000
> index 0000000000..3cd8ee569e
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> index 69363ef85c..2e622c002f 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -428,6 +428,20 @@ mymain(void)
> QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
> DO_TEST("pc-i440fx-acpi-root-hotplug-enable",
> QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
> + DO_TEST("pc-i440fx-acpi-hotplug-bridge-disable",
> + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
> + DO_TEST("pc-i440fx-acpi-hotplug-bridge-enable",
> + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
> + DO_TEST("q35-acpi-hotplug-bridge-disable",
> + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> + QEMU_CAPS_DEVICE_IOH3420,
> + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> + DO_TEST("q35-acpi-hotplug-bridge-enable",
> + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> + QEMU_CAPS_DEVICE_IOH3420,
> + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> DO_TEST("misc-disable-suspends",
> QEMU_CAPS_PIIX_DISABLE_S3,
> QEMU_CAPS_PIIX_DISABLE_S4);
>
On 10/7/21 11:12 PM, Laine Stump wrote:
> @@ -27932,6 +27995,30 @@ virDomainDefFormatFeatures(virBuffer *buf,
>
> virDomainIBSTypeToString(def->features[i]));
> break;
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
> + break;
> +
> + virBufferAddLit(&childBuf, "<pci>\n");
> + virBufferAdjustIndent(&childBuf, 2);
> + for (j = 0; j < VIR_DOMAIN_PCI_LAST; j++) {
> + switch ((virDomainPCI) j) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (def->pci_features[j])
Oops, I missed this the first time I went through - this should compare
to VIR_TRISTATE_SWITCH_ABSENT rather than just checking for non-0. It
ends up being the same thing, but you never know - some day someone may
decide to change the values of the VIR_TRISTATE_* enums just for fun...
> + virBufferAsprintf(&childBuf, "<%s state='%s'/>\n",
> + virDomainPCITypeToString(j),
> + virTristateSwitchTypeToString(
> + def->pci_features[j]));
> + break;
On 10/5/21 1:51 AM, Ani Sinha wrote:
> This change introduces a new libvirt sub-element <pci> under <features> that
> can be used to configure all pci related features.
> Currently the only sub-sub element supported by this sub-element is
> 'acpi-bridge-hotplug' as shown below:
>
> <features>
> <pci>
> <acpi-bridge-hotplug state='on|off'/>
> </pci>
> </features>
>
> The above option is only available for qemu driver and that too for x86 guests
> only. It is a global option.
>
> 'acpi-bridge-hotplug' option enables or disables ACPI hotplug support for
> cold-plugged pci bridges. Examples of bridges include PCI-PCI bridge
> (pci-bridge controller) or PCIe-PCI bridges for pc machines and
> pcie-root-port controller for q35 machines. Being global option, no other
> bridge specific option are required. For pc machine type in x86, this option
> is available in qemu for a long time, from version 2.1.
> Please see the following changes in qemu repo:
>
> 9e047b982452c6 ("piix4: add acpi pci hotplug support")
> 133a2da488062e ("pc: acpi: generate AML only for PCI0 devices if PCI bridge hotplug is disabled")
>
> For q35 machine type, this was introduced in qemu 6.1 with the following
> changes in qemu repo:
>
> (a) c0e427d6eb5fef ("hw/acpi/ich9: Enable ACPI PCI hot-plug")
> (b) 17858a16950860 ("hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35")
>
> The reasons for enabling ACPI based hotplug for PCIe (q35) based machines (as
> opposed to native hotplug) are outlined in (b). There are use cases where users
> would still want to use native hotplug. Therefore, this config option
> enables users to choose either ACPI based hotplug or native hotplug for bridges
> (for example for pcie root port controller in q35 machines).
>
> Qemu capability validation checks have also been added along with related unit
> tests to exercise the new conf option.
>
> Signed-off-by: Ani Sinha <ani@anisinha.ca>
> ---
> docs/formatdomain.rst | 11 +++
> docs/schemas/domaincommon.rng | 15 ++++
> src/conf/domain_conf.c | 89 ++++++++++++++++++-
> src/conf/domain_conf.h | 9 ++
> src/qemu/qemu_validate.c | 46 ++++++++++
> .../aarch64-acpi-hotplug-bridge-disable.xml | 33 +++++++
> .../pc-i440fx-acpi-hotplug-bridge-disable.xml | 33 +++++++
> .../pc-i440fx-acpi-hotplug-bridge-enable.xml | 33 +++++++
> .../q35-acpi-hotplug-bridge-disable.xml | 47 ++++++++++
> .../q35-acpi-hotplug-bridge-enable.xml | 47 ++++++++++
> .../pc-i440fx-acpi-hotplug-bridge-disable.xml | 1 +
> .../pc-i440fx-acpi-hotplug-bridge-enable.xml | 1 +
> .../q35-acpi-hotplug-bridge-disable.xml | 1 +
> .../q35-acpi-hotplug-bridge-enable.xml | 1 +
> tests/qemuxml2xmltest.c | 14 +++
> 15 files changed, 380 insertions(+), 1 deletion(-)
> create mode 100644 tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> create mode 100644 tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> create mode 100644 tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> create mode 100644 tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> create mode 100644 tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> create mode 120000 tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> create mode 120000 tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> create mode 120000 tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> create mode 120000 tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
>
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index a02802a954..8d916eefa6 100644
> --- a/docs/formatdomain.rst
> +++ b/docs/formatdomain.rst
> @@ -1847,6 +1847,9 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
> <e820_host state='on'/>
> <passthrough state='on' mode='share_pt'/>
> </xen>
> + <pci>
> + <acpi-bridge-hotplug state="on"/>
> + </pci>
> <pvspinlock state='on'/>
> <gic version='2'/>
> <ioapic driver='qemu'/>
> @@ -1942,6 +1945,14 @@ are:
> passthrough Enable IOMMU mappings allowing PCI passthrough on, off; mode - optional string sync_pt or share_pt :since:`6.3.0`
> =========== ============================================== =================================================== ==============
>
> +``pci``
> + Various PCI bus related features of the hypervisor.
> + ==================== ======================================================================================== ======= ============================
> + Feature Description Value Since
> + ==================== ======================================================================================== ======= ============================
> + acpi-bridge-hotplug Enable ACPI based hotplug on the cold-plugged PCI bridges (pc) and pcie-root-ports (q35) on, off :since:`7.8.0 (QEMU 6.1.0)`
Weren't the qemu properties there in a much earlier version of QEMU?
(Oh, and also it needs to say 7.9.0 instead of 7.8.0)
Somewhere we need to put the extra info that on 440fx machinetypes ACPI
is on by default, and disabling it means that only SHPC hotplug is
available, while on q35 machinetypes, it is off by default until QEMU
6.1.0, and enabling it has the side-effect of disabling native PCIe
hotplug, while disabling (on qemu 6.1.0+) also has the side-effect of
enabling native PCIe hotplug.
> + ==================== ======================================================================================== ======= ============================
> +
> ``pmu``
> Depending on the ``state`` attribute (values ``on``, ``off``, default ``on``)
> enable or disable the performance monitoring unit for the guest.
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index ec5bd91740..6f33d1e774 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -6169,6 +6169,9 @@
> <optional>
> <ref name="ioapic"/>
> </optional>
> + <optional>
> + <ref name="pci"/>
> + </optional>
> <optional>
> <ref name="hpt"/>
> </optional>
> @@ -6400,6 +6403,18 @@
> </element>
> </define>
>
> + <define name="pci">
> + <element name="pci">
> + <interleave>
> + <optional>
> + <element name="acpi-bridge-hotplug">
> + <ref name="featurestate"/>
> + </element>
> + </optional>
> + </interleave>
> + </element>
> + </define>
> +
> <define name="ioapic">
> <element name="ioapic">
> <attribute name="driver">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index b8370f6950..229b75fecc 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -172,6 +172,7 @@ VIR_ENUM_IMPL(virDomainFeature,
> "cfpc",
> "sbbc",
> "ibs",
> + "pci",
> );
>
> VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
> @@ -212,6 +213,11 @@ VIR_ENUM_IMPL(virDomainXen,
> "passthrough",
> );
>
> +VIR_ENUM_IMPL(virDomainPCI,
> + VIR_DOMAIN_PCI_LAST,
> + "acpi-bridge-hotplug",
> +);
> +
> VIR_ENUM_IMPL(virDomainXenPassthroughMode,
> VIR_DOMAIN_XEN_PASSTHROUGH_MODE_LAST,
> "default",
> @@ -17536,6 +17542,36 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
> return 0;
> }
>
> +static int
> +virDomainFeaturesPCIDefParse(virDomainDef *def,
> + xmlNodePtr node)
> +{
> + def->features[VIR_DOMAIN_FEATURE_PCI] = VIR_TRISTATE_SWITCH_ON;
> +
> + node = xmlFirstElementChild(node);
> + while (node) {
> + int feature;
> + virTristateSwitch value;
> +
> + feature = virDomainPCITypeFromString((const char *)node->name);
> + if (feature < 0) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("unsupported PCI feature: %s"),
> + node->name);
> + return -1;
> + }
> +
> + if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
> + &value) < 0)
> + return -1;
> +
> + def->pci_features[feature] = value;
> +
> + node = xmlNextElementSibling(node);
> + }
> +
> + return 0;
> +}
>
> static int
> virDomainFeaturesXENDefParse(virDomainDef *def,
> @@ -17835,6 +17871,10 @@ virDomainFeaturesDefParse(virDomainDef *def,
> break;
> }
>
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (virDomainFeaturesPCIDefParse(def, nodes[i]) < 0)
> + return -1;
> +
> case VIR_DOMAIN_FEATURE_LAST:
> break;
> }
> @@ -17843,7 +17883,6 @@ virDomainFeaturesDefParse(virDomainDef *def,
> return 0;
> }
>
> -
> static int
> virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDef *def)
> {
> @@ -21521,6 +21560,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
> case VIR_DOMAIN_FEATURE_HTM:
> case VIR_DOMAIN_FEATURE_NESTED_HV:
> case VIR_DOMAIN_FEATURE_CCF_ASSIST:
> + case VIR_DOMAIN_FEATURE_PCI:
> if (src->features[i] != dst->features[i]) {
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> _("State of feature '%s' differs: "
> @@ -21777,6 +21817,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
> }
> }
>
> + /* pci */
> + if (src->features[VIR_DOMAIN_FEATURE_PCI] == VIR_TRISTATE_SWITCH_ON) {
> + for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
> + switch ((virDomainPCI) i) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (src->pci_features[i] != dst->pci_features[i]) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("State of PCI feature '%s' differs: "
> + "source: '%s', destination: '%s'"),
> + virDomainPCITypeToString(i),
> + virTristateSwitchTypeToString(src->pci_features[i]),
> + virTristateSwitchTypeToString(dst->pci_features[i]));
> + return false;
> + }
> +
> + break;
> +
> + case VIR_DOMAIN_PCI_LAST:
> + break;
> + }
> + }
> + }
> +
> /* smm */
> if (src->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
> if (src->tseg_specified != dst->tseg_specified) {
> @@ -27932,6 +27995,30 @@ virDomainDefFormatFeatures(virBuffer *buf,
> virDomainIBSTypeToString(def->features[i]));
> break;
>
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
> + break;
> +
> + virBufferAddLit(&childBuf, "<pci>\n");
> + virBufferAdjustIndent(&childBuf, 2);
> + for (j = 0; j < VIR_DOMAIN_PCI_LAST; j++) {
> + switch ((virDomainPCI) j) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (def->pci_features[j])
> + virBufferAsprintf(&childBuf, "<%s state='%s'/>\n",
> + virDomainPCITypeToString(j),
> + virTristateSwitchTypeToString(
> + def->pci_features[j]));
> + break;
> +
> + case VIR_DOMAIN_PCI_LAST:
> + break;
> + }
> + }
> + virBufferAdjustIndent(&childBuf, -2);
> + virBufferAddLit(&childBuf, "</pci>\n");
> + break;
> +
> case VIR_DOMAIN_FEATURE_LAST:
> break;
> }
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index e054c1508e..e9902a473d 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2043,6 +2043,7 @@ typedef enum {
> VIR_DOMAIN_FEATURE_CFPC,
> VIR_DOMAIN_FEATURE_SBBC,
> VIR_DOMAIN_FEATURE_IBS,
> + VIR_DOMAIN_FEATURE_PCI,
>
> VIR_DOMAIN_FEATURE_LAST
> } virDomainFeature;
> @@ -2068,6 +2069,12 @@ typedef enum {
> VIR_DOMAIN_HYPERV_LAST
> } virDomainHyperv;
>
> +typedef enum {
> + VIR_DOMAIN_PCI_ACPI_BRIDGE_HP = 0,
> +
> + VIR_DOMAIN_PCI_LAST
> +} virDomainPCI;
> +
> typedef enum {
> VIR_DOMAIN_KVM_HIDDEN = 0,
> VIR_DOMAIN_KVM_DEDICATED,
> @@ -2800,6 +2807,7 @@ struct _virDomainDef {
> int features[VIR_DOMAIN_FEATURE_LAST];
> int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
> int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
> + int pci_features[VIR_DOMAIN_PCI_LAST];
> int kvm_features[VIR_DOMAIN_KVM_LAST];
> int msrs_features[VIR_DOMAIN_MSRS_LAST];
> int xen_features[VIR_DOMAIN_XEN_LAST];
> @@ -3923,6 +3931,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode);
> VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode);
> VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy);
> VIR_ENUM_DECL(virDomainHyperv);
> +VIR_ENUM_DECL(virDomainPCI);
> VIR_ENUM_DECL(virDomainKVM);
> VIR_ENUM_DECL(virDomainXen);
> VIR_ENUM_DECL(virDomainXenPassthroughMode);
> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> index c84508cb64..e0e3ca0b10 100644
> --- a/src/qemu/qemu_validate.c
> +++ b/src/qemu/qemu_validate.c
> @@ -173,6 +173,48 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
> return 0;
> }
>
> +static int
> +qemuValidateDomainDefPCIFeature(const virDomainDef *def,
> + virQEMUCaps *qemuCaps,
> + int feature)
> +{
> + size_t i;
> + bool q35Dom = qemuDomainIsQ35(def);
> + bool q35cap = q35Dom && virQEMUCapsGet(qemuCaps,
> + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> +
> + if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
> + return 0;
> +
> + for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
> + if (def->pci_features[i] == VIR_TRISTATE_SWITCH_ABSENT)
> + continue;
> +
> + switch ((virDomainPCI) i) {
> + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> + if (!ARCH_IS_X86(def->os.arch)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("acpi-bridge-hotplug is not available "
> + "for architecture '%s'"),
> + virArchToString(def->os.arch));
> + return -1;
> + }
> + if (!q35cap &&
> + !virQEMUCapsGet(qemuCaps,
> + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("acpi-bridge-hotplug is not available "
> + "with this QEMU binary"));
> + return -1;
> + }
> + break;
> +
> + case VIR_DOMAIN_PCI_LAST:
> + break;
> + }
> + }
> + return 0;
> +}
>
> static int
> qemuValidateDomainDefFeatures(const virDomainDef *def,
> @@ -294,6 +336,10 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
> }
> break;
>
> + case VIR_DOMAIN_FEATURE_PCI:
> + if (qemuValidateDomainDefPCIFeature(def, qemuCaps, i) < 0)
> + return -1;
> + break;
> case VIR_DOMAIN_FEATURE_SMM:
> case VIR_DOMAIN_FEATURE_KVM:
> case VIR_DOMAIN_FEATURE_XEN:
> diff --git a/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> new file mode 100644
> index 0000000000..0d5f945bd7
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1,33 @@
> +<domain type='qemu'>
> + <name>i440fx</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='aarch64' machine='virt'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='off'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-aarch64</emulator>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> new file mode 100644
> index 0000000000..4482825858
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1,33 @@
> +<domain type='qemu'>
> + <name>i440fx</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='off'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> new file mode 100644
> index 0000000000..8215ee0d50
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1,33 @@
> +<domain type='qemu'>
> + <name>i440fx</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='on'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='usb' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> new file mode 100644
> index 0000000000..2ef3a7231f
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1,47 @@
> +<domain type='qemu'>
> + <name>q35</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='off'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='sata' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pcie-root'/>
> + <controller type='pci' index='1' model='dmi-to-pci-bridge'>
> + <model name='i82801b11-bridge'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
> + </controller>
> + <controller type='pci' index='2' model='pci-bridge'>
> + <model name='pci-bridge'/>
> + <target chassisNr='2'/>
> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
> + </controller>
> + <controller type='pci' index='3' model='pcie-root-port'>
> + <model name='ioh3420'/>
> + <target chassis='3' port='0x8'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
> + </controller>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> new file mode 100644
> index 0000000000..2e1b31b0f8
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1,47 @@
> +<domain type='qemu'>
> + <name>q35</name>
> + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> + <memory unit='KiB'>1048576</memory>
> + <currentMemory unit='KiB'>1048576</currentMemory>
> + <vcpu placement='static'>1</vcpu>
> + <os>
> + <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
> + <boot dev='network'/>
> + </os>
> + <features>
> + <pci>
> + <acpi-bridge-hotplug state='on'/>
> + </pci>
> + </features>
> + <clock offset='utc'/>
> + <on_poweroff>destroy</on_poweroff>
> + <on_reboot>restart</on_reboot>
> + <on_crash>destroy</on_crash>
> + <devices>
> + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> + <controller type='sata' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
> + </controller>
> + <controller type='pci' index='0' model='pcie-root'/>
> + <controller type='pci' index='1' model='dmi-to-pci-bridge'>
> + <model name='i82801b11-bridge'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
> + </controller>
> + <controller type='pci' index='2' model='pci-bridge'>
> + <model name='pci-bridge'/>
> + <target chassisNr='2'/>
> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
> + </controller>
> + <controller type='pci' index='3' model='pcie-root-port'>
> + <model name='ioh3420'/>
> + <target chassis='3' port='0x8'/>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
> + </controller>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <audio id='1' type='none'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> new file mode 120000
> index 0000000000..8154897401
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> new file mode 120000
> index 0000000000..6b9e5492f8
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> new file mode 120000
> index 0000000000..77719b1325
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> new file mode 120000
> index 0000000000..3cd8ee569e
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> @@ -0,0 +1 @@
> +../qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> \ No newline at end of file
> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> index 69363ef85c..2e622c002f 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -428,6 +428,20 @@ mymain(void)
> QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
> DO_TEST("pc-i440fx-acpi-root-hotplug-enable",
> QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
> + DO_TEST("pc-i440fx-acpi-hotplug-bridge-disable",
> + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
> + DO_TEST("pc-i440fx-acpi-hotplug-bridge-enable",
> + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
> + DO_TEST("q35-acpi-hotplug-bridge-disable",
> + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> + QEMU_CAPS_DEVICE_IOH3420,
> + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> + DO_TEST("q35-acpi-hotplug-bridge-enable",
> + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> + QEMU_CAPS_DEVICE_IOH3420,
> + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> DO_TEST("misc-disable-suspends",
> QEMU_CAPS_PIIX_DISABLE_S3,
> QEMU_CAPS_PIIX_DISABLE_S4);
>
On Fri, 8 Oct 2021, Laine Stump wrote:
> On 10/5/21 1:51 AM, Ani Sinha wrote:
> > This change introduces a new libvirt sub-element <pci> under <features> that
> > can be used to configure all pci related features.
> > Currently the only sub-sub element supported by this sub-element is
> > 'acpi-bridge-hotplug' as shown below:
> >
> > <features>
> > <pci>
> > <acpi-bridge-hotplug state='on|off'/>
> > </pci>
> > </features>
> >
> > The above option is only available for qemu driver and that too for x86
> > guests
> > only. It is a global option.
> >
> > 'acpi-bridge-hotplug' option enables or disables ACPI hotplug support for
> > cold-plugged pci bridges. Examples of bridges include PCI-PCI bridge
> > (pci-bridge controller) or PCIe-PCI bridges for pc machines and
> > pcie-root-port controller for q35 machines. Being global option, no other
> > bridge specific option are required. For pc machine type in x86, this option
> > is available in qemu for a long time, from version 2.1.
> > Please see the following changes in qemu repo:
> >
> > 9e047b982452c6 ("piix4: add acpi pci hotplug support")
> > 133a2da488062e ("pc: acpi: generate AML only for PCI0 devices if PCI bridge
> > hotplug is disabled")
> >
> > For q35 machine type, this was introduced in qemu 6.1 with the following
> > changes in qemu repo:
> >
> > (a) c0e427d6eb5fef ("hw/acpi/ich9: Enable ACPI PCI hot-plug")
> > (b) 17858a16950860 ("hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35")
> >
> > The reasons for enabling ACPI based hotplug for PCIe (q35) based machines
> > (as
> > opposed to native hotplug) are outlined in (b). There are use cases where
> > users
> > would still want to use native hotplug. Therefore, this config option
> > enables users to choose either ACPI based hotplug or native hotplug for
> > bridges
> > (for example for pcie root port controller in q35 machines).
> >
> > Qemu capability validation checks have also been added along with related
> > unit
> > tests to exercise the new conf option.
> >
> > Signed-off-by: Ani Sinha <ani@anisinha.ca>
> > ---
> > docs/formatdomain.rst | 11 +++
> > docs/schemas/domaincommon.rng | 15 ++++
> > src/conf/domain_conf.c | 89 ++++++++++++++++++-
> > src/conf/domain_conf.h | 9 ++
> > src/qemu/qemu_validate.c | 46 ++++++++++
> > .../aarch64-acpi-hotplug-bridge-disable.xml | 33 +++++++
> > .../pc-i440fx-acpi-hotplug-bridge-disable.xml | 33 +++++++
> > .../pc-i440fx-acpi-hotplug-bridge-enable.xml | 33 +++++++
> > .../q35-acpi-hotplug-bridge-disable.xml | 47 ++++++++++
> > .../q35-acpi-hotplug-bridge-enable.xml | 47 ++++++++++
> > .../pc-i440fx-acpi-hotplug-bridge-disable.xml | 1 +
> > .../pc-i440fx-acpi-hotplug-bridge-enable.xml | 1 +
> > .../q35-acpi-hotplug-bridge-disable.xml | 1 +
> > .../q35-acpi-hotplug-bridge-enable.xml | 1 +
> > tests/qemuxml2xmltest.c | 14 +++
> > 15 files changed, 380 insertions(+), 1 deletion(-)
> > create mode 100644
> > tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> > create mode 100644
> > tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > create mode 100644
> > tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > create mode 100644
> > tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> > create mode 100644
> > tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> > create mode 120000
> > tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > create mode 120000
> > tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > create mode 120000
> > tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> > create mode 120000
> > tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> >
> > diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> > index a02802a954..8d916eefa6 100644
> > --- a/docs/formatdomain.rst
> > +++ b/docs/formatdomain.rst
> > @@ -1847,6 +1847,9 @@ Hypervisors may allow certain CPU / machine features
> > to be toggled on/off.
> > <e820_host state='on'/>
> > <passthrough state='on' mode='share_pt'/>
> > </xen>
> > + <pci>
> > + <acpi-bridge-hotplug state="on"/>
> > + </pci>
> > <pvspinlock state='on'/>
> > <gic version='2'/>
> > <ioapic driver='qemu'/>
> > @@ -1942,6 +1945,14 @@ are:
> > passthrough Enable IOMMU mappings allowing PCI passthrough on, off;
> > mode - optional string sync_pt or share_pt :since:`6.3.0`
> > =========== ==============================================
> > =================================================== ==============
> > +``pci``
> > + Various PCI bus related features of the hypervisor.
> > + ====================
> > ========================================================================================
> > ======= ============================
> > + Feature Description
> > Value Since
> > + ====================
> > ========================================================================================
> > ======= ============================
> > + acpi-bridge-hotplug Enable ACPI based hotplug on the cold-plugged PCI
> > bridges (pc) and pcie-root-ports (q35) on, off :since:`7.8.0 (QEMU 6.1.0)`
>
> Weren't the qemu properties there in a much earlier version of QEMU? (Oh, and
> also it needs to say 7.9.0 instead of 7.8.0)
That was for i440fx. I took the higher version.
>
> Somewhere we need to put the extra info that on 440fx machinetypes ACPI is on
> by default, and disabling it means that only SHPC hotplug is available, while
> on q35 machinetypes, it is off by default until QEMU 6.1.0, and enabling it
> has the side-effect of disabling native PCIe hotplug, while disabling (on qemu
> 6.1.0+) also has the side-effect of enabling native PCIe hotplug.
>
I have added a note in v7.
> > + ====================
> > ========================================================================================
> > ======= ============================
> > +
> > ``pmu``
> > Depending on the ``state`` attribute (values ``on``, ``off``, default
> > ``on``)
> > enable or disable the performance monitoring unit for the guest.
> > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> > index ec5bd91740..6f33d1e774 100644
> > --- a/docs/schemas/domaincommon.rng
> > +++ b/docs/schemas/domaincommon.rng
> > @@ -6169,6 +6169,9 @@
> > <optional>
> > <ref name="ioapic"/>
> > </optional>
> > + <optional>
> > + <ref name="pci"/>
> > + </optional>
> > <optional>
> > <ref name="hpt"/>
> > </optional>
> > @@ -6400,6 +6403,18 @@
> > </element>
> > </define>
> > + <define name="pci">
> > + <element name="pci">
> > + <interleave>
> > + <optional>
> > + <element name="acpi-bridge-hotplug">
> > + <ref name="featurestate"/>
> > + </element>
> > + </optional>
> > + </interleave>
> > + </element>
> > + </define>
> > +
> > <define name="ioapic">
> > <element name="ioapic">
> > <attribute name="driver">
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index b8370f6950..229b75fecc 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -172,6 +172,7 @@ VIR_ENUM_IMPL(virDomainFeature,
> > "cfpc",
> > "sbbc",
> > "ibs",
> > + "pci",
> > );
> > VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
> > @@ -212,6 +213,11 @@ VIR_ENUM_IMPL(virDomainXen,
> > "passthrough",
> > );
> > +VIR_ENUM_IMPL(virDomainPCI,
> > + VIR_DOMAIN_PCI_LAST,
> > + "acpi-bridge-hotplug",
> > +);
> > +
> > VIR_ENUM_IMPL(virDomainXenPassthroughMode,
> > VIR_DOMAIN_XEN_PASSTHROUGH_MODE_LAST,
> > "default",
> > @@ -17536,6 +17542,36 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
> > return 0;
> > }
> > +static int
> > +virDomainFeaturesPCIDefParse(virDomainDef *def,
> > + xmlNodePtr node)
> > +{
> > + def->features[VIR_DOMAIN_FEATURE_PCI] = VIR_TRISTATE_SWITCH_ON;
> > +
> > + node = xmlFirstElementChild(node);
> > + while (node) {
> > + int feature;
> > + virTristateSwitch value;
> > +
> > + feature = virDomainPCITypeFromString((const char *)node->name);
> > + if (feature < 0) {
> > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > + _("unsupported PCI feature: %s"),
> > + node->name);
> > + return -1;
> > + }
> > +
> > + if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
> > + &value) < 0)
> > + return -1;
> > +
> > + def->pci_features[feature] = value;
> > +
> > + node = xmlNextElementSibling(node);
> > + }
> > +
> > + return 0;
> > +}
> > static int
> > virDomainFeaturesXENDefParse(virDomainDef *def,
> > @@ -17835,6 +17871,10 @@ virDomainFeaturesDefParse(virDomainDef *def,
> > break;
> > }
> > + case VIR_DOMAIN_FEATURE_PCI:
> > + if (virDomainFeaturesPCIDefParse(def, nodes[i]) < 0)
> > + return -1;
> > +
> > case VIR_DOMAIN_FEATURE_LAST:
> > break;
> > }
> > @@ -17843,7 +17883,6 @@ virDomainFeaturesDefParse(virDomainDef *def,
> > return 0;
> > }
> > -
> > static int
> > virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDef *def)
> > {
> > @@ -21521,6 +21560,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef
> > *src,
> > case VIR_DOMAIN_FEATURE_HTM:
> > case VIR_DOMAIN_FEATURE_NESTED_HV:
> > case VIR_DOMAIN_FEATURE_CCF_ASSIST:
> > + case VIR_DOMAIN_FEATURE_PCI:
> > if (src->features[i] != dst->features[i]) {
> > virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > _("State of feature '%s' differs: "
> > @@ -21777,6 +21817,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDef
> > *src,
> > }
> > }
> > + /* pci */
> > + if (src->features[VIR_DOMAIN_FEATURE_PCI] == VIR_TRISTATE_SWITCH_ON) {
> > + for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
> > + switch ((virDomainPCI) i) {
> > + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> > + if (src->pci_features[i] != dst->pci_features[i]) {
> > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > + _("State of PCI feature '%s' differs: "
> > + "source: '%s', destination: '%s'"),
> > + virDomainPCITypeToString(i),
> > +
> > virTristateSwitchTypeToString(src->pci_features[i]),
> > +
> > virTristateSwitchTypeToString(dst->pci_features[i]));
> > + return false;
> > + }
> > +
> > + break;
> > +
> > + case VIR_DOMAIN_PCI_LAST:
> > + break;
> > + }
> > + }
> > + }
> > +
> > /* smm */
> > if (src->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
> > if (src->tseg_specified != dst->tseg_specified) {
> > @@ -27932,6 +27995,30 @@ virDomainDefFormatFeatures(virBuffer *buf,
> > virDomainIBSTypeToString(def->features[i]));
> > break;
> > + case VIR_DOMAIN_FEATURE_PCI:
> > + if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
> > + break;
> > +
> > + virBufferAddLit(&childBuf, "<pci>\n");
> > + virBufferAdjustIndent(&childBuf, 2);
> > + for (j = 0; j < VIR_DOMAIN_PCI_LAST; j++) {
> > + switch ((virDomainPCI) j) {
> > + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> > + if (def->pci_features[j])
> > + virBufferAsprintf(&childBuf, "<%s state='%s'/>\n",
> > + virDomainPCITypeToString(j),
> > + virTristateSwitchTypeToString(
> > + def->pci_features[j]));
> > + break;
> > +
> > + case VIR_DOMAIN_PCI_LAST:
> > + break;
> > + }
> > + }
> > + virBufferAdjustIndent(&childBuf, -2);
> > + virBufferAddLit(&childBuf, "</pci>\n");
> > + break;
> > +
> > case VIR_DOMAIN_FEATURE_LAST:
> > break;
> > }
> > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> > index e054c1508e..e9902a473d 100644
> > --- a/src/conf/domain_conf.h
> > +++ b/src/conf/domain_conf.h
> > @@ -2043,6 +2043,7 @@ typedef enum {
> > VIR_DOMAIN_FEATURE_CFPC,
> > VIR_DOMAIN_FEATURE_SBBC,
> > VIR_DOMAIN_FEATURE_IBS,
> > + VIR_DOMAIN_FEATURE_PCI,
> > VIR_DOMAIN_FEATURE_LAST
> > } virDomainFeature;
> > @@ -2068,6 +2069,12 @@ typedef enum {
> > VIR_DOMAIN_HYPERV_LAST
> > } virDomainHyperv;
> > +typedef enum {
> > + VIR_DOMAIN_PCI_ACPI_BRIDGE_HP = 0,
> > +
> > + VIR_DOMAIN_PCI_LAST
> > +} virDomainPCI;
> > +
> > typedef enum {
> > VIR_DOMAIN_KVM_HIDDEN = 0,
> > VIR_DOMAIN_KVM_DEDICATED,
> > @@ -2800,6 +2807,7 @@ struct _virDomainDef {
> > int features[VIR_DOMAIN_FEATURE_LAST];
> > int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
> > int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
> > + int pci_features[VIR_DOMAIN_PCI_LAST];
> > int kvm_features[VIR_DOMAIN_KVM_LAST];
> > int msrs_features[VIR_DOMAIN_MSRS_LAST];
> > int xen_features[VIR_DOMAIN_XEN_LAST];
> > @@ -3923,6 +3931,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode);
> > VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode);
> > VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy);
> > VIR_ENUM_DECL(virDomainHyperv);
> > +VIR_ENUM_DECL(virDomainPCI);
> > VIR_ENUM_DECL(virDomainKVM);
> > VIR_ENUM_DECL(virDomainXen);
> > VIR_ENUM_DECL(virDomainXenPassthroughMode);
> > diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> > index c84508cb64..e0e3ca0b10 100644
> > --- a/src/qemu/qemu_validate.c
> > +++ b/src/qemu/qemu_validate.c
> > @@ -173,6 +173,48 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef
> > *def,
> > return 0;
> > }
> > +static int
> > +qemuValidateDomainDefPCIFeature(const virDomainDef *def,
> > + virQEMUCaps *qemuCaps,
> > + int feature)
> > +{
> > + size_t i;
> > + bool q35Dom = qemuDomainIsQ35(def);
> > + bool q35cap = q35Dom && virQEMUCapsGet(qemuCaps,
> > +
> > QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> > +
> > + if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
> > + return 0;
> > +
> > + for (i = 0; i < VIR_DOMAIN_PCI_LAST; i++) {
> > + if (def->pci_features[i] == VIR_TRISTATE_SWITCH_ABSENT)
> > + continue;
> > +
> > + switch ((virDomainPCI) i) {
> > + case VIR_DOMAIN_PCI_ACPI_BRIDGE_HP:
> > + if (!ARCH_IS_X86(def->os.arch)) {
> > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > + _("acpi-bridge-hotplug is not available
> > "
> > + "for architecture '%s'"),
> > + virArchToString(def->os.arch));
> > + return -1;
> > + }
> > + if (!q35cap &&
> > + !virQEMUCapsGet(qemuCaps,
> > + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE)) {
> > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> > + _("acpi-bridge-hotplug is not available
> > "
> > + "with this QEMU binary"));
> > + return -1;
> > + }
> > + break;
> > +
> > + case VIR_DOMAIN_PCI_LAST:
> > + break;
> > + }
> > + }
> > + return 0;
> > +}
> > static int
> > qemuValidateDomainDefFeatures(const virDomainDef *def,
> > @@ -294,6 +336,10 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
> > }
> > break;
> > + case VIR_DOMAIN_FEATURE_PCI:
> > + if (qemuValidateDomainDefPCIFeature(def, qemuCaps, i) < 0)
> > + return -1;
> > + break;
> > case VIR_DOMAIN_FEATURE_SMM:
> > case VIR_DOMAIN_FEATURE_KVM:
> > case VIR_DOMAIN_FEATURE_XEN:
> > diff --git a/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> > b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> > new file mode 100644
> > index 0000000000..0d5f945bd7
> > --- /dev/null
> > +++ b/tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml
> > @@ -0,0 +1,33 @@
> > +<domain type='qemu'>
> > + <name>i440fx</name>
> > + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> > + <memory unit='KiB'>1048576</memory>
> > + <currentMemory unit='KiB'>1048576</currentMemory>
> > + <vcpu placement='static'>1</vcpu>
> > + <os>
> > + <type arch='aarch64' machine='virt'>hvm</type>
> > + <boot dev='network'/>
> > + </os>
> > + <features>
> > + <pci>
> > + <acpi-bridge-hotplug state='off'/>
> > + </pci>
> > + </features>
> > + <clock offset='utc'/>
> > + <on_poweroff>destroy</on_poweroff>
> > + <on_reboot>restart</on_reboot>
> > + <on_crash>destroy</on_crash>
> > + <devices>
> > + <emulator>/usr/bin/qemu-system-aarch64</emulator>
> > + <controller type='usb' index='0'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> > function='0x2'/>
> > + </controller>
> > + <controller type='pci' index='0' model='pci-root'/>
> > + <input type='mouse' bus='ps2'/>
> > + <input type='keyboard' bus='ps2'/>
> > + <audio id='1' type='none'/>
> > + <memballoon model='virtio'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x02'
> > function='0x0'/>
> > + </memballoon>
> > + </devices>
> > +</domain>
> > diff --git
> > a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > new file mode 100644
> > index 0000000000..4482825858
> > --- /dev/null
> > +++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > @@ -0,0 +1,33 @@
> > +<domain type='qemu'>
> > + <name>i440fx</name>
> > + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> > + <memory unit='KiB'>1048576</memory>
> > + <currentMemory unit='KiB'>1048576</currentMemory>
> > + <vcpu placement='static'>1</vcpu>
> > + <os>
> > + <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
> > + <boot dev='network'/>
> > + </os>
> > + <features>
> > + <pci>
> > + <acpi-bridge-hotplug state='off'/>
> > + </pci>
> > + </features>
> > + <clock offset='utc'/>
> > + <on_poweroff>destroy</on_poweroff>
> > + <on_reboot>restart</on_reboot>
> > + <on_crash>destroy</on_crash>
> > + <devices>
> > + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> > + <controller type='usb' index='0'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> > function='0x2'/>
> > + </controller>
> > + <controller type='pci' index='0' model='pci-root'/>
> > + <input type='mouse' bus='ps2'/>
> > + <input type='keyboard' bus='ps2'/>
> > + <audio id='1' type='none'/>
> > + <memballoon model='virtio'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x02'
> > function='0x0'/>
> > + </memballoon>
> > + </devices>
> > +</domain>
> > diff --git a/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > new file mode 100644
> > index 0000000000..8215ee0d50
> > --- /dev/null
> > +++ b/tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > @@ -0,0 +1,33 @@
> > +<domain type='qemu'>
> > + <name>i440fx</name>
> > + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> > + <memory unit='KiB'>1048576</memory>
> > + <currentMemory unit='KiB'>1048576</currentMemory>
> > + <vcpu placement='static'>1</vcpu>
> > + <os>
> > + <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
> > + <boot dev='network'/>
> > + </os>
> > + <features>
> > + <pci>
> > + <acpi-bridge-hotplug state='on'/>
> > + </pci>
> > + </features>
> > + <clock offset='utc'/>
> > + <on_poweroff>destroy</on_poweroff>
> > + <on_reboot>restart</on_reboot>
> > + <on_crash>destroy</on_crash>
> > + <devices>
> > + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> > + <controller type='usb' index='0'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> > function='0x2'/>
> > + </controller>
> > + <controller type='pci' index='0' model='pci-root'/>
> > + <input type='mouse' bus='ps2'/>
> > + <input type='keyboard' bus='ps2'/>
> > + <audio id='1' type='none'/>
> > + <memballoon model='virtio'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x02'
> > function='0x0'/>
> > + </memballoon>
> > + </devices>
> > +</domain>
> > diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> > b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> > new file mode 100644
> > index 0000000000..2ef3a7231f
> > --- /dev/null
> > +++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> > @@ -0,0 +1,47 @@
> > +<domain type='qemu'>
> > + <name>q35</name>
> > + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> > + <memory unit='KiB'>1048576</memory>
> > + <currentMemory unit='KiB'>1048576</currentMemory>
> > + <vcpu placement='static'>1</vcpu>
> > + <os>
> > + <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
> > + <boot dev='network'/>
> > + </os>
> > + <features>
> > + <pci>
> > + <acpi-bridge-hotplug state='off'/>
> > + </pci>
> > + </features>
> > + <clock offset='utc'/>
> > + <on_poweroff>destroy</on_poweroff>
> > + <on_reboot>restart</on_reboot>
> > + <on_crash>destroy</on_crash>
> > + <devices>
> > + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> > + <controller type='sata' index='0'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f'
> > function='0x2'/>
> > + </controller>
> > + <controller type='pci' index='0' model='pcie-root'/>
> > + <controller type='pci' index='1' model='dmi-to-pci-bridge'>
> > + <model name='i82801b11-bridge'/>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e'
> > function='0x0'/>
> > + </controller>
> > + <controller type='pci' index='2' model='pci-bridge'>
> > + <model name='pci-bridge'/>
> > + <target chassisNr='2'/>
> > + <address type='pci' domain='0x0000' bus='0x01' slot='0x00'
> > function='0x0'/>
> > + </controller>
> > + <controller type='pci' index='3' model='pcie-root-port'>
> > + <model name='ioh3420'/>
> > + <target chassis='3' port='0x8'/>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> > function='0x0'/>
> > + </controller>
> > + <input type='mouse' bus='ps2'/>
> > + <input type='keyboard' bus='ps2'/>
> > + <audio id='1' type='none'/>
> > + <memballoon model='virtio'>
> > + <address type='pci' domain='0x0000' bus='0x02' slot='0x01'
> > function='0x0'/>
> > + </memballoon>
> > + </devices>
> > +</domain>
> > diff --git a/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> > b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> > new file mode 100644
> > index 0000000000..2e1b31b0f8
> > --- /dev/null
> > +++ b/tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> > @@ -0,0 +1,47 @@
> > +<domain type='qemu'>
> > + <name>q35</name>
> > + <uuid>56f5055c-1b8d-490c-844a-ad646a1caaaa</uuid>
> > + <memory unit='KiB'>1048576</memory>
> > + <currentMemory unit='KiB'>1048576</currentMemory>
> > + <vcpu placement='static'>1</vcpu>
> > + <os>
> > + <type arch='x86_64' machine='pc-q35-2.5'>hvm</type>
> > + <boot dev='network'/>
> > + </os>
> > + <features>
> > + <pci>
> > + <acpi-bridge-hotplug state='on'/>
> > + </pci>
> > + </features>
> > + <clock offset='utc'/>
> > + <on_poweroff>destroy</on_poweroff>
> > + <on_reboot>restart</on_reboot>
> > + <on_crash>destroy</on_crash>
> > + <devices>
> > + <emulator>/usr/bin/qemu-system-x86_64</emulator>
> > + <controller type='sata' index='0'>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f'
> > function='0x2'/>
> > + </controller>
> > + <controller type='pci' index='0' model='pcie-root'/>
> > + <controller type='pci' index='1' model='dmi-to-pci-bridge'>
> > + <model name='i82801b11-bridge'/>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e'
> > function='0x0'/>
> > + </controller>
> > + <controller type='pci' index='2' model='pci-bridge'>
> > + <model name='pci-bridge'/>
> > + <target chassisNr='2'/>
> > + <address type='pci' domain='0x0000' bus='0x01' slot='0x00'
> > function='0x0'/>
> > + </controller>
> > + <controller type='pci' index='3' model='pcie-root-port'>
> > + <model name='ioh3420'/>
> > + <target chassis='3' port='0x8'/>
> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> > function='0x0'/>
> > + </controller>
> > + <input type='mouse' bus='ps2'/>
> > + <input type='keyboard' bus='ps2'/>
> > + <audio id='1' type='none'/>
> > + <memballoon model='virtio'>
> > + <address type='pci' domain='0x0000' bus='0x02' slot='0x01'
> > function='0x0'/>
> > + </memballoon>
> > + </devices>
> > +</domain>
> > diff --git
> > a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > new file mode 120000
> > index 0000000000..8154897401
> > --- /dev/null
> > +++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > @@ -0,0 +1 @@
> > +../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml
> > \ No newline at end of file
> > diff --git
> > a/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > new file mode 120000
> > index 0000000000..6b9e5492f8
> > --- /dev/null
> > +++ b/tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > @@ -0,0 +1 @@
> > +../qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml
> > \ No newline at end of file
> > diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> > b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> > new file mode 120000
> > index 0000000000..77719b1325
> > --- /dev/null
> > +++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml
> > @@ -0,0 +1 @@
> > +../qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml
> > \ No newline at end of file
> > diff --git a/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> > b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> > new file mode 120000
> > index 0000000000..3cd8ee569e
> > --- /dev/null
> > +++ b/tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml
> > @@ -0,0 +1 @@
> > +../qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
> > \ No newline at end of file
> > diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> > index 69363ef85c..2e622c002f 100644
> > --- a/tests/qemuxml2xmltest.c
> > +++ b/tests/qemuxml2xmltest.c
> > @@ -428,6 +428,20 @@ mymain(void)
> > QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
> > DO_TEST("pc-i440fx-acpi-root-hotplug-enable",
> > QEMU_CAPS_PIIX4_ACPI_ROOT_PCI_HOTPLUG);
> > + DO_TEST("pc-i440fx-acpi-hotplug-bridge-disable",
> > + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
> > + DO_TEST("pc-i440fx-acpi-hotplug-bridge-enable",
> > + QEMU_CAPS_PIIX4_ACPI_HOTPLUG_BRIDGE);
> > + DO_TEST("q35-acpi-hotplug-bridge-disable",
> > + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> > + QEMU_CAPS_DEVICE_IOH3420,
> > + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> > + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> > + DO_TEST("q35-acpi-hotplug-bridge-enable",
> > + QEMU_CAPS_DEVICE_PCI_BRIDGE,
> > + QEMU_CAPS_DEVICE_IOH3420,
> > + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
> > + QEMU_CAPS_ICH9_ACPI_HOTPLUG_BRIDGE);
> > DO_TEST("misc-disable-suspends",
> > QEMU_CAPS_PIIX_DISABLE_S3,
> > QEMU_CAPS_PIIX_DISABLE_S4);
> >
>
>
© 2016 - 2026 Red Hat, Inc.