diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9cec1a0637..82fdfd5f73 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4736,6 +4736,9 @@ + + + @@ -4924,6 +4927,18 @@ + + + + + enabled + disabled + required + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fffcc8e9da..62d0a1683a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -148,7 +148,9 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "vmport", "gic", "smm", - "ioapic") + "ioapic", + "hpt", +); VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST, "default", @@ -882,6 +884,13 @@ VIR_ENUM_IMPL(virDomainIOAPIC, "qemu", "kvm") +VIR_ENUM_IMPL(virDomainHPTResizing, + VIR_DOMAIN_HPT_RESIZING_LAST, + "enabled", + "disabled", + "required", +); + /* Internal mapping: subset of block job types that can be present in * XML (remaining types are not two-phase). */ VIR_ENUM_DECL(virDomainBlockJob) @@ -18775,6 +18784,22 @@ virDomainDefParseXML(xmlDocPtr xml, } break; + case VIR_DOMAIN_FEATURE_HPT: + tmp = virXMLPropString(nodes[i], "resizing"); + if (tmp) { + int value = virDomainHPTResizingTypeFromString(tmp); + if (value < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown HPT resizing setting: %s"), + tmp); + goto error; + } + def->hpt_resizing = value; + def->features[val] = VIR_TRISTATE_SWITCH_ON; + VIR_FREE(tmp); + } + break; + /* coverity[dead_error_begin] */ case VIR_DOMAIN_FEATURE_LAST: break; @@ -20965,6 +20990,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, return false; } + /* HPT resizing */ + if (src->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON) { + if (src->hpt_resizing != dst->hpt_resizing) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("HPT resizing configuration differs: " + "source: '%s', destination: '%s'"), + virDomainHPTResizingTypeToString(src->hpt_resizing), + virDomainHPTResizingTypeToString(dst->hpt_resizing)); + return false; + } + } + return true; } @@ -26214,6 +26251,13 @@ virDomainDefFormatInternal(virDomainDefPtr def, } break; + case VIR_DOMAIN_FEATURE_HPT: + if (def->features[i] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(buf, "\n", + virDomainHPTResizingTypeToString(def->hpt_resizing)); + } + break; + /* coverity[dead_error_begin] */ case VIR_DOMAIN_FEATURE_LAST: break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e3f060b122..41443a02c9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1723,6 +1723,7 @@ typedef enum { VIR_DOMAIN_FEATURE_GIC, VIR_DOMAIN_FEATURE_SMM, VIR_DOMAIN_FEATURE_IOAPIC, + VIR_DOMAIN_FEATURE_HPT, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; @@ -1851,6 +1852,16 @@ typedef enum { VIR_ENUM_DECL(virDomainIOAPIC); +typedef enum { + VIR_DOMAIN_HPT_RESIZING_ENABLED = 0, + VIR_DOMAIN_HPT_RESIZING_DISABLED, + VIR_DOMAIN_HPT_RESIZING_REQUIRED, + + VIR_DOMAIN_HPT_RESIZING_LAST +} virDomainHPTResizing; + +VIR_ENUM_DECL(virDomainHPTResizing); + /* Operating system configuration data & machine / arch */ typedef struct _virDomainOSEnv virDomainOSEnv; typedef virDomainOSEnv *virDomainOSEnvPtr; @@ -2323,6 +2334,7 @@ struct _virDomainDef { virGICVersion gic_version; char *hyperv_vendor_id; virDomainIOAPIC ioapic; + virDomainHPTResizing hpt_resizing; /* These options are of type virTristateSwitch: ON = keep, OFF = drop */ int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST]; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5a4d50471d..a91b87d09a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -387,6 +387,7 @@ virDomainHostdevModeTypeToString; virDomainHostdevRemove; virDomainHostdevSubsysPCIBackendTypeToString; virDomainHostdevSubsysTypeToString; +virDomainHPTResizingTypeToString; virDomainHubTypeFromString; virDomainHubTypeToString; virDomainHypervTypeFromString; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 7cb091056b..1badadbc2e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -443,6 +443,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, /* 270 */ "vxhs", "virtio-blk.num-queues", + "machine.pseries.resize-hpt", ); @@ -4776,6 +4777,13 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, if (qemuCaps->version >= 2006000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT); + /* HPT resizing is supported since QEMU 2.10 on ppc64; unfortunately + * there's no sane way to probe for it */ + if (qemuCaps->version >= 2010000 && + ARCH_IS_PPC64(qemuCaps->arch)) { + virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); + } + if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) goto cleanup; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index cacc2b77ed..f0e2e9016f 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -429,6 +429,7 @@ typedef enum { /* 270 */ QEMU_CAPS_VXHS, /* -drive file.driver=vxhs via query-qmp-schema */ QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES, /* virtio-blk-*.num-queues */ + QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT, /* -machine pseries,resize-hpt */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index eb72db33ba..56729e4981 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7489,6 +7489,26 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, } } + if (def->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON) { + const char *str; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("HTP resizing is not supported by this " + "QEMU binary")); + goto cleanup; + } + + str = virDomainHPTResizingTypeToString(def->hpt_resizing); + if (!str) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Invalid setting for HPT resizing")); + goto cleanup; + } + + virBufferAsprintf(&buf, ",resize-hpt=%s", str); + } + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_LOADPARM)) qemuAppendLoadparmMachineParm(&buf, def); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a36e157529..cc7596bad1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3144,6 +3144,14 @@ qemuDomainDefVerifyFeatures(const virDomainDef *def) return -1; } + if (def->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON && + !qemuDomainIsPSeries(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", + _("HPT tuning is only supported for pSeries guests")); + return -1; + } + return 0; } diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml index 0dfa20726c..b0ee3f1523 100644 --- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml @@ -177,6 +177,7 @@ + 2010000 0 (v2.10.0)