From 01cda91809751f82ed24ae0eda11ae168d562d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Mon, 12 Aug 2013 13:39:04 +0200 Subject: [PATCH] Add pcihole64 element to root PCI controllers 1048576 It can be used to adjust (or disable) the size of the 64-bit PCI hole. The size attribute is in kilobytes (different unit can be specified on input), but it gets rounded up to the nearest GB by QEMU. Disabling it will be needed for guests that crash with the 64-bit PCI hole (like Windows XP), see: https://bugzilla.redhat.com/show_bug.cgi?id=990418 --- docs/formatdomain.html.in | 9 +++++ docs/schemas/domaincommon.rng | 32 +++++++++++++----- src/conf/domain_conf.c | 26 +++++++++++++-- src/conf/domain_conf.h | 8 +++++ .../qemuxml2argv-pcihole64-gib.xml | 23 +++++++++++++ .../qemuxml2argv-pcihole64-none.xml | 23 +++++++++++++ .../qemuxml2argv-pcihole64-q35.xml | 33 +++++++++++++++++++ .../qemuxml2argv-pcihole64.xml | 23 +++++++++++++ .../qemuxml2xmlout-pcihole64-gib.xml | 23 +++++++++++++ tests/qemuxml2xmltest.c | 5 +++ 10 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64-gib.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-pcihole64-gib.xml 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);