Message ID | 1503592308-93913-2-git-send-email-imammedo@redhat.com |
---|---|
State | New |
Headers | show |
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 <imammedo@redhat.com> > --- > CC: Eduardo Habkost <ehabkost@redhat.com> > CC: Andreas Färber <afaerber@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) { > + cc->parse_features(object_class_get_name(oc), model_pieces[1], &err); } > + g_strfreev(model_pieces); > if (err != NULL) { > goto out; > } >
On Thu, 24 Aug 2017 14:00:21 -0300 Philippe Mathieu-Daudé <f4bug@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 <imammedo@redhat.com> > > --- > > CC: Eduardo Habkost <ehabkost@redhat.com> > > CC: Andreas Färber <afaerber@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; > > } > > >
On 08/25/2017 05:11 AM, Igor Mammedov wrote: > Philippe Mathieu-Daudé <f4bug@amsat.org> wrote: >> 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 <imammedo@redhat.com> >>> --- >>> CC: Eduardo Habkost <ehabkost@redhat.com> >>> CC: Andreas Färber <afaerber@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? Ok so it is safe. I might eventually but this not a big win, so no worries. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> > >> >>> + cc->parse_features(object_class_get_name(oc), model_pieces[1], &err); >> >> } >> >>> + g_strfreev(model_pieces); >>> if (err != NULL) { >>> goto out; >>> } >>> >> >
On Thu, Aug 24, 2017 at 06:31:24PM +0200, 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 <imammedo@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
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); + cc->parse_features(object_class_get_name(oc), model_pieces[1], &err); + g_strfreev(model_pieces); if (err != NULL) { goto out; }
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 <imammedo@redhat.com> --- CC: Eduardo Habkost <ehabkost@redhat.com> CC: Andreas Färber <afaerber@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(-)