]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: introduce support for acpi-bridge-hotplug feature
authorAni Sinha <ani@anisinha.ca>
Fri, 8 Oct 2021 06:42:13 +0000 (12:12 +0530)
committerLaine Stump <laine@redhat.com>
Sun, 10 Oct 2021 17:13:45 +0000 (13:13 -0400)
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 the QEMU driver, for x86 guests
only. It is a global option, affecting all PCI bridge controllers on
the guest.

The 'acpi-bridge-hotplug' option enables or disables ACPI hotplug
support for cold-plugged pci bridges. Examples of bridges include the
PCI-PCI bridge (pci-bridge controller) for pc (i440fx) machinetypes,
or PCIe-PCI bridges and pcie-root-port controllers for q35
machinetypes.

For pc machinetypes in x86, this option has been available in QEMU
since 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 machinetypes, 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>
Reviewed-by: Laine Stump <laine@redhat.com>
15 files changed:
docs/formatdomain.rst
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_validate.c
tests/qemuxml2argvdata/aarch64-acpi-hotplug-bridge-disable.xml [new file with mode: 0644]
tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-disable.xml [new file with mode: 0644]
tests/qemuxml2argvdata/pc-i440fx-acpi-hotplug-bridge-enable.xml [new file with mode: 0644]
tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-disable.xml [new file with mode: 0644]
tests/qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-disable.xml [new symlink]
tests/qemuxml2xmloutdata/pc-i440fx-acpi-hotplug-bridge-enable.xml [new symlink]
tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-disable.xml [new symlink]
tests/qemuxml2xmloutdata/q35-acpi-hotplug-bridge-enable.xml [new symlink]
tests/qemuxml2xmltest.c

index a02802a954f9e33cf4de461ee7058f7d50303672..80aaf4b0339c3e3619abbaacf167c100165090b6 100644 (file)
@@ -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,32 @@ 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) (also see notes) on, off :since:`7.9.0`
+   ==================== ========================================================================================================= ======= ==============
+
+   Note: pc machine types (i440fx) have ACPI hotplug enabled by
+   default on cold plugged bridges (bridges that were present in the
+   VM's domain definition before it was started).  Disabling ACPI
+   hotplug leaves only SHPC hotplug enabled; many OSes don't
+   support SHPC hotplug, so this may have the effect of completely
+   disabling hotplug.
+
+   On q35 machinetypes earlier than pc-q35-6.1 (regardless of the QEMU
+   binary version), ACPI hotplug for cold plugged bridges is disabled
+   by default, and native PCIe hotplug is enabled instead. Enabling
+   ACPI hotplug will disable native PCIe hotplug.
+
+   Starting with the pc-q35-6.1 machinetype, ACPI hotplug is enabled
+   on cold plugged bridges by default while native PCIe hotplug is
+   disabled. In this case, disabling ACPI hotplug will re-enable PCIe
+   native hotplug.
+
 ``pmu``
    Depending on the ``state`` attribute (values ``on``, ``off``, default ``on``)
    enable or disable the performance monitoring unit for the guest.
index ec5bd9174003c211368407c1c4e3ed1346f04119..6f33d1e774aadd3df67a4b5fb52ce322bb723065 100644 (file)
           <optional>
             <ref name="ioapic"/>
           </optional>
+          <optional>
+            <ref name="pci"/>
+          </optional>
           <optional>
             <ref name="hpt"/>
           </optional>
     </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">
index b8370f69503129aefad88f352ebe90a5e1789189..5e89e65d5fe0889a3d2954341b54ce29be2e8128 100644 (file)
@@ -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_HOTPLUG:
+                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_HOTPLUG:
+                    if (def->pci_features[j] != VIR_TRISTATE_SWITCH_ABSENT)
+                        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;
         }
index c23c233184f38ef6d0510a13cb16334e631f3808..79668d229300f40e7fd7e6a12a583b7210c93b02 100644 (file)
@@ -2044,6 +2044,7 @@ typedef enum {
     VIR_DOMAIN_FEATURE_CFPC,
     VIR_DOMAIN_FEATURE_SBBC,
     VIR_DOMAIN_FEATURE_IBS,
+    VIR_DOMAIN_FEATURE_PCI,
 
     VIR_DOMAIN_FEATURE_LAST
 } virDomainFeature;
@@ -2069,6 +2070,12 @@ typedef enum {
     VIR_DOMAIN_HYPERV_LAST
 } virDomainHyperv;
 
+typedef enum {
+    VIR_DOMAIN_PCI_ACPI_BRIDGE_HOTPLUG = 0,
+
+    VIR_DOMAIN_PCI_LAST
+} virDomainPCI;
+
 typedef enum {
     VIR_DOMAIN_KVM_HIDDEN = 0,
     VIR_DOMAIN_KVM_DEDICATED,
@@ -2801,6 +2808,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];
@@ -3925,6 +3933,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);
index c84508cb64dc069b7c365ec64cdc31d34e3bb099..be609c9d39bc636634cd19669c6b2c44225316d2 100644 (file)
@@ -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_HOTPLUG:
+                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 (file)
index 0000000..0d5f945
--- /dev/null
@@ -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 (file)
index 0000000..4482825
--- /dev/null
@@ -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 (file)
index 0000000..8215ee0
--- /dev/null
@@ -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 (file)
index 0000000..2ef3a72
--- /dev/null
@@ -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 (file)
index 0000000..2e1b31b
--- /dev/null
@@ -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 (symlink)
index 0000000..8154897
--- /dev/null
@@ -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 (symlink)
index 0000000..6b9e549
--- /dev/null
@@ -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 (symlink)
index 0000000..77719b1
--- /dev/null
@@ -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 (symlink)
index 0000000..3cd8ee5
--- /dev/null
@@ -0,0 +1 @@
+../qemuxml2argvdata/q35-acpi-hotplug-bridge-enable.xml
\ No newline at end of file
index 69363ef85cd133fb5cd20ad671803691f5fa29f9..2e622c002f346b133bc200413a3a2e8ca28c1630 100644 (file)
@@ -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);