From 62a48a2a5798425997152dea3fc48708f9116c04 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 9 Jun 2016 19:11:01 +0200 Subject: cpu: Use CPUClass->parse_features() as convertor to global properties Currently CPUClass->parse_features() is used to parse -cpu features string and set properties on created CPU instances. But considering that features specified by -cpu apply to every created CPU instance, it doesn't make sense to parse the same features string for every CPU created. It also makes every target that cares about parsing features string explicitly call CPUClass->parse_features() parser, which gets in a way if we consider using generic device_add for CPU hotplug as device_add has not a clue about CPU specific hooks. Turns out we can use global properties mechanism to set properties on every created CPU instance for a given type. That way it's possible to convert CPU features into a set of global properties for CPU type specified by -cpu cpu_model and common Device.device_post_init() will apply them to CPU of given type automatically regardless whether it's manually created CPU or CPU created with help of device_add. Signed-off-by: Igor Mammedov Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/arm/virt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'hw/arm/virt.c') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 6e098afd1f..ae90ca5771 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1261,6 +1261,7 @@ static void machvirt_init(MachineState *machine) for (n = 0; n < smp_cpus; n++) { ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]); + const char *typename = object_class_get_name(oc); CPUClass *cc = CPU_CLASS(oc); Object *cpuobj; Error *err = NULL; @@ -1270,10 +1271,10 @@ static void machvirt_init(MachineState *machine) error_report("Unable to find CPU definition"); exit(1); } - cpuobj = object_new(object_class_get_name(oc)); + /* convert -smp CPU options specified by the user into global props */ + cc->parse_features(typename, cpuopts, &err); + cpuobj = object_new(typename); - /* Handle any CPU options specified by the user */ - cc->parse_features(CPU(cpuobj), cpuopts, &err); g_free(cpuopts); if (err) { error_report_err(err); -- cgit 1.4.1 From 09f71b054a95161950a03fafc9023637929bd404 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 9 Jun 2016 19:11:02 +0200 Subject: arm: virt: Parse cpu_model only once Considering that features are converted to global properties and global properties are automatically applied to every new instance of created CPU (at object_new() time), there is no point in parsing cpu_model string every time a CPU created. So move parsing outside CPU creation loop and do it only once. Parsing also should be done before any CPU is created so that features would affect the first CPU a well. Signed-off-by: Igor Mammedov Reviewed-by: Peter Maydell Signed-off-by: Eduardo Habkost --- hw/arm/virt.c | 42 +++++++++++++++++++++--------------------- qom/cpu.c | 1 - 2 files changed, 21 insertions(+), 22 deletions(-) (limited to 'hw/arm/virt.c') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ae90ca5771..4dafd42be8 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1176,6 +1176,10 @@ static void machvirt_init(MachineState *machine) VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); VirtGuestInfo *guest_info = &guest_info_state->info; char **cpustr; + ObjectClass *oc; + const char *typename; + CPUClass *cc; + Error *err = NULL; bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0); if (!cpu_model) { @@ -1259,27 +1263,24 @@ static void machvirt_init(MachineState *machine) create_fdt(vbi); - for (n = 0; n < smp_cpus; n++) { - ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]); - const char *typename = object_class_get_name(oc); - CPUClass *cc = CPU_CLASS(oc); - Object *cpuobj; - Error *err = NULL; - char *cpuopts = g_strdup(cpustr[1]); - - if (!oc) { - error_report("Unable to find CPU definition"); - exit(1); - } - /* convert -smp CPU options specified by the user into global props */ - cc->parse_features(typename, cpuopts, &err); - cpuobj = object_new(typename); + oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]); + if (!oc) { + error_report("Unable to find CPU definition"); + exit(1); + } + typename = object_class_get_name(oc); - g_free(cpuopts); - if (err) { - error_report_err(err); - exit(1); - } + /* convert -smp CPU options specified by the user into global props */ + cc = CPU_CLASS(oc); + cc->parse_features(typename, cpustr[1], &err); + g_strfreev(cpustr); + if (err) { + error_report_err(err); + exit(1); + } + + for (n = 0; n < smp_cpus; n++) { + Object *cpuobj = object_new(typename); if (!vms->secure) { object_property_set_bool(cpuobj, false, "has_el3", NULL); @@ -1310,7 +1311,6 @@ static void machvirt_init(MachineState *machine) object_property_set_bool(cpuobj, true, "realized", NULL); } - g_strfreev(cpustr); fdt_add_timer_nodes(vbi, gic_version); fdt_add_cpu_nodes(vbi); fdt_add_psci_node(vbi); diff --git a/qom/cpu.c b/qom/cpu.c index 2a0d9fe10f..f884a666a1 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -296,7 +296,6 @@ static void cpu_common_parse_features(const char *typename, char *features, * call it only once, so we can remove this check (or change it * to assert(!cpu_globals_initialized). * Current callers of ->parse_features() are: - * - machvirt_init() * - cpu_generic_init() * - cpu_x86_create() */ -- cgit 1.4.1