On Thu, 18 Jan 2018 17:18:09 -0200 Eduardo Habkost <ehabk...@redhat.com> wrote:
> On Thu, Jan 18, 2018 at 11:10:35AM +0100, Igor Mammedov wrote: > > On Wed, 17 Jan 2018 23:48:46 -0200 > > Eduardo Habkost <ehabk...@redhat.com> wrote: > > > > > On Wed, Jan 17, 2018 at 04:43:32PM +0100, Igor Mammedov wrote: > > > > The last user of it was machine type 'none', which used field > > > > to create CPU id user requested it on CLI with -cpu option. [...] > It looks like default_cpu_type is being overloaded for two > different roles: 1) specifying the default CPU type; 2) finding > the arch-specific class to be used to parse -cpu. > > In the case of null-machine, these two roles conflict with each > other. I believe we can find other solutions instead of this > hack that involves lying on MachineClass::default_cpu_type (and > then having to work around the lie on machine_none_init()). > > I see multiple options: adding a new MachineClass field for that > (e.g. resolving_cpu_type, which defaults to default_cpu_type if > NULL); moving the CPU parsing code to arch_init.c (so it could > use CPU_RESOLVING_TYPE or something similar); adding a optional > MachineClass::parse_cpu_model hook. We could even try to get rid > of CPUClass::parse_features completely Adding hooks just for the sake on null-machine seems to be overkill, I'd go for arch_init.c but it won't work for linux-user, how about exec.c as following: diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 93bd546..0185589 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -661,8 +661,7 @@ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); [...] diff --git a/exec.c b/exec.c index d28fc0c..4543f06 100644 --- a/exec.c +++ b/exec.c @@ -817,6 +817,29 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp) #endif } +const char *parse_cpu_model(const char *cpu_model) +{ + ObjectClass *oc; + CPUClass *cc; + gchar **model_pieces; + const char *cpu_type; + + model_pieces = g_strsplit(cpu_model, ",", 2); + + oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]); + if (oc == NULL) { + error_report("unable to find CPU model '%s'", model_pieces[0]); + g_strfreev(model_pieces); + exit(EXIT_FAILURE); + } + + cpu_type = object_class_get_name(oc); + cc = CPU_CLASS(oc); + cc->parse_features(cpu_type, model_pieces[1], &error_fatal); + g_strfreev(model_pieces); + return cpu_type; +} + #if defined(CONFIG_USER_ONLY) static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index 864832d..cde4d3e 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -24,9 +24,9 @@ static void machine_none_init(MachineState *mch) { CPUState *cpu = NULL; - /* Initialize CPU (if a model has been specified) */ - if (mch->cpu_model) { - cpu = cpu_init(mch->cpu_model); + /* Initialize CPU (if user asked for it) */ + if (mch->cpu_type) { + cpu = cpu_create(mch->cpu_type); if (!cpu) { error_report("Unable to initialize CPU"); exit(1); diff --git a/linux-user/main.c b/linux-user/main.c index a35477e..0afb3f4 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4357,10 +4358,13 @@ int main(int argc, char **argv, char **envp) cpu_model = "any"; #endif } + cpu_type = parse_cpu_model(cpu_model); + tcg_exec_init(0); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ - cpu = cpu_init(cpu_model); + + cpu = cpu_create(cpu_type); env = cpu->env_ptr; cpu_reset(cpu); diff --git a/qom/cpu.c b/qom/cpu.c index e42d9a7..aab8437 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -67,37 +67,6 @@ CPUState *cpu_create(const char *typename) return cpu; } -const char *cpu_parse_cpu_model(const char *typename, const char *cpu_model) -{ [...] -} - -CPUState *cpu_generic_init(const char *typename, const char *cpu_model) -{ [...] -} - bool cpu_paging_enabled(const CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); diff --git a/vl.c b/vl.c index 2586f25..178bca3 100644 --- a/vl.c +++ b/vl.c @@ -4609,17 +4609,13 @@ int main(int argc, char **argv, char **envp) current_machine->maxram_size = maxram_size; current_machine->ram_slots = ram_slots; current_machine->boot_order = boot_order; - current_machine->cpu_model = cpu_model; parse_numa_opts(current_machine); /* parse features once if machine provides default cpu_type */ - if (machine_class->default_cpu_type) { - current_machine->cpu_type = machine_class->default_cpu_type; - if (cpu_model) { - current_machine->cpu_type = - cpu_parse_cpu_model(machine_class->default_cpu_type, cpu_model); - } + current_machine->cpu_type = machine_class->default_cpu_type; + if (cpu_model) { + current_machine->cpu_type = parse_cpu_model(cpu_model); } machine_run_board_init(current_machine);