From 1bd5a08d3810aa7fd99f2a0c433c1d15d274deb9 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Thu, 10 May 2018 21:32:26 +0200 Subject: [PATCH] conf, schema, docs: Add support for TSEG size setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TSEG (Top of Memory Segment) is one of many regions that SMM (System Management Mode) can occupy. This one, however is special, because a) most of the SMM code lives in TSEG nowadays and b) QEMU just (well, some time ago) added support for so called 'extended' TSEG. The difference to the TSEG implemented in real q35's MCH (Memory Controller Hub) is that it can offer one extra size to the guest OS apart from the standard TSEG's 1, 2, and 8 MiB and that size can be selected in 1 MiB increments. Maximum may vary based on QEMU and is way too big, so we don't need to check for the maximum here. Similarly to the memory size we'll leave it to the hypervisor to try satisfying that and giving us an error message in case it is not possible. Signed-off-by: Martin Kletzander Acked-by: Laszlo Ersek Reviewed-by: Ján Tomko --- docs/formatdomain.html.in | 50 +++++++++++++++++++++- docs/schemas/domaincommon.rng | 5 +++ src/conf/domain_conf.c | 66 ++++++++++++++++++++++++++++- src/conf/domain_conf.h | 3 ++ tests/genericxml2xmlindata/tseg.xml | 23 ++++++++++ tests/genericxml2xmltest.c | 2 + 6 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 tests/genericxml2xmlindata/tseg.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index ba5bd1e502..6912762f28 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1924,6 +1924,9 @@ <ioapic driver='qemu'/> <hpt resizing='required'/> <vmcoreinfo state='on'/> + <smm state='on'> + <tseg unit='MiB'>48</tseg> + </smm> </features> ... @@ -2079,10 +2082,55 @@ Since 1.2.16
smm
-
Depending on the state attribute (values on, +
+

+ Depending on the state attribute (values on, off, default on) enable or disable System Management Mode. Since 2.1.0 +

Optional sub-element tseg can be used to specify + the amount of memory dedicated to SMM's extended TSEG. That offers a + fourth option size apart from the existing ones (1 MiB, 2 MiB and 8 + MiB) that the guest OS (or rather loader) can choose from. The size + can be specified as a value of that element, optional attribute + unit can be used to specify the unit of the + aforementioned value (defaults to 'MiB'). If set to 0 the extended + size is not advertised and only the default ones (see above) are + available. +

+ If the VM is booting you should leave this option alone, unless you + are very certain you know what you are doing. +

+ This value is configurable due to the fact that the calculation cannot + be done right with the guarantee that it will work correctly. In + QEMU, the user-configurable extended TSEG feature was unavailable up + to and including pc-q35-2.9. Starting with + pc-q35-2.10 the feature is available, with default size + 16 MiB. That should suffice for up to roughly 272 VCPUs, 5 GiB guest + RAM in total, no hotplug memory range, and 32 GiB of 64-bit PCI MMIO + aperture. Or for 48 VCPUs, with 1TB of guest RAM, no hotplug DIMM + range, and 32GB of 64-bit PCI MMIO aperture. The values may also vary + based on the loader the VM is using. +

+ Additional size might be needed for significantly higher VCPU counts + or increased address space (that can be memory, maxMemory, 64-bit PCI + MMIO aperture size; roughly 8 MiB of TSEG per 1 TiB of address space) + which can also be rounded up. +

+ Due to the nature of this setting being similar to "how much RAM + should the guest have" users are advised to either consult the + documentation of the guest OS or loader (if there is any), or test + this by trial-and-error changing the value until the VM boots + successfully. Yet another guiding value for users might be the fact + that 48 MiB should be enough for pretty large guests (240 VCPUs and + 4TB guest RAM), but it is on purpose not set as default as 48 MiB of + unavailable RAM might be too much for small guests (e.g. with 512 MiB + of RAM). +

+ See Memory Allocation + for more details about the unit attribute. + Since 4.5.0 (QEMU only) +

ioapic
Tune the I/O APIC. Possible values for the diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index c5c8c575b8..550fb10159 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4846,6 +4846,11 @@ + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5be773cda4..ab93bb7b45 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19898,6 +19898,19 @@ virDomainDefParseXML(xmlDocPtr xml, VIR_FREE(nodes); } + if (def->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) { + int rv = virDomainParseScaledValue("string(./features/smm/tseg)", + "string(./features/smm/tseg/@unit)", + ctxt, + &def->tseg_size, + 1024 * 1024, /* Defaults to mebibytes */ + ULLONG_MAX, + false); + if (rv < 0) + goto error; + def->tseg_specified = rv; + } + if ((n = virXPathNodeSet("./features/capabilities/*", ctxt, &nodes)) < 0) goto error; @@ -22020,6 +22033,33 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } } + /* smm */ + if (src->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) { + if (src->tseg_specified != dst->tseg_specified) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("SMM TSEG differs: source: %s, destination: '%s'"), + src->tseg_specified ? _("specified") : _("not specified"), + dst->tseg_specified ? _("specified") : _("not specified")); + return false; + } + + if (src->tseg_specified && + src->tseg_size != dst->tseg_size) { + const char *unit_src, *unit_dst; + unsigned long long short_size_src = virFormatIntPretty(src->tseg_size, + &unit_src); + unsigned long long short_size_dst = virFormatIntPretty(dst->tseg_size, + &unit_dst); + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Size of SMM TSEG size differs: " + "source: '%llu %s', destination: '%llu %s'"), + short_size_src, unit_src, + short_size_dst, unit_dst); + return false; + } + } + return true; } @@ -27446,7 +27486,6 @@ virDomainDefFormatInternal(virDomainDefPtr def, case VIR_DOMAIN_FEATURE_PMU: case VIR_DOMAIN_FEATURE_PVSPINLOCK: case VIR_DOMAIN_FEATURE_VMPORT: - case VIR_DOMAIN_FEATURE_SMM: switch ((virTristateSwitch) def->features[i]) { case VIR_TRISTATE_SWITCH_LAST: case VIR_TRISTATE_SWITCH_ABSENT: @@ -27463,6 +27502,31 @@ virDomainDefFormatInternal(virDomainDefPtr def, break; + case VIR_DOMAIN_FEATURE_SMM: + if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT) { + virTristateSwitch state = def->features[i]; + virBuffer attrBuf = VIR_BUFFER_INITIALIZER; + virBuffer childBuf = VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&attrBuf, " state='%s'", + virTristateSwitchTypeToString(state)); + + if (state == VIR_TRISTATE_SWITCH_ON && + def->tseg_specified) { + const char *unit; + unsigned long long short_size = virFormatIntPretty(def->tseg_size, + &unit); + + virBufferSetChildIndent(&childBuf, buf); + virBufferAsprintf(&childBuf, "%llu\n", + unit, short_size); + } + + virXMLFormatElement(buf, "smm", &attrBuf, &childBuf); + } + + break; + case VIR_DOMAIN_FEATURE_APIC: if (def->features[i] == VIR_TRISTATE_SWITCH_ON) { virBufferAddLit(buf, " + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + + 48 + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c index d8270a6cae..daad6e0f78 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -141,6 +141,8 @@ mymain(void) DO_TEST_FULL("cachetune-colliding-types", false, true, TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + DO_TEST("tseg"); + virObjectUnref(caps); virObjectUnref(xmlopt);