Fixes issue when combining CPU features and smp. The issue is caused by parse_feature's use of strtok which modifies the input feature string that is needed for each smp CPU pass. This patch restores the feature string for each pass.
Signed-off-by: Greg Bellows <greg.bell...@linaro.org> --- hw/arm/virt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 69f51ac..a64eedd 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -728,7 +728,7 @@ static void machvirt_init(MachineState *machine) const char *cpu_model = machine->cpu_model; VirtBoardInfo *vbi; uint32_t gic_phandle; - char **cpustr; + char **cpustr, *featurestr; if (!cpu_model) { cpu_model = "cortex-a15"; @@ -753,6 +753,12 @@ static void machvirt_init(MachineState *machine) create_fdt(vbi); + /* Parsing modifies the feature string and we need it for each CPU pass, so + * make a copy to refresh from. Duplicate is used to allocate the + * appropriate storage size. + */ + featurestr = g_strdup(cpustr[1]); + for (n = 0; n < smp_cpus; n++) { ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]); CPUClass *cc = CPU_CLASS(oc); @@ -766,11 +772,14 @@ static void machvirt_init(MachineState *machine) cpuobj = object_new(object_class_get_name(oc)); /* Handle any CPU options specified by the user */ - cc->parse_features(CPU(cpuobj), cpustr[1], &err); + cc->parse_features(CPU(cpuobj), featurestr, &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } + /* Refresh the feature string as parse modified the pointer. */ + g_stpcpy(featurestr, cpustr[1]); + if (!vms->secure) { object_property_set_bool(cpuobj, false, "has_el3", NULL); @@ -791,6 +800,7 @@ static void machvirt_init(MachineState *machine) object_property_set_bool(cpuobj, true, "realized", NULL); } + g_free(featurestr); g_strfreev(cpustr); fdt_add_timer_nodes(vbi); fdt_add_cpu_nodes(vbi); -- 1.8.3.2