提交 0280fc72 编写于 作者: D Daniel Henrique Barboza 提交者: Michal Privoznik

qemu: Implement the CFPC pSeries feature

This patch adds the implementation of the CFPC pSeries feature,
using the QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC capability added
in the previous patch.

CPFC can have the values "broken", "workaround" or "fixed". Extra
code is required to handle it since it's not a regular tristate
capability.

This is the XML format for the cap:

<features>
  <cfpc value='workaround'/>
</features>
Signed-off-by: NDaniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NMichal Privoznik <mprivozn@redhat.com>
上级 a0a2c8ab
...@@ -2078,6 +2078,7 @@ ...@@ -2078,6 +2078,7 @@
&lt;htm state='on'/&gt; &lt;htm state='on'/&gt;
&lt;ccf-assist state='on'/&gt; &lt;ccf-assist state='on'/&gt;
&lt;msrs unknown='ignore'/&gt; &lt;msrs unknown='ignore'/&gt;
&lt;cfpc value='workaround'/&gt;
&lt;/features&gt; &lt;/features&gt;
...</pre> ...</pre>
...@@ -2406,6 +2407,16 @@ ...@@ -2406,6 +2407,16 @@
defined, the hypervisor default will be used. defined, the hypervisor default will be used.
<span class="since">Since 5.9.0</span> (QEMU/KVM only) <span class="since">Since 5.9.0</span> (QEMU/KVM only)
</dd> </dd>
<dt><code>cfpc</code></dt>
<dd>Configure cfpc (Cache Flush on Privilege Change) availability for
pSeries guests.
Possible values for the <code>value</code> attribute
are <code>broken</code> (no protection), <code>workaround</code>
(software workaround available) and <code>fixed</code> (fixed in
hardware). If the attribute is not defined, the hypervisor
default will be used.
<span class="since">Since 6.3.0</span> (QEMU/KVM only)
</dd>
</dl> </dl>
<h3><a id="elementsTime">Time keeping</a></h3> <h3><a id="elementsTime">Time keeping</a></h3>
......
...@@ -5434,6 +5434,9 @@ ...@@ -5434,6 +5434,9 @@
<ref name="featurestate"/> <ref name="featurestate"/>
</element> </element>
</optional> </optional>
<optional>
<ref name="cfpc"/>
</optional>
</interleave> </interleave>
</element> </element>
</optional> </optional>
...@@ -5693,6 +5696,18 @@ ...@@ -5693,6 +5696,18 @@
</element> </element>
</define> </define>
<define name="cfpc">
<element name="cfpc">
<attribute name="value">
<choice>
<value>broken</value>
<value>workaround</value>
<value>fixed</value>
</choice>
</attribute>
</element>
</define>
<define name="address"> <define name="address">
<element name="address"> <element name="address">
<choice> <choice>
......
...@@ -174,6 +174,7 @@ VIR_ENUM_IMPL(virDomainFeature, ...@@ -174,6 +174,7 @@ VIR_ENUM_IMPL(virDomainFeature,
"msrs", "msrs",
"ccf-assist", "ccf-assist",
"xen", "xen",
"cfpc",
); );
VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
...@@ -1266,6 +1267,14 @@ VIR_ENUM_IMPL(virDomainOsDefFirmware, ...@@ -1266,6 +1267,14 @@ VIR_ENUM_IMPL(virDomainOsDefFirmware,
"efi", "efi",
); );
VIR_ENUM_IMPL(virDomainCFPC,
VIR_DOMAIN_CFPC_LAST,
"none",
"broken",
"workaround",
"fixed",
);
/* Internal mapping: subset of block job types that can be present in /* Internal mapping: subset of block job types that can be present in
* <mirror> XML (remaining types are not two-phase). */ * <mirror> XML (remaining types are not two-phase). */
VIR_ENUM_DECL(virDomainBlockJob); VIR_ENUM_DECL(virDomainBlockJob);
...@@ -19326,6 +19335,21 @@ virDomainFeaturesDefParse(virDomainDefPtr def, ...@@ -19326,6 +19335,21 @@ virDomainFeaturesDefParse(virDomainDefPtr def,
} }
break; break;
case VIR_DOMAIN_FEATURE_CFPC:
tmp = virXMLPropString(nodes[i], "value");
if (tmp) {
int value = virDomainCFPCTypeFromString(tmp);
if (value < 0 || value == VIR_DOMAIN_CFPC_NONE) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown value: %s"),
tmp);
goto error;
}
def->features[val] = value;
VIR_FREE(tmp);
}
break;
case VIR_DOMAIN_FEATURE_HTM: case VIR_DOMAIN_FEATURE_HTM:
case VIR_DOMAIN_FEATURE_NESTED_HV: case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST: case VIR_DOMAIN_FEATURE_CCF_ASSIST:
...@@ -23377,6 +23401,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, ...@@ -23377,6 +23401,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
} }
break; break;
case VIR_DOMAIN_FEATURE_CFPC:
if (src->features[i] != dst->features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of feature '%s' differs: "
"source: '%s=%s', destination: '%s=%s'"),
featureName,
"value", virDomainCFPCTypeToString(src->features[i]),
"value", virDomainCFPCTypeToString(dst->features[i]));
return false;
}
break;
case VIR_DOMAIN_FEATURE_MSRS: case VIR_DOMAIN_FEATURE_MSRS:
break; break;
...@@ -29211,6 +29247,14 @@ virDomainDefFormatFeatures(virBufferPtr buf, ...@@ -29211,6 +29247,14 @@ virDomainDefFormatFeatures(virBufferPtr buf,
virDomainMsrsUnknownTypeToString(def->msrs_features[VIR_DOMAIN_MSRS_UNKNOWN])); virDomainMsrsUnknownTypeToString(def->msrs_features[VIR_DOMAIN_MSRS_UNKNOWN]));
break; break;
case VIR_DOMAIN_FEATURE_CFPC:
if (def->features[i] == VIR_DOMAIN_CFPC_NONE)
break;
virBufferAsprintf(&childBuf, "<cfpc value='%s'/>\n",
virDomainCFPCTypeToString(def->features[i]));
break;
/* coverity[dead_error_begin] */ /* coverity[dead_error_begin] */
case VIR_DOMAIN_FEATURE_LAST: case VIR_DOMAIN_FEATURE_LAST:
break; break;
...@@ -1816,6 +1816,7 @@ typedef enum { ...@@ -1816,6 +1816,7 @@ typedef enum {
VIR_DOMAIN_FEATURE_MSRS, VIR_DOMAIN_FEATURE_MSRS,
VIR_DOMAIN_FEATURE_CCF_ASSIST, VIR_DOMAIN_FEATURE_CCF_ASSIST,
VIR_DOMAIN_FEATURE_XEN, VIR_DOMAIN_FEATURE_XEN,
VIR_DOMAIN_FEATURE_CFPC,
VIR_DOMAIN_FEATURE_LAST VIR_DOMAIN_FEATURE_LAST
} virDomainFeature; } virDomainFeature;
...@@ -1987,6 +1988,17 @@ typedef enum { ...@@ -1987,6 +1988,17 @@ typedef enum {
VIR_ENUM_DECL(virDomainHPTResizing); VIR_ENUM_DECL(virDomainHPTResizing);
typedef enum {
VIR_DOMAIN_CFPC_NONE = 0,
VIR_DOMAIN_CFPC_BROKEN,
VIR_DOMAIN_CFPC_WORKAROUND,
VIR_DOMAIN_CFPC_FIXED,
VIR_DOMAIN_CFPC_LAST
} virDomainCFPC;
VIR_ENUM_DECL(virDomainCFPC);
/* Operating system configuration data & machine / arch */ /* Operating system configuration data & machine / arch */
struct _virDomainOSEnv { struct _virDomainOSEnv {
char *name; char *name;
......
...@@ -235,6 +235,8 @@ virDomainBlockIoTuneInfoHasMaxLength; ...@@ -235,6 +235,8 @@ virDomainBlockIoTuneInfoHasMaxLength;
virDomainBootTypeFromString; virDomainBootTypeFromString;
virDomainBootTypeToString; virDomainBootTypeToString;
virDomainCapabilitiesPolicyTypeToString; virDomainCapabilitiesPolicyTypeToString;
virDomainCFPCTypeFromString;
virDomainCFPCTypeToString;
virDomainChrConsoleTargetTypeFromString; virDomainChrConsoleTargetTypeFromString;
virDomainChrConsoleTargetTypeToString; virDomainChrConsoleTargetTypeToString;
virDomainChrDefForeach; virDomainChrDefForeach;
......
...@@ -7171,6 +7171,11 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, ...@@ -7171,6 +7171,11 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
virBufferAsprintf(&buf, ",cap-ccf-assist=%s", str); virBufferAsprintf(&buf, ",cap-ccf-assist=%s", str);
} }
if (def->features[VIR_DOMAIN_FEATURE_CFPC] != VIR_DOMAIN_CFPC_NONE) {
const char *str = virDomainCFPCTypeToString(def->features[VIR_DOMAIN_FEATURE_CFPC]);
virBufferAsprintf(&buf, ",cap-cfpc=%s", str);
}
if (cpu && cpu->model && if (cpu && cpu->model &&
cpu->mode == VIR_CPU_MODE_HOST_MODEL && cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
qemuDomainIsPSeries(def) && qemuDomainIsPSeries(def) &&
......
...@@ -136,6 +136,16 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def, ...@@ -136,6 +136,16 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
return -1; return -1;
} }
break;
case VIR_DOMAIN_FEATURE_CFPC:
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("cfpc configuration is not supported by "
"this QEMU binary"));
return -1;
}
break; break;
} }
...@@ -194,6 +204,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, ...@@ -194,6 +204,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
case VIR_DOMAIN_FEATURE_HTM: case VIR_DOMAIN_FEATURE_HTM:
case VIR_DOMAIN_FEATURE_NESTED_HV: case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST: case VIR_DOMAIN_FEATURE_CCF_ASSIST:
case VIR_DOMAIN_FEATURE_CFPC:
if (qemuValidateDomainDefPSeriesFeature(def, qemuCaps, i) < 0) if (qemuValidateDomainDefPSeriesFeature(def, qemuCaps, i) < 0)
return -1; return -1;
break; break;
......
...@@ -11,7 +11,8 @@ QEMU_AUDIO_DRV=none \ ...@@ -11,7 +11,8 @@ QEMU_AUDIO_DRV=none \
-name guest \ -name guest \
-S \ -S \
-machine pseries,accel=tcg,usb=off,dump-guest-core=off,resize-hpt=required,\ -machine pseries,accel=tcg,usb=off,dump-guest-core=off,resize-hpt=required,\
cap-hpt-max-page-size=1048576k,cap-htm=on,cap-nested-hv=off,cap-ccf-assist=on \ cap-hpt-max-page-size=1048576k,cap-htm=on,cap-nested-hv=off,cap-ccf-assist=on,\
cap-cfpc=fixed \
-m 512 \ -m 512 \
-realtime mlock=off \ -realtime mlock=off \
-smp 1,sockets=1,cores=1,threads=1 \ -smp 1,sockets=1,cores=1,threads=1 \
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
<htm state='on'/> <htm state='on'/>
<nested-hv state='off'/> <nested-hv state='off'/>
<ccf-assist state='on'/> <ccf-assist state='on'/>
<cfpc value='fixed'/>
</features> </features>
<devices> <devices>
<emulator>/usr/bin/qemu-system-ppc64</emulator> <emulator>/usr/bin/qemu-system-ppc64</emulator>
......
...@@ -1964,6 +1964,7 @@ mymain(void) ...@@ -1964,6 +1964,7 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
/* parse error: no QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT */ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT */
...@@ -1972,7 +1973,8 @@ mymain(void) ...@@ -1972,7 +1973,8 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST); QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC);
/* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE */ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE */
DO_TEST_PARSE_ERROR("pseries-features", DO_TEST_PARSE_ERROR("pseries-features",
...@@ -1980,6 +1982,7 @@ mymain(void) ...@@ -1980,6 +1982,7 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
/* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HTM */ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HTM */
...@@ -1988,6 +1991,7 @@ mymain(void) ...@@ -1988,6 +1991,7 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
/* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV */ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV */
...@@ -1996,6 +2000,7 @@ mymain(void) ...@@ -1996,6 +2000,7 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
/* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST */ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST */
...@@ -2004,8 +2009,18 @@ mymain(void) ...@@ -2004,8 +2009,18 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE, QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
/* parse error: no QEMU_CAPS_MACHINE_PSERIES_CFPC */
DO_TEST_PARSE_ERROR("pseries-features",
QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT,
QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST);
DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", NONE); DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", NONE);
DO_TEST("pseries-serial-native", DO_TEST("pseries-serial-native",
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<htm state='on'/> <htm state='on'/>
<nested-hv state='off'/> <nested-hv state='off'/>
<ccf-assist state='on'/> <ccf-assist state='on'/>
<cfpc value='fixed'/>
</features> </features>
<clock offset='utc'/> <clock offset='utc'/>
<on_poweroff>destroy</on_poweroff> <on_poweroff>destroy</on_poweroff>
......
...@@ -695,7 +695,8 @@ mymain(void) ...@@ -695,7 +695,8 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT); QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT,
QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC);
DO_TEST("pseries-serial-native", DO_TEST("pseries-serial-native",
QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册