On Thu, 24 Aug 2017 14:00:21 -0300 Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Hi Igor, > > On 08/24/2017 01:31 PM, Igor Mammedov wrote: > > since commit ( 9262685b cpu: Factor out cpu_generic_init() ) > > features parsed by it were truncated only to the 1st feature > > after CPU name due to fact that > > > > featurestr = strtok(NULL, ","); > > cc->parse_features(cpu, featurestr, &err); > > > > would extract exactly one feature and parse_features() callback > > would parse it and only it leaving the rest of features ignored. > > > > Reuse approach from x86 custom impl. i.e. replace strtok() token > > parsing with g_strsplit(), which would split feature string in > > 2 parts name and features list and pass the later to > > parse_features() callback. > > > > Signed-off-by: Igor Mammedov <imamm...@redhat.com> > > --- > > CC: Eduardo Habkost <ehabk...@redhat.com> > > CC: Andreas Färber <afaer...@suse.de> > > > > Probably due to existing users not actualy using/having any > > features to parse bug were unnoticed for 2 years but switching > > from custom cpu_foo_init() to cpu_generic_init() triggered it. > > --- > > qom/cpu.c | 14 ++++++-------- > > 1 file changed, 6 insertions(+), 8 deletions(-) > > > > diff --git a/qom/cpu.c b/qom/cpu.c > > index 4f38db0..caf5c14 100644 > > --- a/qom/cpu.c > > +++ b/qom/cpu.c > > @@ -50,28 +50,26 @@ bool cpu_exists(int64_t id) > > > > CPUState *cpu_generic_init(const char *typename, const char *cpu_model) > > { > > - char *str, *name, *featurestr; > > CPUState *cpu = NULL; > > ObjectClass *oc; > > CPUClass *cc; > > Error *err = NULL; > > + gchar **model_pieces; > > > > - str = g_strdup(cpu_model); > > - name = strtok(str, ","); > > + model_pieces = g_strsplit(cpu_model, ",", 2); > > > > - oc = cpu_class_by_name(typename, name); > > + oc = cpu_class_by_name(typename, model_pieces[0]); > > if (oc == NULL) { > > - g_free(str); > > + g_strfreev(model_pieces); > > return NULL; > > } > > > > cc = CPU_CLASS(oc); > > - featurestr = strtok(NULL, ","); > > /* TODO: all callers of cpu_generic_init() need to be converted to > > * call parse_features() only once, before calling cpu_generic_init(). > > */ > > - cc->parse_features(object_class_get_name(oc), featurestr, &err); > > - g_free(str); > > I feel safer adding: > > if (g_strv_length(model_pieces) > 1) { all current callbacks (i386/sparc/cpu_common_parse_features) deal with cc->parse_features(,NULL,) by explicitly checking for NULL, so there is no need for check here. Though, it's possible to avoid calling callback at all if model_pieces[1] == NULL Would you like to post a patch on top? > > > + cc->parse_features(object_class_get_name(oc), model_pieces[1], &err); > > } > > > + g_strfreev(model_pieces); > > if (err != NULL) { > > goto out; > > } > > >