@@ -2010,24 +2010,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
-
-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
+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.
-=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
@@ -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,208 +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},
- {"pks", 0x00000007, 0, CPUID_REG_ECX, 31, 1},
-
- {"avx512-4vnniw",0x00000007, 0, CPUID_REG_EDX, 2, 1},
- {"avx512-4fmaps",0x00000007, 0, CPUID_REG_EDX, 3, 1},
- {"fsrm", 0x00000007, 0, CPUID_REG_EDX, 4, 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},
- {"avx512-fp16", 0x00000007, 0, CPUID_REG_EDX, 23, 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},
- {"fzrm", 0x00000007, 1, CPUID_REG_EAX, 10, 1},
- {"fsrs", 0x00000007, 1, CPUID_REG_EAX, 11, 1},
- {"fsrcs", 0x00000007, 1, CPUID_REG_EAX, 12, 1},
- {"wrmsrns", 0x00000007, 1, CPUID_REG_EAX, 19, 1},
- {"avx-ifma", 0x00000007, 1, CPUID_REG_EAX, 23, 1},
-
- {"avx-vnni-int8",0x00000007, 1, CPUID_REG_EDX, 4, 1},
- {"avx-ne-convert",0x00000007, 1, CPUID_REG_EDX, 5, 1},
- {"cet-sss", 0x00000007, 1, CPUID_REG_EDX, 18, 1},
-
- {"intel-psfd", 0x00000007, 2, CPUID_REG_EDX, 0, 1},
- {"ipred-ctrl", 0x00000007, 2, CPUID_REG_EDX, 1, 1},
- {"rrsba-ctrl", 0x00000007, 2, CPUID_REG_EDX, 2, 1},
- {"ddp-ctrl", 0x00000007, 2, CPUID_REG_EDX, 3, 1},
- {"bhi-ctrl", 0x00000007, 2, CPUID_REG_EDX, 4, 1},
- {"mcdt-no", 0x00000007, 2, CPUID_REG_EDX, 5, 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},
- {"no-lmsl", 0x80000008, NA, CPUID_REG_EBX, 20, 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},
@@ -391,17 +239,63 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str)
{"svm_pausefilt",0x8000000a, NA, CPUID_REG_EDX, 10, 1},
{"lfence+", 0x80000021, NA, CPUID_REG_EAX, 2, 1},
- {"nscb", 0x80000021, NA, CPUID_REG_EAX, 6, 1},
- {"auto-ibrs", 0x80000021, NA, CPUID_REG_EAX, 8, 1},
- {"cpuid-user-dis", 0x80000021, NA, CPUID_REG_EAX, 17, 1},
{"maxhvleaf", 0x40000000, NA, CPUID_REG_EAX, 0, 8},
{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) {
@@ -414,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;
}
@@ -2620,6 +2620,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;