[libvirt] [PATCH 0/5] Add optional pSeries features

I consider the first 4 patches ready for inclusion, but the last one - which is basically what justifies going through all this trouble - is sub-optimal until more development has happened in QEMU, so it's marked as RFC. Still, I thought I'd get the ball rolling sooner rather than later. Andrea Bolognani (5): docs: Refactor schema for 'resizing' attribute conf: Add pSeries features conf: Remove obsolete <hpt> feature tests: Clean up HPT tests conf: Add HTM pSeries feature docs/formatdomain.html.in | 39 +++- docs/schemas/domaincommon.rng | 39 +++- src/conf/domain_conf.c | 249 ++++++++++++++++++--- src/conf/domain_conf.h | 14 +- src/libvirt_private.syms | 2 + src/qemu/qemu_capabilities.c | 9 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 116 ++++++++-- src/qemu/qemu_domain.c | 7 +- ...hpt-resizing.args => pseries-features-hpt.args} | 1 - .../pseries-features-hpt.xml} | 4 +- ...hpt-resizing.args => pseries-features-htm.args} | 3 +- .../pseries-features-htm.xml} | 4 +- ...ne.xml => pseries-features-invalid-machine.xml} | 6 +- tests/qemuxml2argvdata/pseries-hpt-resizing.xml | 19 -- tests/qemuxml2argvtest.c | 12 +- tests/qemuxml2xmloutdata/pseries-features-hpt.xml | 1 + tests/qemuxml2xmloutdata/pseries-features-htm.xml | 1 + tests/qemuxml2xmltest.c | 6 +- 19 files changed, 423 insertions(+), 110 deletions(-) copy tests/qemuxml2argvdata/{pseries-hpt-resizing.args => pseries-features-hpt.args} (96%) copy tests/{qemuxml2xmloutdata/pseries-hpt-resizing.xml => qemuxml2argvdata/pseries-features-hpt.xml} (92%) rename tests/qemuxml2argvdata/{pseries-hpt-resizing.args => pseries-features-htm.args} (86%) rename tests/{qemuxml2xmloutdata/pseries-hpt-resizing.xml => qemuxml2argvdata/pseries-features-htm.xml} (93%) rename tests/qemuxml2argvdata/{pseries-hpt-resizing-invalid-machine.xml => pseries-features-invalid-machine.xml} (76%) delete mode 100644 tests/qemuxml2argvdata/pseries-hpt-resizing.xml create mode 120000 tests/qemuxml2xmloutdata/pseries-features-hpt.xml create mode 120000 tests/qemuxml2xmloutdata/pseries-features-htm.xml -- 2.14.3

We're going to use the same attribute for two elements, so it makes sense to give it its own stand-alone definition. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/schemas/domaincommon.rng | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f22c932f6..75838b581 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4952,13 +4952,7 @@ <define name="hpt"> <element name="hpt"> - <attribute name="resizing"> - <choice> - <value>enabled</value> - <value>disabled</value> - <value>required</value> - </choice> - </attribute> + <ref name="resizing"/> </element> </define> @@ -5740,6 +5734,16 @@ </attribute> </define> + <define name="resizing"> + <attribute name="resizing"> + <choice> + <value>enabled</value> + <value>disabled</value> + <value>required</value> + </choice> + </attribute> + </define> + <define name="capabilitiespolicy"> <attribute name="policy"> <choice> -- 2.14.3

We're going to introduce a number of optional, pSeries-specific features, so we want to have a dedicated sub-element to avoid cluttering the <domain><features> element. Along with the generic framework, we also introduce the first actual feature: HPT (Hash Page Table) tuning. This will replace the existing <hpt> feature later on, but right now they simply co-exist without interfering with each other. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.html.in | 20 +++++++++ docs/schemas/domaincommon.rng | 16 +++++++ src/conf/domain_conf.c | 102 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 11 +++++ src/libvirt_private.syms | 2 + src/qemu/qemu_command.c | 93 ++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.c | 7 +++ 7 files changed, 251 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index d272cc1ba..b2584fbb0 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1768,6 +1768,9 @@ <kvm> <hidden state='on'/> </kvm> + <pseries> + <hpt resizing='required'/> + </pseries> <pvspinlock state='on'/> <gic version='2'/> <ioapic driver='qemu'/> @@ -1904,6 +1907,23 @@ </tr> </table> </dd> + <dt><code>pseries</code></dt> + <dd>Various features to change the behavior of pSeries guests. + <table class="top_table"> + <tr> + <th>Feature</th> + <th>Description</th> + <th>Value</th> + <th>Since</th> + </tr> + <tr> + <td>hpt</td> + <td>Configure HPT (Hash Page Table)</td> + <td>resizing: enabled, disabled, required</td> + <td><span class="since">4.1.0 (QEMU 2.10)</span></td> + </tr> + </table> + </dd> <dt><code>pmu</code></dt> <dd>Depending on the <code>state</code> attribute (values <code>on</code>, <code>off</code>, default <code>on</code>) enable or disable the diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 75838b581..fead6e7cc 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4703,6 +4703,9 @@ <optional> <ref name="kvm"/> </optional> + <optional> + <ref name="pseries"/> + </optional> <optional> <element name="privnet"> <empty/> @@ -5526,6 +5529,19 @@ </element> </define> + <!-- Optional pSeries features --> + <define name="pseries"> + <element name="pseries"> + <interleave> + <optional> + <element name="hpt"> + <ref name="resizing"/> + </element> + </optional> + </interleave> + </element> + </define> + <!-- Optional capabilities features --> <define name="capabilities"> <element name="capabilities"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a1c25060f..577a804df 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -152,6 +152,7 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "ioapic", "hpt", "vmcoreinfo", + "pseries", ); VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST, @@ -173,6 +174,11 @@ VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST, VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST, "hidden") +VIR_ENUM_IMPL(virDomainPSeries, + VIR_DOMAIN_PSERIES_LAST, + "hpt", +); + VIR_ENUM_IMPL(virDomainCapsFeature, VIR_DOMAIN_CAPS_FEATURE_LAST, "audit_control", "audit_write", @@ -18879,6 +18885,7 @@ virDomainDefParseXML(xmlDocPtr xml, case VIR_DOMAIN_FEATURE_HYPERV: case VIR_DOMAIN_FEATURE_VMCOREINFO: case VIR_DOMAIN_FEATURE_KVM: + case VIR_DOMAIN_FEATURE_PSERIES: def->features[val] = VIR_TRISTATE_SWITCH_ON; break; @@ -19114,6 +19121,54 @@ virDomainDefParseXML(xmlDocPtr xml, VIR_FREE(nodes); } + if (def->features[VIR_DOMAIN_FEATURE_PSERIES] == VIR_TRISTATE_SWITCH_ON) { + int feature; + int value; + + if ((n = virXPathNodeSet("./features/pseries/*", ctxt, &nodes)) < 0) + goto error; + + for (i = 0; i < n; i++) { + feature = virDomainPSeriesTypeFromString((const char *) nodes[i]->name); + + if (feature < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown '%s' pSeries feature"), + nodes[i]->name); + goto error; + } + + switch ((virDomainPSeries) feature) { + case VIR_DOMAIN_PSERIES_HPT: + if (!(tmp = virXMLPropString(nodes[i], "resizing"))) { + virReportError(VIR_ERR_XML_ERROR, + _("Missing '%s' attribute for " + "'%s' pSeries feature"), + "resizing", nodes[i]->name); + goto error; + } + + if ((value = virDomainHPTResizingTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid value '%s' for '%s' " + "attribute of '%s' pSeries feature"), + tmp, "resizing", nodes[i]->name); + goto error; + } + + def->pseries_features[feature] = VIR_TRISTATE_SWITCH_ON; + def->pseries_hpt_resizing = value; + + VIR_FREE(tmp); + break; + + case VIR_DOMAIN_PSERIES_LAST: + break; + } + } + VIR_FREE(nodes); + } + if ((n = virXPathNodeSet("./features/capabilities/*", ctxt, &nodes)) < 0) goto error; @@ -21140,6 +21195,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } } + /* pSeries features */ + if (src->features[VIR_DOMAIN_FEATURE_PSERIES] == VIR_TRISTATE_SWITCH_ON) { + for (i = 0; i < VIR_DOMAIN_PSERIES_LAST; i++) { + switch ((virDomainPSeries) i) { + case VIR_DOMAIN_PSERIES_HPT: + if (src->pseries_features[i] != dst->pseries_features[i] || + src->pseries_hpt_resizing != dst->pseries_hpt_resizing) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("State of '%s' pSeries feature differs: " + "source: '%s', destination: '%s'"), + virDomainPSeriesTypeToString(i), + virDomainHPTResizingTypeToString(src->pseries_hpt_resizing), + virDomainHPTResizingTypeToString(dst->pseries_hpt_resizing)); + return false; + } + break; + + case VIR_DOMAIN_PSERIES_LAST: + break; + } + } + } + /* ioapic */ if (src->ioapic != dst->ioapic) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -26487,6 +26565,30 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, "</kvm>\n"); break; + case VIR_DOMAIN_FEATURE_PSERIES: + if (def->features[i] != VIR_TRISTATE_SWITCH_ON) + break; + + virBufferAddLit(buf, "<pseries>\n"); + virBufferAdjustIndent(buf, 2); + for (j = 0; j < VIR_DOMAIN_PSERIES_LAST; j++) { + switch ((virDomainPSeries) j) { + case VIR_DOMAIN_PSERIES_HPT: + if (def->pseries_features[j] != VIR_TRISTATE_SWITCH_ON) + break; + + virBufferAsprintf(buf, "<hpt resizing='%s'/>\n", + virDomainHPTResizingTypeToString(def->pseries_hpt_resizing)); + break; + + case VIR_DOMAIN_PSERIES_LAST: + break; + } + } + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</pseries>\n"); + break; + case VIR_DOMAIN_FEATURE_CAPABILITIES: if (def->features[i] == VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT && !virDomainDefHasCapabilitiesFeatures(def)) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6f7f96b3d..e4ae2a26c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1740,6 +1740,7 @@ typedef enum { VIR_DOMAIN_FEATURE_IOAPIC, VIR_DOMAIN_FEATURE_HPT, VIR_DOMAIN_FEATURE_VMCOREINFO, + VIR_DOMAIN_FEATURE_PSERIES, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; @@ -1766,6 +1767,14 @@ typedef enum { VIR_DOMAIN_KVM_LAST } virDomainKVM; +typedef enum { + VIR_DOMAIN_PSERIES_HPT = 0, + + VIR_DOMAIN_PSERIES_LAST +} virDomainPSeries; + +VIR_ENUM_DECL(virDomainPSeries); + typedef enum { VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT = 0, VIR_DOMAIN_CAPABILITIES_POLICY_ALLOW, @@ -2346,11 +2355,13 @@ struct _virDomainDef { int apic_eoi; int hyperv_features[VIR_DOMAIN_HYPERV_LAST]; int kvm_features[VIR_DOMAIN_KVM_LAST]; + int pseries_features[VIR_DOMAIN_PSERIES_LAST]; unsigned int hyperv_spinlocks; virGICVersion gic_version; char *hyperv_vendor_id; virDomainIOAPIC ioapic; virDomainHPTResizing hpt_resizing; + virDomainHPTResizing pseries_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 bc8cc1fba..ae9eecb5d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -484,6 +484,8 @@ virDomainPausedReasonTypeFromString; virDomainPausedReasonTypeToString; virDomainPMSuspendedReasonTypeFromString; virDomainPMSuspendedReasonTypeToString; +virDomainPSeriesTypeFromString; +virDomainPSeriesTypeToString; virDomainRedirdevBusTypeFromString; virDomainRedirdevBusTypeToString; virDomainRedirdevDefFind; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b8aede32d..a053b597c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7360,6 +7360,79 @@ qemuBuildNameCommandLine(virCommandPtr cmd, return 0; } +static int +virDomainPSeriesToQEMUCaps(int feature) +{ + switch ((virDomainPSeries) feature) { + case VIR_DOMAIN_PSERIES_HPT: + return QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT; + case VIR_DOMAIN_PSERIES_LAST: + break; + } + + return -1; +} + +static const char* +virDomainPSeriesToMachineOption(int feature) +{ + switch ((virDomainPSeries) feature) { + case VIR_DOMAIN_PSERIES_HPT: + return "resize-hpt"; + case VIR_DOMAIN_PSERIES_LAST: + break; + } + + return NULL; +} + +static int +qemuBuildMachineCommandLinePSeriesFeature(virBufferPtr buf, + virDomainPSeries feature, + const char *value, + virQEMUCapsPtr qemuCaps) +{ + const char *name = virDomainPSeriesTypeToString(feature); + const char *option = virDomainPSeriesToMachineOption(feature); + int cap; + int ret = -1; + + if (!option) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown QEMU option for '%s' pSeries feature"), + name); + goto cleanup; + } + + if (!value) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid value for '%s' pSeries feature"), + name); + goto cleanup; + } + + if ((cap = virDomainPSeriesToQEMUCaps(feature)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown QEMU capability for '%s' pSeries feature"), + name); + goto cleanup; + } + + if (!virQEMUCapsGet(qemuCaps, cap)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("'%s' pSeries feature not supported by this QEMU binary"), + name); + goto cleanup; + } + + virBufferAsprintf(buf, ",%s=%s", option, value); + + ret = 0; + + cleanup: + return ret; +} + static int qemuBuildMachineCommandLine(virCommandPtr cmd, virQEMUDriverConfigPtr cfg, @@ -7592,6 +7665,26 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, virBufferAsprintf(&buf, ",resize-hpt=%s", str); } + if (def->features[VIR_DOMAIN_FEATURE_PSERIES] == VIR_TRISTATE_SWITCH_ON) { + const char *value; + + for (i = 0; i < VIR_DOMAIN_PSERIES_LAST; i++) { + switch ((virDomainPSeries) i) { + case VIR_DOMAIN_PSERIES_HPT: + if (def->pseries_features[i] != VIR_TRISTATE_SWITCH_ON) + break; + + value = virDomainHPTResizingTypeToString(def->pseries_hpt_resizing); + if (qemuBuildMachineCommandLinePSeriesFeature(&buf, i, value, qemuCaps) < 0) + goto cleanup; + break; + + case VIR_DOMAIN_PSERIES_LAST: + goto cleanup; + } + } + } + if (cpu && cpu->model && cpu->mode == VIR_CPU_MODE_HOST_MODEL && qemuDomainIsPSeries(def) && diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6b4bd3cca..edef3838e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3125,6 +3125,13 @@ qemuDomainDefVerifyFeatures(const virDomainDef *def) return -1; } + if (def->features[VIR_DOMAIN_FEATURE_PSERIES] == VIR_TRISTATE_SWITCH_ON && + !qemuDomainIsPSeries(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("pSeries features are only supported for pSeries guests")); + return -1; + } + if (def->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON && !qemuDomainIsPSeries(def)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, -- 2.14.3

On Tue, Jan 23, 2018 at 04:45:01PM +0100, Andrea Bolognani wrote:
We're going to introduce a number of optional, pSeries-specific features, so we want to have a dedicated sub-element to avoid cluttering the <domain><features> element.
I don't think we want todo this as all. Pretty much *every* single existing <feature> element is architecture specific. Adding a nested level just for pseries is making it different from existing practice and I don't see any benefit to that. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Thu, 2018-01-25 at 15:03 +0000, Daniel P. Berrangé wrote:
On Tue, Jan 23, 2018 at 04:45:01PM +0100, Andrea Bolognani wrote:
We're going to introduce a number of optional, pSeries-specific features, so we want to have a dedicated sub-element to avoid cluttering the <domain><features> element.
I don't think we want todo this as all. Pretty much *every* single existing <feature> element is architecture specific. Adding a nested level just for pseries is making it different from existing practice and I don't see any benefit to that.
Well, there's going to be a bunch of them added pretty soon (six or so) plus probably more down the line, so that's already quite a bit of clutter. My reasoning was to try and organize them the way we already do with <kvm> and <hyperv> capabilities - even though pSeries is not a hypervisor per se, you can kinda see sPAPR as a specification implemented by various hypervisors, like PowerVM and in our case QEMU/KVM. But if you think this effort is misguided and they belong to the top-level <features> element, then I'm okay with that too. -- Andrea Bolognani / Red Hat / Virtualization

On Thu, Jan 25, 2018 at 05:12:49PM +0100, Andrea Bolognani wrote:
On Thu, 2018-01-25 at 15:03 +0000, Daniel P. Berrangé wrote:
On Tue, Jan 23, 2018 at 04:45:01PM +0100, Andrea Bolognani wrote:
We're going to introduce a number of optional, pSeries-specific features, so we want to have a dedicated sub-element to avoid cluttering the <domain><features> element.
I don't think we want todo this as all. Pretty much *every* single existing <feature> element is architecture specific. Adding a nested level just for pseries is making it different from existing practice and I don't see any benefit to that.
Well, there's going to be a bunch of them added pretty soon (six or so) plus probably more down the line, so that's already quite a bit of clutter. My reasoning was to try and organize them the way we already do with <kvm> and <hyperv> capabilities - even though pSeries is not a hypervisor per se, you can kinda see sPAPR as a specification implemented by various hypervisors, like PowerVM and in our case QEMU/KVM. But if you think this effort is misguided and they belong to the top-level <features> element, then I'm okay with that too.
I guess where the nesting makes sense is if there's a chance of having namespace collision between features. eg if both kvm and hyperv had a feature called "pvspinlocks", you might want to enable them separately, so the nesting is important there. If you do think the pSeries nesting is important in this respect, can you still leave the existing "hpt" feature un-nested for sake of full back-compat - just nest new features. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Thu, 2018-01-25 at 16:16 +0000, Daniel P. Berrangé wrote:
My reasoning was to try and organize them the way we already do with <kvm> and <hyperv> capabilities - even though pSeries is not a hypervisor per se, you can kinda see sPAPR as a specification implemented by various hypervisors, like PowerVM and in our case QEMU/KVM. But if you think this effort is misguided and they belong to the top-level <features> element, then I'm okay with that too.
I guess where the nesting makes sense is if there's a chance of having namespace collision between features. eg if both kvm and hyperv had a feature called "pvspinlocks", you might want to enable them separately, so the nesting is important there.
Mh, I don't foresee that kind of collision happening. We should be safe; and if it ever turns out not to be the case, then we can just nest the new features instead. I'll respin a simpler version of this. Thanks for the feedback :) -- Andrea Bolognani / Red Hat / Virtualization

Now that the <pseries><hpt> feature has been implemented, we can get rid of the original <hpt> feature and thus ensure all pSeries features are grouped together in the same sub-element. Compatibility code is provided so that existing guests can be parsed and migrated successfully despite the change. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.html.in | 12 --- src/conf/domain_conf.c | 105 ++++++++++++++-------- src/conf/domain_conf.h | 2 - src/qemu/qemu_command.c | 20 ----- src/qemu/qemu_domain.c | 8 -- tests/qemuxml2xmloutdata/pseries-hpt-resizing.xml | 4 +- 6 files changed, 71 insertions(+), 80 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b2584fbb0..1e2fccaeb 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1774,7 +1774,6 @@ <pvspinlock state='on'/> <gic version='2'/> <ioapic driver='qemu'/> - <hpt resizing='required'/> </features> ...</pre> @@ -1960,17 +1959,6 @@ which is also known as a split I/O APIC mode. <span class="since">Since 3.4.0</span> (QEMU/KVM only) </dd> - <dt><code>hpt</code></dt> - <dd>Configure the HPT (Hash Page Table) of a pSeries guest. Possible - values for the <code>resizing</code> attribute are - <code>enabled</code>, which causes HPT resizing to be enabled if - both the guest and the host support it; <code>disabled</code>, which - causes HPT resizing to be disabled regardless of guest and host - 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) - </dd> <dt><code>vmcoreinfo</code></dt> <dd>Enable QEMU vmcoreinfo device to let the guest kernel save debug details. <span class="since">Since 3.10.0</span> (QEMU only) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 577a804df..763228ca7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -150,7 +150,6 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "gic", "smm", "ioapic", - "hpt", "vmcoreinfo", "pseries", ); @@ -18857,6 +18856,36 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; for (i = 0; i < n; i++) { + + /* Compatibility code. + * + * Between 3.10.0 and 4.1.0, we had <features><hpt> instead of + * <features><pseries><hpt>, and we need to be able to parse existing + * guest configurations; this takes care of it. Note that the compat + * code, like the original implementation and unlike the new one, + * must handle gracefully the 'resizing' attribute being absent */ + if (STREQ((const char *) nodes[i]->name, "hpt")) { + tmp = virXMLPropString(nodes[i], "resizing"); + if (tmp) { + int value = virDomainHPTResizingTypeFromString(tmp); + if (value < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid value '%s' for '%s' " + "attribute of '%s' pSeries feature"), + tmp, "resizing", nodes[i]->name); + goto error; + } + + def->features[VIR_DOMAIN_FEATURE_PSERIES] = VIR_TRISTATE_SWITCH_ON; + def->pseries_features[VIR_DOMAIN_PSERIES_HPT] = VIR_TRISTATE_SWITCH_ON; + def->pseries_hpt_resizing = value; + + VIR_FREE(tmp); + } + i++; + continue; + } + int val = virDomainFeatureTypeFromString((const char *)nodes[i]->name); if (val < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -18951,22 +18980,6 @@ 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; @@ -21228,18 +21241,6 @@ 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; } @@ -26565,10 +26566,44 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, "</kvm>\n"); break; - case VIR_DOMAIN_FEATURE_PSERIES: + case VIR_DOMAIN_FEATURE_PSERIES: { + bool needsPSeriesElement = false; + if (def->features[i] != VIR_TRISTATE_SWITCH_ON) break; + /* Figure out whether we need the <pseries> element. + * For compatibility reasons (see below) we might need to + * skip it even though some pSeries features are enabled: + * namely, if the HPT feature is enabled and we're formatting + * a migratable XML */ + for (j = 0; j < VIR_DOMAIN_PSERIES_LAST; j++) { + if (def->pseries_features[j] == VIR_TRISTATE_SWITCH_ABSENT) + continue; + if ((virDomainPSeries) j == VIR_DOMAIN_PSERIES_HPT && + flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE) { + continue; + } + needsPSeriesElement = true; + break; + } + + /* Compatibility code. + * Between 3.10.0 and 4.1.0, we had <features><hpt> instead + * of <features><pseries><hpt>, and we need to be able to + * migrate existing guests back and forth between old libvirt + * and new libvirt; this takes care of it, by using the old + * element when formatting a migratable XML */ + if (def->pseries_features[VIR_DOMAIN_PSERIES_HPT] == VIR_TRISTATE_SWITCH_ON && + flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE) { + virBufferAsprintf(buf, "<hpt resizing='%s'/>\n", + virDomainHPTResizingTypeToString(def->pseries_hpt_resizing)); + } + + /* Stop here unless we need the <pseries> element */ + if (!needsPSeriesElement) + break; + virBufferAddLit(buf, "<pseries>\n"); virBufferAdjustIndent(buf, 2); for (j = 0; j < VIR_DOMAIN_PSERIES_LAST; j++) { @@ -26576,6 +26611,8 @@ virDomainDefFormatInternal(virDomainDefPtr def, case VIR_DOMAIN_PSERIES_HPT: if (def->pseries_features[j] != VIR_TRISTATE_SWITCH_ON) break; + if (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE) + break; virBufferAsprintf(buf, "<hpt resizing='%s'/>\n", virDomainHPTResizingTypeToString(def->pseries_hpt_resizing)); @@ -26588,6 +26625,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</pseries>\n"); break; + } case VIR_DOMAIN_FEATURE_CAPABILITIES: if (def->features[i] == VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT && @@ -26625,13 +26663,6 @@ virDomainDefFormatInternal(virDomainDefPtr def, } break; - case VIR_DOMAIN_FEATURE_HPT: - if (def->features[i] == VIR_TRISTATE_SWITCH_ON) { - virBufferAsprintf(buf, "<hpt resizing='%s'/>\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 e4ae2a26c..91db2220a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1738,7 +1738,6 @@ typedef enum { VIR_DOMAIN_FEATURE_GIC, VIR_DOMAIN_FEATURE_SMM, VIR_DOMAIN_FEATURE_IOAPIC, - VIR_DOMAIN_FEATURE_HPT, VIR_DOMAIN_FEATURE_VMCOREINFO, VIR_DOMAIN_FEATURE_PSERIES, @@ -2360,7 +2359,6 @@ struct _virDomainDef { virGICVersion gic_version; char *hyperv_vendor_id; virDomainIOAPIC ioapic; - virDomainHPTResizing hpt_resizing; virDomainHPTResizing pseries_hpt_resizing; /* These options are of type virTristateSwitch: ON = keep, OFF = drop */ diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a053b597c..26122b048 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7645,26 +7645,6 @@ 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 (def->features[VIR_DOMAIN_FEATURE_PSERIES] == VIR_TRISTATE_SWITCH_ON) { const char *value; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index edef3838e..c604f0657 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3132,14 +3132,6 @@ 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/qemuxml2xmloutdata/pseries-hpt-resizing.xml b/tests/qemuxml2xmloutdata/pseries-hpt-resizing.xml index 5dd0dbd0b..b6a89ffe2 100644 --- a/tests/qemuxml2xmloutdata/pseries-hpt-resizing.xml +++ b/tests/qemuxml2xmloutdata/pseries-hpt-resizing.xml @@ -9,7 +9,9 @@ <boot dev='hd'/> </os> <features> - <hpt resizing='required'/> + <pseries> + <hpt resizing='required'/> + </pseries> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> -- 2.14.3

On Tue, Jan 23, 2018 at 04:45:02PM +0100, Andrea Bolognani wrote:
Now that the <pseries><hpt> feature has been implemented, we can get rid of the original <hpt> feature and thus ensure all pSeries features are grouped together in the same sub-element.
Compatibility code is provided so that existing guests can be parsed and migrated successfully despite the change.
This is still not ok - we're breaking any application which is reading the XML, because the <hpt> flag it used to have is now gone. I'm afraid we cannot change this and must keep the original <hpt> flag as is. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Give them better names and remove some redundancy. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- I would probably just squash this into the previous patch, but I figured others would prefer it as a separate one. ...es-hpt-resizing.args => pseries-features-hpt.args} | 1 - .../pseries-features-hpt.xml} | 0 ...chine.xml => pseries-features-invalid-machine.xml} | 6 ++++-- tests/qemuxml2argvdata/pseries-hpt-resizing.xml | 19 ------------------- tests/qemuxml2argvtest.c | 9 +++------ tests/qemuxml2xmloutdata/pseries-features-hpt.xml | 1 + tests/qemuxml2xmltest.c | 3 +-- 7 files changed, 9 insertions(+), 30 deletions(-) rename tests/qemuxml2argvdata/{pseries-hpt-resizing.args => pseries-features-hpt.args} (96%) rename tests/{qemuxml2xmloutdata/pseries-hpt-resizing.xml => qemuxml2argvdata/pseries-features-hpt.xml} (100%) rename tests/qemuxml2argvdata/{pseries-hpt-resizing-invalid-machine.xml => pseries-features-invalid-machine.xml} (76%) delete mode 100644 tests/qemuxml2argvdata/pseries-hpt-resizing.xml create mode 120000 tests/qemuxml2xmloutdata/pseries-features-hpt.xml diff --git a/tests/qemuxml2argvdata/pseries-hpt-resizing.args b/tests/qemuxml2argvdata/pseries-features-hpt.args similarity index 96% rename from tests/qemuxml2argvdata/pseries-hpt-resizing.args rename to tests/qemuxml2argvdata/pseries-features-hpt.args index 994789a5e..8cdb32965 100644 --- a/tests/qemuxml2argvdata/pseries-hpt-resizing.args +++ b/tests/qemuxml2argvdata/pseries-features-hpt.args @@ -12,7 +12,6 @@ QEMU_AUDIO_DRV=none \ -smp 1,sockets=1,cores=1,threads=1 \ -uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \ -nographic \ --nodefconfig \ -nodefaults \ -chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ server,nowait \ diff --git a/tests/qemuxml2xmloutdata/pseries-hpt-resizing.xml b/tests/qemuxml2argvdata/pseries-features-hpt.xml similarity index 100% rename from tests/qemuxml2xmloutdata/pseries-hpt-resizing.xml rename to tests/qemuxml2argvdata/pseries-features-hpt.xml diff --git a/tests/qemuxml2argvdata/pseries-hpt-resizing-invalid-machine.xml b/tests/qemuxml2argvdata/pseries-features-invalid-machine.xml similarity index 76% rename from tests/qemuxml2argvdata/pseries-hpt-resizing-invalid-machine.xml rename to tests/qemuxml2argvdata/pseries-features-invalid-machine.xml index 757fcc70e..bc5501b6c 100644 --- a/tests/qemuxml2argvdata/pseries-hpt-resizing-invalid-machine.xml +++ b/tests/qemuxml2argvdata/pseries-features-invalid-machine.xml @@ -7,8 +7,10 @@ <type arch='x86_64' machine='pc'>hvm</type> </os> <features> - <!-- HPT resizing can't be enabled for non-pSeries guests --> - <hpt resizing='enabled'/> + <!-- pSeries features can't be enabled for non-pSeries guests --> + <pseries> + <hpt resizing='enabled'/> + </pseries> </features> <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> diff --git a/tests/qemuxml2argvdata/pseries-hpt-resizing.xml b/tests/qemuxml2argvdata/pseries-hpt-resizing.xml deleted file mode 100644 index f9dc9cac9..000000000 --- a/tests/qemuxml2argvdata/pseries-hpt-resizing.xml +++ /dev/null @@ -1,19 +0,0 @@ -<domain type='qemu'> - <name>guest</name> - <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> - <memory unit='KiB'>524288</memory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='ppc64' machine='pseries'>hvm</type> - </os> - <features> - <!-- Explicitly enable HPT resizing. The guest will not start - at all unless HPT resizing can be arranged --> - <hpt resizing='required'/> - </features> - <devices> - <emulator>/usr/bin/qemu-system-ppc64</emulator> - <controller type='usb' model='none'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c8739909d..cc9280db0 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1891,15 +1891,12 @@ mymain(void) QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VFIO_PCI); - DO_TEST("pseries-hpt-resizing", - QEMU_CAPS_NODEFCONFIG, + DO_TEST("pseries-features-hpt", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); - DO_TEST_FAILURE("pseries-hpt-resizing", - QEMU_CAPS_NODEFCONFIG, + DO_TEST_FAILURE("pseries-features-hpt", QEMU_CAPS_MACHINE_OPT); - DO_TEST_PARSE_ERROR("pseries-hpt-resizing-invalid-machine", - QEMU_CAPS_NODEFCONFIG, + DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); diff --git a/tests/qemuxml2xmloutdata/pseries-features-hpt.xml b/tests/qemuxml2xmloutdata/pseries-features-hpt.xml new file mode 120000 index 000000000..bcaf2e6fe --- /dev/null +++ b/tests/qemuxml2xmloutdata/pseries-features-hpt.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/pseries-features-hpt.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 78519f509..ba4e853f9 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -763,8 +763,7 @@ mymain(void) QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DEVICE_VFIO_PCI); - DO_TEST("pseries-hpt-resizing", - QEMU_CAPS_NODEFCONFIG, + DO_TEST("pseries-features-hpt", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); -- 2.14.3

Introduce a way to enable and disable the availability of HTM (Hardware Transactional Memory) for pSeries guests. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- The availability of the corresponding QEMU toggle is currently crudely inferred from the version number, but there's ongoing discussion on how to introspect it properly through QMP, hence the RFC status of this patch. docs/formatdomain.html.in | 7 ++++ docs/schemas/domaincommon.rng | 5 +++ src/conf/domain_conf.c | 44 +++++++++++++++++++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 9 +++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 13 +++++++ tests/qemuxml2argvdata/pseries-features-htm.args | 19 ++++++++++ tests/qemuxml2argvdata/pseries-features-htm.xml | 30 ++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ tests/qemuxml2xmloutdata/pseries-features-htm.xml | 1 + tests/qemuxml2xmltest.c | 3 ++ 12 files changed, 136 insertions(+) create mode 100644 tests/qemuxml2argvdata/pseries-features-htm.args create mode 100644 tests/qemuxml2argvdata/pseries-features-htm.xml create mode 120000 tests/qemuxml2xmloutdata/pseries-features-htm.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 1e2fccaeb..22b0739ac 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1770,6 +1770,7 @@ </kvm> <pseries> <hpt resizing='required'/> + <htm state='off'/> </pseries> <pvspinlock state='on'/> <gic version='2'/> @@ -1921,6 +1922,12 @@ <td>resizing: enabled, disabled, required</td> <td><span class="since">4.1.0 (QEMU 2.10)</span></td> </tr> + <tr> + <td>htm</td> + <td>Configure HTM (Hardware Transactional Memory)</td> + <td>state: on, off</td> + <td><span class="since">4.1.0 (QEMU 2.12)</span></td> + </tr> </table> </dd> <dt><code>pmu</code></dt> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index fead6e7cc..b49318aa3 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5538,6 +5538,11 @@ <ref name="resizing"/> </element> </optional> + <optional> + <element name="htm"> + <ref name="featurestate"/> + </element> + </optional> </interleave> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 763228ca7..34ef08e21 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -176,6 +176,7 @@ VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST, VIR_ENUM_IMPL(virDomainPSeries, VIR_DOMAIN_PSERIES_LAST, "hpt", + "htm", ); VIR_ENUM_IMPL(virDomainCapsFeature, VIR_DOMAIN_CAPS_FEATURE_LAST, @@ -19175,6 +19176,28 @@ virDomainDefParseXML(xmlDocPtr xml, VIR_FREE(tmp); break; + case VIR_DOMAIN_PSERIES_HTM: + if (!(tmp = virXMLPropString(nodes[i], "state"))) { + virReportError(VIR_ERR_XML_ERROR, + _("Missing 'state' attribute for " + "'%s' pSeries feature"), + nodes[i]->name); + goto error; + } + + if ((value = virTristateSwitchTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid value '%s' for 'state' " + "attribute of '%s' pSeries feature"), + nodes[i]->name, tmp); + goto error; + } + + def->pseries_features[feature] = value; + + VIR_FREE(tmp); + break; + case VIR_DOMAIN_PSERIES_LAST: break; } @@ -21225,6 +21248,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } break; + case VIR_DOMAIN_PSERIES_HTM: + if (src->pseries_features[i] != dst->pseries_features[i]) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("State of '%s' pSeries feature differs: " + "source: '%s', destination: '%s'"), + virDomainPSeriesTypeToString(i), + virTristateSwitchTypeToString(src->pseries_features[i]), + virTristateSwitchTypeToString(dst->pseries_features[i])); + return false; + } + break; + case VIR_DOMAIN_PSERIES_LAST: break; } @@ -26618,6 +26653,15 @@ virDomainDefFormatInternal(virDomainDefPtr def, virDomainHPTResizingTypeToString(def->pseries_hpt_resizing)); break; + case VIR_DOMAIN_PSERIES_HTM: + if (def->pseries_features[j] == VIR_TRISTATE_SWITCH_ABSENT) + break; + + virBufferAsprintf(buf, "<%s state='%s'/>\n", + virDomainPSeriesTypeToString(j), + virTristateSwitchTypeToString(def->pseries_features[j])); + break; + case VIR_DOMAIN_PSERIES_LAST: break; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 91db2220a..3c1a61c8e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1768,6 +1768,7 @@ typedef enum { typedef enum { VIR_DOMAIN_PSERIES_HPT = 0, + VIR_DOMAIN_PSERIES_HTM, VIR_DOMAIN_PSERIES_LAST } virDomainPSeries; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 5e03447ba..5897b6c66 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -458,6 +458,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, /* 280 */ "pl011", "machine.pseries.max-cpu-compat", + "machine.pseries.cap-htm", ); @@ -4894,6 +4895,14 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT); } + /* No way to query cap-htm availability... Yet. See + * http://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg04674.html + * for an attempt at making this introspectable through QMP */ + if (qemuCaps->version >= 2012000 && + ARCH_IS_PPC64(qemuCaps->arch)) { + virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM); + } + if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) goto cleanup; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 3dfc77f87..5401a3118 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -443,6 +443,7 @@ typedef enum { /* 280 */ QEMU_CAPS_DEVICE_PL011, /* -device pl011 (not user-instantiable) */ QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT, /* -machine pseries,max-cpu-compat= */ + QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, /* -machine pseries,cap-htm= */ 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 26122b048..bb8567629 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7366,6 +7366,8 @@ virDomainPSeriesToQEMUCaps(int feature) switch ((virDomainPSeries) feature) { case VIR_DOMAIN_PSERIES_HPT: return QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT; + case VIR_DOMAIN_PSERIES_HTM: + return QEMU_CAPS_MACHINE_PSERIES_CAP_HTM; case VIR_DOMAIN_PSERIES_LAST: break; } @@ -7379,6 +7381,8 @@ virDomainPSeriesToMachineOption(int feature) switch ((virDomainPSeries) feature) { case VIR_DOMAIN_PSERIES_HPT: return "resize-hpt"; + case VIR_DOMAIN_PSERIES_HTM: + return "cap-htm"; case VIR_DOMAIN_PSERIES_LAST: break; } @@ -7659,6 +7663,15 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, goto cleanup; break; + case VIR_DOMAIN_PSERIES_HTM: + if (def->pseries_features[i] == VIR_TRISTATE_SWITCH_ABSENT) + break; + + value = virTristateSwitchTypeToString(def->pseries_features[i]); + if (qemuBuildMachineCommandLinePSeriesFeature(&buf, i, value, qemuCaps) < 0) + goto cleanup; + break; + case VIR_DOMAIN_PSERIES_LAST: goto cleanup; } diff --git a/tests/qemuxml2argvdata/pseries-features-htm.args b/tests/qemuxml2argvdata/pseries-features-htm.args new file mode 100644 index 000000000..64fd28ed2 --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-features-htm.args @@ -0,0 +1,19 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest \ +-S \ +-machine pseries,accel=tcg,cap-htm=on \ +-m 512 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-boot c diff --git a/tests/qemuxml2argvdata/pseries-features-htm.xml b/tests/qemuxml2argvdata/pseries-features-htm.xml new file mode 100644 index 000000000..9e92aa91e --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-features-htm.xml @@ -0,0 +1,30 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>524288</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <pseries> + <htm state='on'/> + </pseries> + </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-ppc64</emulator> + <controller type='usb' index='0' model='none'/> + <controller type='pci' index='0' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target index='0'/> + </controller> + <memballoon model='none'/> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index cc9280db0..03d159e69 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1899,6 +1899,9 @@ mymain(void) DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); + DO_TEST("pseries-features-htm", + QEMU_CAPS_MACHINE_OPT, + QEMU_CAPS_MACHINE_PSERIES_CAP_HTM); DO_TEST("pseries-serial-native", QEMU_CAPS_NODEFCONFIG, diff --git a/tests/qemuxml2xmloutdata/pseries-features-htm.xml b/tests/qemuxml2xmloutdata/pseries-features-htm.xml new file mode 120000 index 000000000..42cf0f7d7 --- /dev/null +++ b/tests/qemuxml2xmloutdata/pseries-features-htm.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/pseries-features-htm.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index ba4e853f9..e97f17740 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -766,6 +766,9 @@ mymain(void) DO_TEST("pseries-features-hpt", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); + DO_TEST("pseries-features-htm", + QEMU_CAPS_MACHINE_OPT, + QEMU_CAPS_MACHINE_PSERIES_CAP_HTM); DO_TEST("pseries-serial-native", QEMU_CAPS_NODEFCONFIG, -- 2.14.3
participants (2)
-
Andrea Bolognani
-
Daniel P. Berrangé