[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 4/6] libxl: split logic to parse user provided CPUID features
Move the CPUID value parsers out of libxl_cpuid_parse_config() into a newly created cpuid_add() local helper. This is in preparation for also adding MSR feature parsing support. No functional change intended. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Reviewed-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- Changes since v3: - Fix UB and use strtoul. --- tools/libs/light/libxl_cpuid.c | 120 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/tools/libs/light/libxl_cpuid.c b/tools/libs/light/libxl_cpuid.c index dd97699bbde7..f04b192c0e44 100644 --- a/tools/libs/light/libxl_cpuid.c +++ b/tools/libs/light/libxl_cpuid.c @@ -96,6 +96,66 @@ static struct xc_xend_cpuid *cpuid_find_match(libxl_cpuid_policy_list *pl, return *list + i; } +static int cpuid_add(libxl_cpuid_policy_list *policy, + const struct cpuid_flags *flag, const char *val) +{ + struct xc_xend_cpuid *entry = cpuid_find_match(policy, flag->leaf, + flag->subleaf); + unsigned long num; + char flags[33], *resstr, *endptr; + unsigned int i; + + resstr = entry->policy[flag->reg - 1]; + num = strtoul(val, &endptr, 0); + flags[flag->length] = 0; + if (endptr != val) { + /* if this was a valid number, write the binary form into the string */ + for (i = 0; i < flag->length; i++) { + flags[flag->length - 1 - i] = "01"[(num >> i) & 1]; + } + } else { + switch(val[0]) { + case 'x': case 'k': case 's': + memset(flags, val[0], flag->length); + break; + default: + return 3; + } + } + + if (resstr == NULL) { + resstr = strdup("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + } + + /* the family and model entry is potentially split up across + * two fields in Fn0000_0001_EAX, so handle them here separately. + */ + if (!strcmp(flag->name, "family")) { + if (num < 16) { + memcpy(resstr + (32 - 4) - flag->bit, flags + 4, 4); + memcpy(resstr + (32 - 8) - 20, "00000000", 8); + } else { + num -= 15; + memcpy(resstr + (32 - 4) - flag->bit, "1111", 4); + for (i = 0; i < 7; i++) { + flags[7 - i] = "01"[num & 1]; + num >>= 1; + } + memcpy(resstr + (32 - 8) - 20, flags, 8); + } + } else if (!strcmp(flag->name, "model")) { + memcpy(resstr + (32 - 4) - 16, flags, 4); + memcpy(resstr + (32 - 4) - flag->bit, flags + 4, 4); + } else { + memcpy(resstr + (32 - flag->length) - flag->bit, flags, + flag->length); + } + entry->policy[flag->reg - 1] = resstr; + + return 0; + +} + /* parse a single key=value pair and translate it into the libxc * used interface using 32-characters strings for each register. * Will overwrite earlier entries and thus can be called multiple @@ -340,12 +400,8 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str) {NULL, 0, NA, CPUID_REG_INV, 0, 0} }; #undef NA - char *sep, *val, *endptr; - int i; + const char *sep, *val; const struct cpuid_flags *flag; - struct xc_xend_cpuid *entry; - unsigned long num; - char flags[33], *resstr; sep = strchr(str, '='); if (sep == NULL) { @@ -355,60 +411,10 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str) } for (flag = cpuid_flags; flag->name != NULL; flag++) { if(!strncmp(str, flag->name, sep - str) && flag->name[sep - str] == 0) - break; - } - if (flag->name == NULL) { - return 2; - } - entry = cpuid_find_match(policy, flag->leaf, flag->subleaf); - resstr = entry->policy[flag->reg - 1]; - num = strtoull(val, &endptr, 0); - flags[flag->length] = 0; - if (endptr != val) { - /* if this was a valid number, write the binary form into the string */ - for (i = 0; i < flag->length; i++) { - flags[flag->length - 1 - i] = "01"[!!(num & (1 << i))]; - } - } else { - switch(val[0]) { - case 'x': case 'k': case 's': - memset(flags, val[0], flag->length); - break; - default: - return 3; - } - } - - if (resstr == NULL) { - resstr = strdup("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + return cpuid_add(policy, flag, val); } - /* the family and model entry is potentially split up across - * two fields in Fn0000_0001_EAX, so handle them here separately. - */ - if (!strncmp(str, "family", sep - str)) { - if (num < 16) { - memcpy(resstr + (32 - 4) - flag->bit, flags + 4, 4); - memcpy(resstr + (32 - 8) - 20, "00000000", 8); - } else { - num -= 15; - memcpy(resstr + (32 - 4) - flag->bit, "1111", 4); - for (i = 0; i < 7; i++) { - flags[7 - i] = "01"[num & 1]; - num >>= 1; - } - memcpy(resstr + (32 - 8) - 20, flags, 8); - } - } else if (!strncmp(str, "model", sep - str)) { - memcpy(resstr + (32 - 4) - 16, flags, 4); - memcpy(resstr + (32 - 4) - flag->bit, flags + 4, 4); - } else { - memcpy(resstr + (32 - flag->length) - flag->bit, flags, - flag->length); - } - entry->policy[flag->reg - 1] = resstr; - - return 0; + return 2; } /* parse a single list item from the legacy Python xend syntax, where -- 2.41.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |