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.przyw...@amd.com> --- target-i386/cpuid.c | 34 ++++++++++++++++++++++++---------- 1 files changed, 24 insertions(+), 10 deletions(-) diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c index cc080f4..0238718 100644 --- a/target-i386/cpuid.c +++ b/target-i386/cpuid.c @@ -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; } -- 1.6.4