libxl: use the cpuid feature names from cpufeatureset.h

The current implementation in libxl_cpuid_parse_config() requires
keeping a list of cpuid feature bits that should be mostly in sync
with the contents of cpufeatureset.h.

Avoid such duplication by using the automatically generated list of
cpuid features in INIT_FEATURE_NAMES in order to map feature names to
featureset bits, and then translate from featureset bits into cpuid
leaf, subleaf, register tuple.

Note that the full contents of the previous cpuid translation table
can't be removed.  That's because some feature names allowed by libxl
are not described in the featuresets, or because naming has diverged
and the previous nomenclature is preserved for compatibility reasons.

Should result in no functional change observed by callers, albeit some
new cpuid features will be available as a result of the change.

While there constify cpuid_flags name field.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
(cherry picked from commit d638fe233c)
This commit is contained in:
Roger Pau Monne authored and Andrew Cooper committed 2023-08-03 19:13:40 +01:00
1 parent bfcf0def25
commit fcd4f8387f
3 files changed
+106 -165

No files matched your search

+8 -16
View File
@@ -1957,24 +1957,16 @@ proccount procpkg stepping
=back
List of keys taking a character:
List of keys taking a character can be found in the public header file
L<arch-x86/cpufeatureset.h|https://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,arch-x86,cpufeatureset.h.html>
=over 4
The feature names described in C<cpufeatureset.h> should be specified in all
lowercase letters, and with underscores converted to hyphens. For example in
order to reference feature C<LAHF_LM> the string C<lahf-lm> should be used.
3dnow 3dnowext 3dnowprefetch abm acpi adx aes altmovcr8 apic arat avx avx2
avx512-4fmaps avx512-4vnniw avx512bw avx512cd avx512dq avx512er avx512f
avx512ifma avx512pf avx512vbmi avx512vl bmi1 bmi2 clflushopt clfsh clwb cmov
cmplegacy cmpxchg16 cmpxchg8 cmt cntxid dca de ds dscpl dtes64 erms est extapic
f16c ffxsr fma fma4 fpu fsgsbase fxsr hle htt hypervisor ia64 ibs invpcid
invtsc lahfsahf lm lwp mca mce misalignsse mmx mmxext monitor movbe mpx msr
mtrr nodeid nx ospke osvw osxsave pae page1gb pat pbe pcid pclmulqdq pdcm
perfctr_core perfctr_nb pge pku popcnt pse pse36 psn rdrand rdseed rdtscp rtm
sha skinit smap smep smx ss sse sse2 sse3 sse4.1 sse4.2 sse4_1 sse4_2 sse4a
ssse3 svm svm_decode svm_lbrv svm_npt svm_nrips svm_pausefilt svm_tscrate
svm_vmcbclean syscall sysenter tbm tm tm2 topoext tsc tsc-deadline tsc_adjust
umip vme vmx wdt x2apic xop xsave xtpr
=back
Note that C<clflush> is described as an option that takes a value, and that
takes precedence over the C<clflush> flag in C<cpufeatureset.h>. The feature
flag must be referenced as C<clfsh>.
=back
+95 -149
View File
@@ -14,6 +14,8 @@
#include "libxl_internal.h"
#include <xen/lib/x86/cpu-policy.h>
int libxl__cpuid_policy_is_empty(libxl_cpuid_policy_list *pl)
{
return !*pl || (!libxl_cpuid_policy_list_length(pl) && !(*pl)->msr);
@@ -60,7 +62,7 @@ void libxl_cpuid_dispose(libxl_cpuid_policy_list *pl)
* Used for the static structure describing all features.
*/
struct cpuid_flags {
char* name;
const char *name;
uint32_t leaf;
uint32_t subleaf;
int reg;
@@ -153,7 +155,19 @@ static int cpuid_add(libxl_cpuid_policy_list *policy,
entry->policy[flag->reg - 1] = resstr;
return 0;
}
struct feature_name {
const char *name;
unsigned int bit;
};
static int search_feature(const void *a, const void *b)
{
const char *key = a;
const char *feat = ((const struct feature_name *)b)->name;
return strcmp(key, feat);
}
/* parse a single key=value pair and translate it into the libxc
@@ -176,190 +190,42 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str)
{"proccount", 0x00000001, NA, CPUID_REG_EBX, 16, 8},
{"localapicid", 0x00000001, NA, CPUID_REG_EBX, 24, 8},
{"sse3", 0x00000001, NA, CPUID_REG_ECX, 0, 1},
{"pclmulqdq", 0x00000001, NA, CPUID_REG_ECX, 1, 1},
{"dtes64", 0x00000001, NA, CPUID_REG_ECX, 2, 1},
{"monitor", 0x00000001, NA, CPUID_REG_ECX, 3, 1},
{"dscpl", 0x00000001, NA, CPUID_REG_ECX, 4, 1},
{"vmx", 0x00000001, NA, CPUID_REG_ECX, 5, 1},
{"smx", 0x00000001, NA, CPUID_REG_ECX, 6, 1},
{"est", 0x00000001, NA, CPUID_REG_ECX, 7, 1},
{"tm2", 0x00000001, NA, CPUID_REG_ECX, 8, 1},
{"ssse3", 0x00000001, NA, CPUID_REG_ECX, 9, 1},
{"cntxid", 0x00000001, NA, CPUID_REG_ECX, 10, 1},
{"fma", 0x00000001, NA, CPUID_REG_ECX, 12, 1},
{"cmpxchg16", 0x00000001, NA, CPUID_REG_ECX, 13, 1},
{"xtpr", 0x00000001, NA, CPUID_REG_ECX, 14, 1},
{"pdcm", 0x00000001, NA, CPUID_REG_ECX, 15, 1},
{"pcid", 0x00000001, NA, CPUID_REG_ECX, 17, 1},
{"dca", 0x00000001, NA, CPUID_REG_ECX, 18, 1},
/* Linux uses sse4_{1,2}. Keep sse4.{1,2} for compatibility */
{"sse4_1", 0x00000001, NA, CPUID_REG_ECX, 19, 1},
{"sse4.1", 0x00000001, NA, CPUID_REG_ECX, 19, 1},
{"sse4_2", 0x00000001, NA, CPUID_REG_ECX, 20, 1},
{"sse4.2", 0x00000001, NA, CPUID_REG_ECX, 20, 1},
{"x2apic", 0x00000001, NA, CPUID_REG_ECX, 21, 1},
{"movbe", 0x00000001, NA, CPUID_REG_ECX, 22, 1},
{"popcnt", 0x00000001, NA, CPUID_REG_ECX, 23, 1},
{"tsc-deadline", 0x00000001, NA, CPUID_REG_ECX, 24, 1},
{"aes", 0x00000001, NA, CPUID_REG_ECX, 25, 1},
{"xsave", 0x00000001, NA, CPUID_REG_ECX, 26, 1},
{"osxsave", 0x00000001, NA, CPUID_REG_ECX, 27, 1},
{"avx", 0x00000001, NA, CPUID_REG_ECX, 28, 1},
{"f16c", 0x00000001, NA, CPUID_REG_ECX, 29, 1},
{"rdrand", 0x00000001, NA, CPUID_REG_ECX, 30, 1},
{"hypervisor", 0x00000001, NA, CPUID_REG_ECX, 31, 1},
{"fpu", 0x00000001, NA, CPUID_REG_EDX, 0, 1},
{"vme", 0x00000001, NA, CPUID_REG_EDX, 1, 1},
{"de", 0x00000001, NA, CPUID_REG_EDX, 2, 1},
{"pse", 0x00000001, NA, CPUID_REG_EDX, 3, 1},
{"tsc", 0x00000001, NA, CPUID_REG_EDX, 4, 1},
{"msr", 0x00000001, NA, CPUID_REG_EDX, 5, 1},
{"pae", 0x00000001, NA, CPUID_REG_EDX, 6, 1},
{"mce", 0x00000001, NA, CPUID_REG_EDX, 7, 1},
{"cmpxchg8", 0x00000001, NA, CPUID_REG_EDX, 8, 1},
{"apic", 0x00000001, NA, CPUID_REG_EDX, 9, 1},
{"sysenter", 0x00000001, NA, CPUID_REG_EDX, 11, 1},
{"mtrr", 0x00000001, NA, CPUID_REG_EDX, 12, 1},
{"pge", 0x00000001, NA, CPUID_REG_EDX, 13, 1},
{"mca", 0x00000001, NA, CPUID_REG_EDX, 14, 1},
{"cmov", 0x00000001, NA, CPUID_REG_EDX, 15, 1},
{"pat", 0x00000001, NA, CPUID_REG_EDX, 16, 1},
{"pse36", 0x00000001, NA, CPUID_REG_EDX, 17, 1},
{"psn", 0x00000001, NA, CPUID_REG_EDX, 18, 1},
{"clfsh", 0x00000001, NA, CPUID_REG_EDX, 19, 1},
{"ds", 0x00000001, NA, CPUID_REG_EDX, 21, 1},
{"acpi", 0x00000001, NA, CPUID_REG_EDX, 22, 1},
{"mmx", 0x00000001, NA, CPUID_REG_EDX, 23, 1},
{"fxsr", 0x00000001, NA, CPUID_REG_EDX, 24, 1},
{"sse", 0x00000001, NA, CPUID_REG_EDX, 25, 1},
{"sse2", 0x00000001, NA, CPUID_REG_EDX, 26, 1},
{"ss", 0x00000001, NA, CPUID_REG_EDX, 27, 1},
{"htt", 0x00000001, NA, CPUID_REG_EDX, 28, 1},
{"tm", 0x00000001, NA, CPUID_REG_EDX, 29, 1},
{"ia64", 0x00000001, NA, CPUID_REG_EDX, 30, 1},
{"pbe", 0x00000001, NA, CPUID_REG_EDX, 31, 1},
{"arat", 0x00000006, NA, CPUID_REG_EAX, 2, 1},
{"fsgsbase", 0x00000007, 0, CPUID_REG_EBX, 0, 1},
{"tsc_adjust", 0x00000007, 0, CPUID_REG_EBX, 1, 1},
{"bmi1", 0x00000007, 0, CPUID_REG_EBX, 3, 1},
{"hle", 0x00000007, 0, CPUID_REG_EBX, 4, 1},
{"avx2", 0x00000007, 0, CPUID_REG_EBX, 5, 1},
{"smep", 0x00000007, 0, CPUID_REG_EBX, 7, 1},
{"bmi2", 0x00000007, 0, CPUID_REG_EBX, 8, 1},
{"erms", 0x00000007, 0, CPUID_REG_EBX, 9, 1},
{"invpcid", 0x00000007, 0, CPUID_REG_EBX, 10, 1},
{"rtm", 0x00000007, 0, CPUID_REG_EBX, 11, 1},
{"cmt", 0x00000007, 0, CPUID_REG_EBX, 12, 1},
{"mpx", 0x00000007, 0, CPUID_REG_EBX, 14, 1},
{"avx512f", 0x00000007, 0, CPUID_REG_EBX, 16, 1},
{"avx512dq", 0x00000007, 0, CPUID_REG_EBX, 17, 1},
{"rdseed", 0x00000007, 0, CPUID_REG_EBX, 18, 1},
{"adx", 0x00000007, 0, CPUID_REG_EBX, 19, 1},
{"smap", 0x00000007, 0, CPUID_REG_EBX, 20, 1},
{"avx512-ifma", 0x00000007, 0, CPUID_REG_EBX, 21, 1},
{"clflushopt", 0x00000007, 0, CPUID_REG_EBX, 23, 1},
{"clwb", 0x00000007, 0, CPUID_REG_EBX, 24, 1},
{"proc-trace", 0x00000007, 0, CPUID_REG_EBX, 25, 1},
{"avx512pf", 0x00000007, 0, CPUID_REG_EBX, 26, 1},
{"avx512er", 0x00000007, 0, CPUID_REG_EBX, 27, 1},
{"avx512cd", 0x00000007, 0, CPUID_REG_EBX, 28, 1},
{"sha", 0x00000007, 0, CPUID_REG_EBX, 29, 1},
{"avx512bw", 0x00000007, 0, CPUID_REG_EBX, 30, 1},
{"avx512vl", 0x00000007, 0, CPUID_REG_EBX, 31, 1},
{"prefetchwt1", 0x00000007, 0, CPUID_REG_ECX, 0, 1},
{"avx512-vbmi", 0x00000007, 0, CPUID_REG_ECX, 1, 1},
{"umip", 0x00000007, 0, CPUID_REG_ECX, 2, 1},
{"pku", 0x00000007, 0, CPUID_REG_ECX, 3, 1},
{"ospke", 0x00000007, 0, CPUID_REG_ECX, 4, 1},
{"avx512-vbmi2", 0x00000007, 0, CPUID_REG_ECX, 6, 1},
{"cet-ss", 0x00000007, 0, CPUID_REG_ECX, 7, 1},
{"gfni", 0x00000007, 0, CPUID_REG_ECX, 8, 1},
{"vaes", 0x00000007, 0, CPUID_REG_ECX, 9, 1},
{"vpclmulqdq", 0x00000007, 0, CPUID_REG_ECX, 10, 1},
{"avx512-vnni", 0x00000007, 0, CPUID_REG_ECX, 11, 1},
{"avx512-bitalg",0x00000007, 0, CPUID_REG_ECX, 12, 1},
{"avx512-vpopcntdq",0x00000007,0,CPUID_REG_ECX, 14, 1},
{"rdpid", 0x00000007, 0, CPUID_REG_ECX, 22, 1},
{"cldemote", 0x00000007, 0, CPUID_REG_ECX, 25, 1},
{"avx512-4vnniw",0x00000007, 0, CPUID_REG_EDX, 2, 1},
{"avx512-4fmaps",0x00000007, 0, CPUID_REG_EDX, 3, 1},
{"avx512-vp2intersect",0x00000007,0,CPUID_REG_EDX,8, 1},
{"srbds-ctrl", 0x00000007, 0, CPUID_REG_EDX, 9, 1},
{"md-clear", 0x00000007, 0, CPUID_REG_EDX, 10, 1},
{"serialize", 0x00000007, 0, CPUID_REG_EDX, 14, 1},
{"tsxldtrk", 0x00000007, 0, CPUID_REG_EDX, 16, 1},
{"cet-ibt", 0x00000007, 0, CPUID_REG_EDX, 20, 1},
{"ibrsb", 0x00000007, 0, CPUID_REG_EDX, 26, 1},
{"stibp", 0x00000007, 0, CPUID_REG_EDX, 27, 1},
{"l1d-flush", 0x00000007, 0, CPUID_REG_EDX, 28, 1},
{"arch-caps", 0x00000007, 0, CPUID_REG_EDX, 29, 1},
{"core-caps", 0x00000007, 0, CPUID_REG_EDX, 30, 1},
{"ssbd", 0x00000007, 0, CPUID_REG_EDX, 31, 1},
{"avx-vnni", 0x00000007, 1, CPUID_REG_EAX, 4, 1},
{"avx512-bf16", 0x00000007, 1, CPUID_REG_EAX, 5, 1},
{"intel-psfd", 0x00000007, 2, CPUID_REG_EDX, 0, 1},
{"lahfsahf", 0x80000001, NA, CPUID_REG_ECX, 0, 1},
{"cmplegacy", 0x80000001, NA, CPUID_REG_ECX, 1, 1},
{"svm", 0x80000001, NA, CPUID_REG_ECX, 2, 1},
{"extapic", 0x80000001, NA, CPUID_REG_ECX, 3, 1},
{"altmovcr8", 0x80000001, NA, CPUID_REG_ECX, 4, 1},
{"abm", 0x80000001, NA, CPUID_REG_ECX, 5, 1},
{"sse4a", 0x80000001, NA, CPUID_REG_ECX, 6, 1},
{"misalignsse", 0x80000001, NA, CPUID_REG_ECX, 7, 1},
{"3dnowprefetch",0x80000001, NA, CPUID_REG_ECX, 8, 1},
{"osvw", 0x80000001, NA, CPUID_REG_ECX, 9, 1},
{"ibs", 0x80000001, NA, CPUID_REG_ECX, 10, 1},
{"xop", 0x80000001, NA, CPUID_REG_ECX, 11, 1},
{"skinit", 0x80000001, NA, CPUID_REG_ECX, 12, 1},
{"wdt", 0x80000001, NA, CPUID_REG_ECX, 13, 1},
{"lwp", 0x80000001, NA, CPUID_REG_ECX, 15, 1},
{"fma4", 0x80000001, NA, CPUID_REG_ECX, 16, 1},
{"nodeid", 0x80000001, NA, CPUID_REG_ECX, 19, 1},
{"tbm", 0x80000001, NA, CPUID_REG_ECX, 21, 1},
{"topoext", 0x80000001, NA, CPUID_REG_ECX, 22, 1},
{"perfctr_core", 0x80000001, NA, CPUID_REG_ECX, 23, 1},
{"perfctr_nb", 0x80000001, NA, CPUID_REG_ECX, 24, 1},
{"syscall", 0x80000001, NA, CPUID_REG_EDX, 11, 1},
{"nx", 0x80000001, NA, CPUID_REG_EDX, 20, 1},
{"mmxext", 0x80000001, NA, CPUID_REG_EDX, 22, 1},
{"ffxsr", 0x80000001, NA, CPUID_REG_EDX, 25, 1},
{"page1gb", 0x80000001, NA, CPUID_REG_EDX, 26, 1},
{"rdtscp", 0x80000001, NA, CPUID_REG_EDX, 27, 1},
{"lm", 0x80000001, NA, CPUID_REG_EDX, 29, 1},
{"3dnowext", 0x80000001, NA, CPUID_REG_EDX, 30, 1},
{"3dnow", 0x80000001, NA, CPUID_REG_EDX, 31, 1},
{"procpkg", 0x00000004, 0, CPUID_REG_EAX, 26, 6},
{"invtsc", 0x80000007, NA, CPUID_REG_EDX, 8, 1},
{"clzero", 0x80000008, NA, CPUID_REG_EBX, 0, 1},
{"rstr-fp-err-ptrs", 0x80000008, NA, CPUID_REG_EBX, 2, 1},
{"wbnoinvd", 0x80000008, NA, CPUID_REG_EBX, 9, 1},
{"ibpb", 0x80000008, NA, CPUID_REG_EBX, 12, 1},
{"ibrs", 0x80000008, NA, CPUID_REG_EBX, 14, 1},
{"amd-stibp", 0x80000008, NA, CPUID_REG_EBX, 15, 1},
{"ibrs-always", 0x80000008, NA, CPUID_REG_EBX, 16, 1},
{"stibp-always", 0x80000008, NA, CPUID_REG_EBX, 17, 1},
{"ibrs-fast", 0x80000008, NA, CPUID_REG_EBX, 18, 1},
{"ibrs-same-mode", 0x80000008, NA, CPUID_REG_EBX, 19, 1},
{"ppin", 0x80000008, NA, CPUID_REG_EBX, 23, 1},
{"amd-ssbd", 0x80000008, NA, CPUID_REG_EBX, 24, 1},
{"virt-ssbd", 0x80000008, NA, CPUID_REG_EBX, 25, 1},
{"ssb-no", 0x80000008, NA, CPUID_REG_EBX, 26, 1},
{"psfd", 0x80000008, NA, CPUID_REG_EBX, 28, 1},
{"btc-no", 0x80000008, NA, CPUID_REG_EBX, 29, 1},
{"ibpb-ret", 0x80000008, NA, CPUID_REG_EBX, 30, 1},
{"nc", 0x80000008, NA, CPUID_REG_ECX, 0, 8},
{"apicidsize", 0x80000008, NA, CPUID_REG_ECX, 12, 4},
@@ -378,9 +244,58 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str)
{NULL, 0, NA, CPUID_REG_INV, 0, 0}
};
static const struct feature_name features[] = INIT_FEATURE_NAMES;
/*
* NB: if we switch to using a cpu_policy derived object instead of a
* libxl_cpuid_policy_list we could get rid of the featureset -> cpuid leaf
* conversion table and use a featureset directly as we have conversions
* to/from featureset and cpu_policy.
*/
static const struct {
enum { FEAT_CPUID, FEAT_MSR } type;
union {
struct {
uint32_t leaf, subleaf;
unsigned int reg;
} cpuid;
struct {
uint32_t index;
unsigned int reg;
} msr;
};
} feature_to_policy[] = {
#define CPUID_ENTRY(l, s, r) \
{ .type = FEAT_CPUID, .cpuid.leaf = l, .cpuid.subleaf = s, .cpuid.reg = r }
#define MSR_ENTRY(i, r) \
{ .type = FEAT_MSR, .msr.index = i, .msr.reg = r }
CPUID_ENTRY(0x00000001, NA, CPUID_REG_EDX),
CPUID_ENTRY(0x00000001, NA, CPUID_REG_ECX),
CPUID_ENTRY(0x80000001, NA, CPUID_REG_EDX),
CPUID_ENTRY(0x80000001, NA, CPUID_REG_ECX),
CPUID_ENTRY(0x0000000D, 1, CPUID_REG_EAX),
CPUID_ENTRY(0x00000007, 0, CPUID_REG_EBX),
CPUID_ENTRY(0x00000007, 0, CPUID_REG_ECX),
CPUID_ENTRY(0x80000007, NA, CPUID_REG_EDX),
CPUID_ENTRY(0x80000008, NA, CPUID_REG_EBX),
CPUID_ENTRY(0x00000007, 0, CPUID_REG_EDX),
CPUID_ENTRY(0x00000007, 1, CPUID_REG_EAX),
CPUID_ENTRY(0x80000021, NA, CPUID_REG_EAX),
CPUID_ENTRY(0x00000007, 1, CPUID_REG_EBX),
CPUID_ENTRY(0x00000007, 2, CPUID_REG_EDX),
CPUID_ENTRY(0x00000007, 1, CPUID_REG_ECX),
CPUID_ENTRY(0x00000007, 1, CPUID_REG_EDX),
MSR_ENTRY(0x10a, CPUID_REG_EAX),
MSR_ENTRY(0x10a, CPUID_REG_EDX),
#undef MSR_ENTRY
#undef CPUID_ENTRY
};
#undef NA
const char *sep, *val;
char *name;
const struct cpuid_flags *flag;
const struct feature_name *feat;
BUILD_BUG_ON(ARRAY_SIZE(feature_to_policy) != FEATURESET_NR_ENTRIES);
sep = strchr(str, '=');
if (sep == NULL) {
@@ -393,6 +308,37 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str)
return cpuid_add(policy, flag, val);
}
/* Provide a NUL terminated feature name to the search helper. */
name = strndup(str, sep - str);
if (name == NULL)
return ERROR_NOMEM;
feat = bsearch(name, features, ARRAY_SIZE(features), sizeof(features[0]),
search_feature);
free(name);
if (feat == NULL)
return 2;
switch (feature_to_policy[feat->bit / 32].type) {
case FEAT_CPUID:
{
struct cpuid_flags f;
f.name = feat->name;
f.leaf = feature_to_policy[feat->bit / 32].cpuid.leaf;
f.subleaf = feature_to_policy[feat->bit / 32].cpuid.subleaf;
f.reg = feature_to_policy[feat->bit / 32].cpuid.reg;
f.bit = feat->bit % 32;
f.length = 1;
return cpuid_add(policy, &f, val);
}
case FEAT_MSR:
return 2;
}
return 2;
}
+3
View File
@@ -2471,6 +2471,9 @@ skip_usbdev:
case 3:
errstr = "illegal CPUID value (must be: [0|1|x|k|s])";
break;
case ERROR_NOMEM:
errstr = "out of memory";
break;
default:
errstr = "unknown error";
break;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.