diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 3dd6a59a01fdfaf76e20d22fb8fb195fd3f6a84b..0d685969910f5e4579426d060fb31404eab02598 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 required, 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. - Since 3.10.0 (QEMU/KVM only) + Since 3.10.0 (QEMU/KVM only). + +

The optional maxpagesize 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. Since 4.5.0 (QEMU/KVM only).

vmcoreinfo
Enable QEMU vmcoreinfo device to let the guest kernel save debug diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 611bbef1389ac9dca9867dea4bed93b10f3ec64a..450e8ac77b8505a5dabc2a01d3d747abeae756c0 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5127,13 +5127,20 @@ - - - enabled - disabled - required - - + + + + enabled + disabled + required + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3f7b0d1bfe97ecf0f96cfbee20e85d67856f3595..d8cb7f37f3f802eadca2f598c082c5665f6586cc 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, + "%llu\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 39fa2bc35ac6e9eb5a134490b4f67e0f4cd1bee2..0924fc4f3ce0a924e203bab87816c0ca8a51f10e 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 5ef1a744c871370781b0738bb64f4f7aa22bb6e4..30cee5b81c70df9d29f26b895536c75ba5e30558 100644 --- a/tests/qemuxml2argvdata/pseries-features.xml +++ b/tests/qemuxml2argvdata/pseries-features.xml @@ -7,7 +7,9 @@ hvm - + + 1 + /usr/bin/qemu-system-ppc64 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 582a9de7bb646c0edb5d361689b030cd5297d798..ac9593acbeb53dba157185af767ff51489a6fc88 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 e8ed842fb6385f0167ae9be81d5a8496c233e5cc..f36705f011fcd33692dbe7377f97aed682512523 100644 --- a/tests/qemuxml2xmloutdata/pseries-features.xml +++ b/tests/qemuxml2xmloutdata/pseries-features.xml @@ -9,7 +9,9 @@ - + + 1048576 + destroy diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 4449954ad4bcdd80642fe745ccf62a7903f404ab..eac6d5b0735e7abfc7639a110ade5e87c0770df6 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",