[libvirt] [PATCH v4 7/8] xenconfig: add CPUID handling to domXML <-> xl.cfg conversion
Jim Fehlig
jfehlig at suse.com
Mon Feb 26 23:14:58 UTC 2018
On 02/08/2018 03:59 PM, Marek Marczykowski-Górecki wrote:
> Only "libxl" format supported for now. Special care needed around
> vmx/svm, because those two are translated into "nestedhvm" setting.
>
> ---
> Changes since v3:
> - improve error reporting (VIR_ERR_CONF_SYNTAX)
> - ignore empty cpuid option - same as libxl
> - fix cleanup on error
> Changes since v2:
> - new patch
> ---
> src/xenconfig/xen_xl.c | 165 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 165 insertions(+)
Reviewed-by: Jim Fehlig <jfehlig at suse.com>
Regards,
Jim
>
> diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
> index d5dff59..ffec0ba 100644
> --- a/src/xenconfig/xen_xl.c
> +++ b/src/xenconfig/xen_xl.c
> @@ -252,6 +252,91 @@ xenTranslateCPUFeature(const char *feature_name, bool from_libxl)
> return feature_name;
> }
>
> +static int
> +xenParseXLCPUID(virConfPtr conf, virDomainDefPtr def)
> +{
> + const char *cpuid_str = NULL;
> + char **cpuid_pairs = NULL;
> + char **name_and_value = NULL;
> + size_t i;
> + int ret = -1;
> + int policy;
> +
> + if (xenConfigGetString(conf, "cpuid", &cpuid_str, NULL) < 0)
> + return -1;
> +
> + if (!cpuid_str)
> + return 0;
> +
> + if (!def->cpu) {
> + if (VIR_ALLOC(def->cpu) < 0)
> + goto cleanup;
> + def->cpu->mode = VIR_CPU_MODE_HOST_PASSTHROUGH;
> + def->cpu->type = VIR_CPU_TYPE_GUEST;
> + def->cpu->nfeatures = 0;
> + def->cpu->nfeatures_max = 0;
> + }
> +
> + cpuid_pairs = virStringSplit(cpuid_str, ",", 0);
> + if (!cpuid_pairs)
> + goto cleanup;
> +
> + if (!cpuid_pairs[0]) {
> + ret = 0;
> + goto cleanup;
> + }
> +
> + if (STRNEQ(cpuid_pairs[0], "host")) {
> + virReportError(VIR_ERR_CONF_SYNTAX,
> + _("cpuid starting with %s is not supported, only libxl format is"),
> + cpuid_pairs[0]);
> + goto cleanup;
> + }
> +
> + for (i = 1; cpuid_pairs[i]; i++) {
> + name_and_value = virStringSplit(cpuid_pairs[i], "=", 2);
> + if (!name_and_value)
> + goto cleanup;
> + if (!name_and_value[0] || !name_and_value[1]) {
> + virReportError(VIR_ERR_CONF_SYNTAX,
> + _("Invalid libxl cpuid key=value element: %s"),
> + cpuid_pairs[i]);
> + goto cleanup;
> + }
> + if (STREQ(name_and_value[1], "1")) {
> + policy = VIR_CPU_FEATURE_FORCE;
> + } else if (STREQ(name_and_value[1], "0")) {
> + policy = VIR_CPU_FEATURE_DISABLE;
> + } else if (STREQ(name_and_value[1], "x")) {
> + policy = VIR_CPU_FEATURE_OPTIONAL;
> + } else if (STREQ(name_and_value[1], "k")) {
> + policy = VIR_CPU_FEATURE_OPTIONAL;
> + } else if (STREQ(name_and_value[1], "s")) {
> + policy = VIR_CPU_FEATURE_OPTIONAL;
> + } else {
> + virReportError(VIR_ERR_CONF_SYNTAX,
> + _("Invalid libxl cpuid value: %s"),
> + cpuid_pairs[i]);
> + goto cleanup;
> + }
> +
> + if (virCPUDefAddFeature(def->cpu,
> + xenTranslateCPUFeature(name_and_value[0], true),
> + policy) < 0)
> + goto cleanup;
> +
> + virStringListFree(name_and_value);
> + name_and_value = NULL;
> + }
> +
> + ret = 0;
> +
> + cleanup:
> + virStringListFree(name_and_value);
> + virStringListFree(cpuid_pairs);
> + return ret;
> +}
> +
>
> static int
> xenParseXLSpice(virConfPtr conf, virDomainDefPtr def)
> @@ -1089,6 +1174,9 @@ xenParseXL(virConfPtr conf,
> goto cleanup;
> #endif
>
> + if (xenParseXLCPUID(conf, def) < 0)
> + goto cleanup;
> +
> if (xenParseXLDisk(conf, def) < 0)
> goto cleanup;
>
> @@ -1231,6 +1319,80 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
> return 0;
> }
>
> +static int
> +xenFormatXLCPUID(virConfPtr conf, virDomainDefPtr def)
> +{
> + char **cpuid_pairs = NULL;
> + char *cpuid_string = NULL;
> + size_t i, j;
> + int ret = -1;
> +
> + if (!def->cpu)
> + return 0;
> +
> + if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("'%s' CPU mode not supported, only host-passthrough is"),
> + virCPUModeTypeToString(def->cpu->mode));
> + return -1;
> + }
> +
> + /* "host" + all features + NULL */
> + if (VIR_ALLOC_N(cpuid_pairs, def->cpu->nfeatures + 2) < 0)
> + return -1;
> +
> + if (VIR_STRDUP(cpuid_pairs[0], "host") < 0)
> + goto cleanup;
> +
> + j = 1;
> + for (i = 0; i < def->cpu->nfeatures; i++) {
> + const char *feature_name = xenTranslateCPUFeature(
> + def->cpu->features[i].name,
> + false);
> + const char *policy = NULL;
> +
> + if (STREQ(feature_name, "vmx") || STREQ(feature_name, "svm"))
> + /* ignore vmx/svm in cpuid option, translated into nestedhvm
> + * elsewhere */
> + continue;
> +
> + switch (def->cpu->features[i].policy) {
> + case VIR_CPU_FEATURE_FORCE:
> + case VIR_CPU_FEATURE_REQUIRE:
> + policy = "1";
> + break;
> + case VIR_CPU_FEATURE_OPTIONAL:
> + policy = "x";
> + break;
> + case VIR_CPU_FEATURE_DISABLE:
> + case VIR_CPU_FEATURE_FORBID:
> + policy = "0";
> + break;
> + }
> + if (virAsprintf(&cpuid_pairs[j++], "%s=%s",
> + feature_name,
> + policy) < 0)
> + goto cleanup;
> + }
> + cpuid_pairs[j] = NULL;
> +
> + if (j > 1) {
> + cpuid_string = virStringListJoin((const char **)cpuid_pairs, ",");
> + if (!cpuid_string)
> + goto cleanup;
> +
> + if (xenConfigSetString(conf, "cpuid", cpuid_string) < 0)
> + goto cleanup;
> + }
> +
> + ret = 0;
> +
> + cleanup:
> + virStringListFree(cpuid_pairs);
> + VIR_FREE(cpuid_string);
> + return ret;
> +}
> +
> #ifdef LIBXL_HAVE_VNUMA
> static int
> xenFormatXLVnode(virConfValuePtr list,
> @@ -1996,6 +2158,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn)
> if (xenFormatXLOS(conf, def) < 0)
> goto cleanup;
>
> + if (xenFormatXLCPUID(conf, def) < 0)
> + goto cleanup;
> +
> #ifdef LIBXL_HAVE_VNUMA
> if (xenFormatXLDomainVnuma(conf, def) < 0)
> goto cleanup;
>
More information about the libvir-list
mailing list