Signed-off-by: Andrea Bolognani <abologna@xxxxxxxxxx> --- docs/formatdomain.html.in | 11 ++++-- docs/schemas/domaincommon.rng | 21 +++++++---- src/conf/domain_conf.c | 36 ++++++++++++++++--- src/conf/domain_conf.h | 1 + tests/qemuxml2argvdata/pseries-features.xml | 4 ++- tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmloutdata/pseries-features.xml | 4 ++- tests/qemuxml2xmltest.c | 1 + 8 files changed, 63 insertions(+), 16 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 89672a0486..1cf92cd755 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1922,7 +1922,9 @@ <pvspinlock state='on'/> <gic version='2'/> <ioapic driver='qemu'/> - <hpt resizing='required'/> + <hpt resizing='required'> + <maxpagesize unit='MiB'>16</maxpagesize> + </hpt> <vmcoreinfo state='on'/> <smm state='on'> <tseg unit='MiB'>48</tseg> @@ -2149,7 +2151,12 @@ support; and <code>required</code>, which prevents the guest from starting unless both the guest and the host support HPT resizing. If the attribute is not defined, the hypervisor default will be used. - <span class="since">Since 3.10.0</span> (QEMU/KVM only) + <span class="since">Since 3.10.0</span> (QEMU/KVM only). + + <p>The optional <code>maxpagesize</code> subelement can be used to + limit the usable page size for HPT guests. Common values are 64 KiB, + 16 MiB and 16 GiB; when not specified, the hypervisor default will + be used. <span class="since">Since 4.5.0</span> (QEMU/KVM only).</p> </dd> <dt><code>vmcoreinfo</code></dt> <dd>Enable QEMU vmcoreinfo device to let the guest kernel save debug diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4a454dddb4..0a661cf1e7 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5121,13 +5121,20 @@ <define name="hpt"> <element name="hpt"> - <attribute name="resizing"> - <choice> - <value>enabled</value> - <value>disabled</value> - <value>required</value> - </choice> - </attribute> + <optional> + <attribute name="resizing"> + <choice> + <value>enabled</value> + <value>disabled</value> + <value>required</value> + </choice> + </attribute> + </optional> + <optional> + <element name="maxpagesize"> + <ref name='scaledInteger'/> + </element> + </optional> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3f7b0d1bfe..d8cb7f37f3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19807,8 +19807,24 @@ virDomainDefParseXML(xmlDocPtr xml, VIR_FREE(tmp); } - if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) + if (virDomainParseScaledValue("./features/hpt/maxpagesize", + NULL, + ctxt, + &def->hpt_maxpagesize, + 1024, + ULLONG_MAX, + false) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", + _("Unable to parse HPT maxpagesize setting")); + goto error; + } + def->hpt_maxpagesize = VIR_DIV_UP(def->hpt_maxpagesize, 1024); + + if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE || + def->hpt_maxpagesize > 0) { def->features[val] = VIR_TRISTATE_SWITCH_ON; + } break; /* coverity[dead_error_begin] */ @@ -21987,15 +22003,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, case VIR_DOMAIN_FEATURE_HPT: if (src->features[i] != dst->features[i] || - src->hpt_resizing != dst->hpt_resizing) { + src->hpt_resizing != dst->hpt_resizing || + src->hpt_maxpagesize != dst->hpt_maxpagesize) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("State of feature '%s' differs: " - "source: '%s,%s=%s', destination: '%s,%s=%s'"), + "source: '%s,%s=%s,%s=%llu', destination: '%s,%s=%s,%s=%llu'"), featureName, virTristateSwitchTypeToString(src->features[i]), "resizing", virDomainHPTResizingTypeToString(src->hpt_resizing), + "maxpagesize", src->hpt_maxpagesize, virTristateSwitchTypeToString(dst->features[i]), - "resizing", virDomainHPTResizingTypeToString(dst->hpt_resizing)); + "resizing", virDomainHPTResizingTypeToString(dst->hpt_resizing), + "maxpagesize", dst->hpt_maxpagesize); return false; } break; @@ -27778,15 +27797,22 @@ virDomainDefFormatInternal(virDomainDefPtr def, break; virBufferFreeAndReset(&attributeBuf); + virBufferFreeAndReset(&childrenBuf); if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) { virBufferAsprintf(&attributeBuf, " resizing='%s'", virDomainHPTResizingTypeToString(def->hpt_resizing)); } + if (def->hpt_maxpagesize > 0) { + virBufferSetChildIndent(&childrenBuf, buf); + virBufferAsprintf(&childrenBuf, + "<maxpagesize unit='KiB'>%llu</maxpagesize>\n", + def->hpt_maxpagesize); + } if (virXMLFormatElement(buf, "hpt", - &attributeBuf, NULL) < 0) { + &attributeBuf, &childrenBuf) < 0) { goto error; } break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 39fa2bc35a..0924fc4f3c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2439,6 +2439,7 @@ struct _virDomainDef { unsigned int hyperv_spinlocks; virGICVersion gic_version; virDomainHPTResizing hpt_resizing; + unsigned long long hpt_maxpagesize; /* Stored in KiB */ char *hyperv_vendor_id; int apic_eoi; diff --git a/tests/qemuxml2argvdata/pseries-features.xml b/tests/qemuxml2argvdata/pseries-features.xml index 5ef1a744c8..30cee5b81c 100644 --- a/tests/qemuxml2argvdata/pseries-features.xml +++ b/tests/qemuxml2argvdata/pseries-features.xml @@ -7,7 +7,9 @@ <type arch='ppc64' machine='pseries'>hvm</type> </os> <features> - <hpt resizing='required'/> + <hpt resizing='required'> + <maxpagesize unit='GiB'>1</maxpagesize> + </hpt> </features> <devices> <emulator>/usr/bin/qemu-system-ppc64</emulator> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 582a9de7bb..ac9593acbe 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1849,6 +1849,7 @@ mymain(void) DO_TEST("pseries-features", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); DO_TEST_FAILURE("pseries-features", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE); diff --git a/tests/qemuxml2xmloutdata/pseries-features.xml b/tests/qemuxml2xmloutdata/pseries-features.xml index e8ed842fb6..f36705f011 100644 --- a/tests/qemuxml2xmloutdata/pseries-features.xml +++ b/tests/qemuxml2xmloutdata/pseries-features.xml @@ -9,7 +9,9 @@ <boot dev='hd'/> </os> <features> - <hpt resizing='required'/> + <hpt resizing='required'> + <maxpagesize unit='KiB'>1048576</maxpagesize> + </hpt> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 4449954ad4..eac6d5b073 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -619,6 +619,7 @@ mymain(void) DO_TEST("pseries-features", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); DO_TEST("pseries-serial-native", -- 2.17.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list