diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index e2f66b982c..83c1405c17 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -4153,6 +4153,12 @@ generated by libvirt. :since:`Since 1.2.19 (QEMU only)`.
``index``
pci-root controllers for pSeries guests use this attribute to record the
order they will show up in the guest. :since:`Since 3.6.0`
+``memReserve``
+ Some PCI devices have non-prefetchable memory bar larger than 2MiB. Use this
+ attribute to override value computed by firmware and thus make controller
+ reserve more memory (in KiB) so that such PCI device can be hot plugged.
+ For cold plugged PCI devices, the firmware will automatically reserve the
+ correct amount of memory. :since:`Since 10.3.0`
For machine types which provide an implicit PCI bus, the pci-root controller
with index=0 is auto-added and required to use PCI devices. pci-root has no
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 48c5d546da..a0912062ff 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8528,6 +8528,11 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt,
&def->opts.pciopts.targetIndex,
def->opts.pciopts.targetIndex) < 0)
return NULL;
+
+ if (virXMLPropULongLong(targetNodes[0], "memReserve", 0,
+ VIR_XML_PROP_NONZERO,
+ &def->opts.pciopts.memReserve) < 0)
+ return NULL;
}
}
@@ -23095,6 +23100,10 @@ virDomainControllerDefFormatPCI(virBuffer *buf,
virBufferAsprintf(&targetAttrBuf, " hotplug='%s'",
virTristateSwitchTypeToString(def->opts.pciopts.hotplug));
}
+ if (def->opts.pciopts.memReserve) {
+ virBufferAsprintf(&targetAttrBuf, " memReserve='%llu'",
+ def->opts.pciopts.memReserve);
+ }
if (def->opts.pciopts.numaNode != -1)
virBufferAsprintf(&targetChildBuf, "%d\n", def->opts.pciopts.numaNode);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5925faaf1a..356c25405b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -738,6 +738,9 @@ struct _virDomainPCIControllerOpts {
*/
int numaNode;
virTristateSwitch hotplug; /* 'off' to prevent hotplug/unplug, default 'on' */
+
+ unsigned long long memReserve; /* used by pci-bridge and pcie-root-port,
+ 0 == undef, KiB */
};
struct _virDomainUSBControllerOpts {
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index f386e46fae..d84e030255 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -2897,6 +2897,11 @@
+
+
+
+
+
diff --git a/tests/qemuxmlconfdata/q35-usb2.x86_64-latest.xml b/tests/qemuxmlconfdata/q35-usb2.x86_64-latest.xml
index b860ae2dee..2bbbbfe346 100644
--- a/tests/qemuxmlconfdata/q35-usb2.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/q35-usb2.x86_64-latest.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/tests/qemuxmlconfdata/q35-usb2.xml b/tests/qemuxmlconfdata/q35-usb2.xml
index 571782a17c..4f5a5580ac 100644
--- a/tests/qemuxmlconfdata/q35-usb2.xml
+++ b/tests/qemuxmlconfdata/q35-usb2.xml
@@ -25,7 +25,7 @@
-
+