<ioapic driver='qemu'/>
<hpt resizing='required'/>
<vmcoreinfo state='on'/>
+ <smm state='on'>
+ <tseg unit='MiB'>48</tseg>
+ </smm>
</features>
...</pre>
<span class="since">Since 1.2.16</span>
</dd>
<dt><code>smm</code></dt>
- <dd>Depending on the <code>state</code> attribute (values <code>on</code>,
+ <dd>
+ <p>
+ Depending on the <code>state</code> attribute (values <code>on</code>,
<code>off</code>, default <code>on</code>) enable or disable
System Management Mode.
<span class="since">Since 2.1.0</span>
+ </p><p> Optional sub-element <code>tseg</code> 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
+ <code>unit</code> 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.
+ </p><p>
+ <b>If the VM is booting you should leave this option alone, unless you
+ are very certain you know what you are doing.</b>
+ </p><p>
+ 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 <code>pc-q35-2.9</code>. Starting with
+ <code>pc-q35-2.10</code> 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.
+ </p><p>
+ 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.
+ </p><p>
+ 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).
+ </p><p>
+ See <a href="#elementsMemoryAllocation">Memory Allocation</a>
+ for more details about the <code>unit</code> attribute.
+ <span class="since">Since 4.5.0</span> (QEMU only)
+ </p>
</dd>
<dt><code>ioapic</code></dt>
<dd>Tune the I/O APIC. Possible values for the
<attribute name="state">
<ref name="virOnOff"/>
</attribute>
+ <optional>
+ <element name="tseg">
+ <ref name="scaledInteger"/>
+ </element>
+ </optional>
</optional>
</element>
</optional>
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;
}
}
+ /* 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;
}
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:
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, "<tseg unit='%s'>%llu</tseg>\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, "<apic");
char *hyperv_vendor_id;
int apic_eoi;
+ bool tseg_specified;
+ unsigned long long tseg_size;
+
virDomainClockDef clock;
size_t ngraphics;
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <smm state='on'>
+ <tseg unit='MiB'>48</tseg>
+ </smm>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ </devices>
+</domain>
DO_TEST_FULL("cachetune-colliding-types", false, true,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
+ DO_TEST("tseg");
+
virObjectUnref(caps);
virObjectUnref(xmlopt);