diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 7f057ec87d..cce179d12b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2465,6 +2465,15 @@
PCI controllers have an optional model
attribute with
possible values pci-root
, pcie-root
,
pci-bridge
, or dmi-to-pci-bridge
.
+ The root controllers (pci-root
and pcie-root
)
+ have an optional pcihole64
element specifying how big
+ (in kilobytes, or in the unit specified by pcihole64
's
+ unit
attribute) the 64-bit PCI hole should be. Some guests (like
+ Windows XP or Windows Server 2003) might crash when QEMU and Seabios
+ are recent enough to support 64-bit PCI holes, unless this is disabled
+ (set to 0). Since 1.1.2 (QEMU only)
+
+
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 address.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3df61f696a..6978dc74d3 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1544,14 +1544,30 @@
pci
-
-
- pci-root
- pcie-root
- pci-bridge
- dmi-to-pci-bridge
-
-
+
+
+
+
+
+ pci-root
+ pcie-root
+
+
+
+
+
+
+
+
+
+
+
+ pci-bridge
+ dmi-to-pci-bridge
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 682b7e9677..9b1387d62b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5680,6 +5680,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
char *model = NULL;
char *queues = NULL;
xmlNodePtr saved = ctxt->node;
+ int rc;
ctxt->node = node;
@@ -5792,7 +5793,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
switch (def->model) {
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
- case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+ case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: {
+ unsigned long long bytes;
if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("pci-root and pcie-root controllers should not "
@@ -5805,7 +5807,15 @@ virDomainControllerDefParseXML(xmlNodePtr node,
"should have index 0"));
goto error;
}
+ if ((rc = virDomainParseScaledValue("./pcihole64", ctxt,
+ &bytes, 1024,
+ 1024ULL * ULONG_MAX, false)) < 0)
+ goto error;
+ if (rc == 1)
+ def->opts.pciopts.pcihole64 = true;
+ def->opts.pciopts.pcihole64size = VIR_DIV_UP(bytes, 1024);
+ }
}
default:
@@ -14484,6 +14494,7 @@ virDomainControllerDefFormat(virBufferPtr buf,
{
const char *type = virDomainControllerTypeToString(def->type);
const char *model = NULL;
+ bool pcihole64 = false;
if (!type) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -14521,11 +14532,17 @@ virDomainControllerDefFormat(virBufferPtr buf,
}
break;
+ case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
+ if (def->opts.pciopts.pcihole64)
+ pcihole64 = true;
+ break;
+
default:
break;
}
- if (def->queues || virDomainDeviceInfoIsSet(&def->info, flags)) {
+ if (def->queues || virDomainDeviceInfoIsSet(&def->info, flags) ||
+ pcihole64) {
virBufferAddLit(buf, ">\n");
if (def->queues)
@@ -14535,6 +14552,11 @@ virDomainControllerDefFormat(virBufferPtr buf,
virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1;
+ if (pcihole64) {
+ virBufferAsprintf(buf, " %lu"
+ "pcihole64>\n", def->opts.pciopts.pcihole64size);
+ }
+
virBufferAddLit(buf, " \n");
} else {
virBufferAddLit(buf, "/>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6cb2d85b71..0ac576a82e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -814,6 +814,13 @@ struct _virDomainVirtioSerialOpts {
int vectors; /* -1 == undef */
};
+typedef struct _virDomainPciControllerOpts virDomainPciControllerOpts;
+typedef virDomainPciControllerOpts *virDomainPciControllerOptsPtr;
+struct _virDomainPciControllerOpts {
+ bool pcihole64;
+ unsigned long pcihole64size;
+};
+
/* Stores the virtual disk controller configuration */
struct _virDomainControllerDef {
int type;
@@ -822,6 +829,7 @@ struct _virDomainControllerDef {
unsigned int queues;
union {
virDomainVirtioSerialOpts vioserial;
+ virDomainPciControllerOpts pciopts;
} opts;
virDomainDeviceInfo info;
};
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-gib.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-gib.xml
new file mode 100644
index 0000000000..13eb2dd182
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-gib.xml
@@ -0,0 +1,23 @@
+
+ foo
+ c84fc647-6198-4ff9-bf81-d65a1f8f5ec0
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+ 1
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.xml
new file mode 100644
index 0000000000..a181d6c16a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.xml
@@ -0,0 +1,23 @@
+
+ foo
+ c84fc647-6198-4ff9-bf81-d65a1f8f5ec0
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+ 0
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml
new file mode 100644
index 0000000000..ee151be96d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml
@@ -0,0 +1,33 @@
+
+ q35-test
+ 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+
+
+
+
+
+ 1048576
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64.xml b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64.xml
new file mode 100644
index 0000000000..60da238b5d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64.xml
@@ -0,0 +1,23 @@
+
+ foo
+ 3c7c30b5-7866-4b05-8a29-efebccba52a0
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+ 1048576
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcihole64-gib.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcihole64-gib.xml
new file mode 100644
index 0000000000..6d949ac309
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-pcihole64-gib.xml
@@ -0,0 +1,23 @@
+
+ foo
+ c84fc647-6198-4ff9-bf81-d65a1f8f5ec0
+ 2097152
+ 2097152
+ 2
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/libexec/qemu-kvm
+
+ 1048576
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 6eebc685f9..c6615739b4 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -311,6 +311,11 @@ mymain(void)
DO_TEST_DIFFERENT("s390-defaultconsole");
+ DO_TEST("pcihole64");
+ DO_TEST_DIFFERENT("pcihole64-gib");
+ DO_TEST("pcihole64-none");
+ DO_TEST("pcihole64-q35");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);