diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 9ea37595a5..e98fe52ea6 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -50,6 +50,7 @@ #include "secret_util.h" #include "cpu/cpu.h" #include "xen_common.h" +#include "xen_xl.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -394,6 +395,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, def->cpu && def->cpu->mode == (VIR_CPU_MODE_HOST_PASSTHROUGH)) { bool hasHwVirt = false; bool svm = false, vmx = false; + char xlCPU[32]; /* enable nested HVM only if global nested_hvm option enable it and * host support it*/ @@ -411,17 +413,45 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, case VIR_CPU_FEATURE_DISABLE: case VIR_CPU_FEATURE_FORBID: if ((vmx && STREQ(def->cpu->features[i].name, "vmx")) || - (svm && STREQ(def->cpu->features[i].name, "svm"))) + (svm && STREQ(def->cpu->features[i].name, "svm"))) { hasHwVirt = false; + continue; + } + + snprintf(xlCPU, + sizeof(xlCPU), + "%s=0", + xenTranslateCPUFeature( + def->cpu->features[i].name, + false)); + if (libxl_cpuid_parse_config(&b_info->cpuid, xlCPU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported cpu feature '%s'"), + def->cpu->features[i].name); + return -1; + } break; case VIR_CPU_FEATURE_FORCE: case VIR_CPU_FEATURE_REQUIRE: if ((vmx && STREQ(def->cpu->features[i].name, "vmx")) || - (svm && STREQ(def->cpu->features[i].name, "svm"))) + (svm && STREQ(def->cpu->features[i].name, "svm"))) { hasHwVirt = true; - break; + continue; + } + snprintf(xlCPU, + sizeof(xlCPU), + "%s=1", + xenTranslateCPUFeature( + def->cpu->features[i].name, false)); + if (libxl_cpuid_parse_config(&b_info->cpuid, xlCPU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported cpu feature '%s'"), + def->cpu->features[i].name); + return -1; + } + break; case VIR_CPU_FEATURE_OPTIONAL: case VIR_CPU_FEATURE_LAST: break; diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c index ea5cacb2b8..f60ee088d1 100644 --- a/src/xenconfig/xen_xl.c +++ b/src/xenconfig/xen_xl.c @@ -218,6 +218,41 @@ xenParseXLOS(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps) return 0; } +/* + * Translate CPU feature name from libvirt to libxl (from_libxl=false) or from + * libxl to libvirt (from_libxl=true). + */ +const char * +xenTranslateCPUFeature(const char *feature_name, bool from_libxl) +{ + static const char *translation_table[][2] = { + /* libvirt name, libxl name */ + { "cx16", "cmpxchg16" }, + { "cid", "cntxid" }, + { "ds_cpl", "dscpl" }, + { "pclmuldq", "pclmulqdq" }, + { "pni", "sse3" }, + { "ht", "htt" }, + { "pn", "psn" }, + { "clflush", "clfsh" }, + { "sep", "sysenter" }, + { "cx8", "cmpxchg8" }, + { "nodeid_msr", "nodeid" }, + { "cr8legacy", "altmovcr8" }, + { "lahf_lm", "lahfsahf" }, + { "cmp_legacy", "cmplegacy" }, + { "fxsr_opt", "ffxsr" }, + { "pdpe1gb", "page1gb" }, + { "spec-ctrl", "ibrsb" }, + }; + size_t i; + + for (i = 0; i < ARRAY_CARDINALITY(translation_table); i++) + if (STREQ(translation_table[i][from_libxl], feature_name)) + return translation_table[i][!from_libxl]; + return feature_name; +} + static int xenParseXLSpice(virConfPtr conf, virDomainDefPtr def) diff --git a/src/xenconfig/xen_xl.h b/src/xenconfig/xen_xl.h index dd963268e0..68f332aca5 100644 --- a/src/xenconfig/xen_xl.h +++ b/src/xenconfig/xen_xl.h @@ -33,4 +33,6 @@ virDomainDefPtr xenParseXL(virConfPtr conn, virConfPtr xenFormatXL(virDomainDefPtr def, virConnectPtr); +const char *xenTranslateCPUFeature(const char *feature_name, bool from_libxl); + #endif /* __VIR_XEN_XL_H__ */