libxl: add support for CPUID features policy

Convert CPU features policy into libxl cpuid policy settings. Use new
("libxl") syntax, which allow to enable/disable specific bits, using
host CPU as a base. For this reason, only "host-passthrough" mode is
accepted.
Libxl do not have distinction between "force" and "required" policy
(there is only "force") and also between "forbid" and "disable" (there
is only "disable"). So, merge them appropriately. If anything, "require"
and "forbid" should be enforced outside of specific driver.
Nested HVM (vmx and svm features) is handled separately, so exclude it
from translation.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Marek Marczykowski-Górecki 2018-04-12 03:03:24 +02:00 committed by Jim Fehlig
parent 69eded56b8
commit cc9af5631d
3 changed files with 70 additions and 3 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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__ */