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\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);