@@ -24,6 +24,23 @@
#include "cpu.h"
#include "kvm.h"
+static const char *get_opt_name(char *buf, int buf_size,
+ const char *p, char delim)
+{
+ char *q;
+
+ q = buf;
+ while (*p != '\0' && *p != delim) {
+ if (q && (q - buf) < buf_size - 1)
+ *q++ = *p;
+ p++;
+ }
+ if (q)
+ *q = '\0';
+
+ return p;
+}
+
/* feature flags taken from "Intel Processor Identification and the CPUID
* Instruction" and AMD's "CPUID Specification". In cases of disagreement
* about feature names, the Linux name is used. */
@@ -423,8 +440,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
unsigned int i;
x86_def_t *def;
- char *s = strdup(cpu_model);
- char *featurestr, *name = strtok(s, ",");
+ const char* s;
+ char featurestr[64];
uint32_t plus_features = 0, plus_ext_features = 0,
plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
uint32_t minus_features = 0, minus_ext_features = 0,
@@ -432,14 +449,15 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
minus_kvm_features = 0;
uint32_t numvalue;
+ s = get_opt_name(featurestr, 64, cpu_model, ',');
def = NULL;
for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
- if (strcmp(name, x86_defs[i].name) == 0) {
+ if (strcmp(featurestr, x86_defs[i].name) == 0) {
def = &x86_defs[i];
break;
}
}
- if (kvm_enabled() && strcmp(name, "host") == 0) {
+ if (kvm_enabled() && strcmp(featurestr, "host") == 0) {
cpu_x86_fill_host(x86_cpu_def);
} else if (!def) {
goto error;
@@ -453,10 +471,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
&plus_ext_features, &plus_ext2_features, &plus_ext3_features,
&plus_kvm_features);
- featurestr = strtok(NULL, ",");
-
- while (featurestr) {
+ while (*s != 0) {
char *val;
+ s = get_opt_name(featurestr, 64, s + 1, ',');
if (featurestr[0] == '+') {
add_flagname_to_bitmaps(featurestr + 1, &plus_features,
&plus_ext_features, &plus_ext2_features,
@@ -536,7 +553,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
"(+feature|-feature|feature=xyz)\n", featurestr);
goto error;
}
- featurestr = strtok(NULL, ",");
}
x86_cpu_def->features |= plus_features;
x86_cpu_def->ext_features |= plus_ext_features;
@@ -548,11 +564,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
x86_cpu_def->ext2_features &= ~minus_ext2_features;
x86_cpu_def->ext3_features &= ~minus_ext3_features;
x86_cpu_def->kvm_features &= ~minus_kvm_features;
- free(s);
return 0;
error:
- free(s);
return -1;
}
To avoid the non-reentrant capable strtok() use the QEMU defined get_opt_name() to parse the -cpu parameter list. Since there is a name clash between linux-user/mmap.c:qemu_malloc() and qemu-malloc.c:qemu_malloc() I copied the small function from qemu-option.c into cpuid.c. Not the best solution, bit IMO the least intrusive and smallest one. Signed-off-by: Andre Przywara <andre.przywara@amd.com> --- target-i386/cpuid.c | 34 ++++++++++++++++++++++++---------- 1 files changed, 24 insertions(+), 10 deletions(-)