From f5730c69f00eaf7218ab79d1393d7197fcd9fe69 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 11 Nov 2020 13:38:15 -0500 Subject: i386: Register feature bit properties as class properties Class properties make QOM introspection simpler and easier, as they don't require an object to be instantiated. Also, the hundreds of instance properties were having an impact on QMP commands that create temporary CPU objects. On my machine, run time of qmp_query_cpu_definitions() changed from ~200ms to ~16ms after applying this patch. Signed-off-by: Eduardo Habkost Message-Id: <20201111183823.283752-5-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) (limited to 'target') diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6c11fee..ca997a6 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6858,29 +6858,23 @@ static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name, cpu->env.user_features[fp->w] |= fp->mask; } -static void x86_cpu_release_bit_prop(Object *obj, const char *name, - void *opaque) -{ - BitProperty *prop = opaque; - g_free(prop); -} - /* Register a boolean property to get/set a single bit in a uint32_t field. * * The same property name can be registered multiple times to make it affect * multiple bits in the same FeatureWord. In that case, the getter will return * true only if all bits are set. */ -static void x86_cpu_register_bit_prop(X86CPU *cpu, +static void x86_cpu_register_bit_prop(X86CPUClass *xcc, const char *prop_name, FeatureWord w, int bitnr) { + ObjectClass *oc = OBJECT_CLASS(xcc); BitProperty *fp; ObjectProperty *op; uint64_t mask = (1ULL << bitnr); - op = object_property_find(OBJECT(cpu), prop_name); + op = object_class_property_find(oc, prop_name); if (op) { fp = op->opaque; assert(fp->w == w); @@ -6889,14 +6883,14 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu, fp = g_new0(BitProperty, 1); fp->w = w; fp->mask = mask; - object_property_add(OBJECT(cpu), prop_name, "bool", - x86_cpu_get_bit_prop, - x86_cpu_set_bit_prop, - x86_cpu_release_bit_prop, fp); + object_class_property_add(oc, prop_name, "bool", + x86_cpu_get_bit_prop, + x86_cpu_set_bit_prop, + NULL, fp); } } -static void x86_cpu_register_feature_bit_props(X86CPU *cpu, +static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc, FeatureWord w, int bitnr) { @@ -6915,7 +6909,7 @@ static void x86_cpu_register_feature_bit_props(X86CPU *cpu, /* aliases don't use "|" delimiters anymore, they are registered * manually using object_property_add_alias() */ assert(!strchr(name, '|')); - x86_cpu_register_bit_prop(cpu, name, w, bitnr); + x86_cpu_register_bit_prop(xcc, name, w, bitnr); } #if !defined(CONFIG_USER_ONLY) @@ -6969,7 +6963,6 @@ static void x86_cpu_initfn(Object *obj) X86CPU *cpu = X86_CPU(obj); X86CPUClass *xcc = X86_CPU_GET_CLASS(obj); CPUX86State *env = &cpu->env; - FeatureWord w; env->nr_dies = 1; cpu_set_cpustate_pointers(cpu); @@ -6981,14 +6974,6 @@ static void x86_cpu_initfn(Object *obj) x86_cpu_get_feature_words, NULL, NULL, (void *)cpu->filtered_features); - for (w = 0; w < FEATURE_WORDS; w++) { - int bitnr; - - for (bitnr = 0; bitnr < 64; bitnr++) { - x86_cpu_register_feature_bit_props(cpu, w, bitnr); - } - } - object_property_add_alias(obj, "sse3", obj, "pni"); object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq"); object_property_add_alias(obj, "sse4-1", obj, "sse4.1"); @@ -7274,6 +7259,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) X86CPUClass *xcc = X86_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); + FeatureWord w; device_class_set_parent_realize(dc, x86_cpu_realizefn, &xcc->parent_realize); @@ -7363,6 +7349,12 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) x86_cpu_get_crash_info_qom, NULL, NULL, NULL); #endif + for (w = 0; w < FEATURE_WORDS; w++) { + int bitnr; + for (bitnr = 0; bitnr < 64; bitnr++) { + x86_cpu_register_feature_bit_props(xcc, w, bitnr); + } + } } static const TypeInfo x86_cpu_type_info = { -- cgit v1.1 From 85cc807cbc48055c92c187a3dc97c1c5d85de39f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 11 Nov 2020 13:38:18 -0500 Subject: arm/cpu64: Register "aarch64" as class property Class properties make QOM introspection simpler and easier, as they don't require an object to be instantiated. Signed-off-by: Eduardo Habkost Reviewed-by: Peter Maydell Message-Id: <20201111183823.283752-8-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/arm/cpu64.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'target') diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 6492130..7cf9fc4 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -762,15 +762,6 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp) } } -static void aarch64_cpu_initfn(Object *obj) -{ - object_property_add_bool(obj, "aarch64", aarch64_cpu_get_aarch64, - aarch64_cpu_set_aarch64); - object_property_set_description(obj, "aarch64", - "Set on/off to enable/disable aarch64 " - "execution state "); -} - static void aarch64_cpu_finalizefn(Object *obj) { } @@ -790,6 +781,12 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data) cc->gdb_num_core_regs = 34; cc->gdb_core_xml_file = "aarch64-core.xml"; cc->gdb_arch_name = aarch64_gdb_arch_name; + + object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64, + aarch64_cpu_set_aarch64); + object_class_property_set_description(oc, "aarch64", + "Set on/off to enable/disable aarch64 " + "execution state "); } static void aarch64_cpu_instance_init(Object *obj) @@ -827,7 +824,6 @@ static const TypeInfo aarch64_cpu_type_info = { .name = TYPE_AARCH64_CPU, .parent = TYPE_ARM_CPU, .instance_size = sizeof(ARMCPU), - .instance_init = aarch64_cpu_initfn, .instance_finalize = aarch64_cpu_finalizefn, .abstract = true, .class_size = sizeof(AArch64CPUClass), -- cgit v1.1 From 0ea0a42ef6796e1d2cc2734e6a697becdb0cd3ff Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2020 17:05:02 -0500 Subject: sparc: Check dev->realized at sparc_set_nwindows() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sparc_set_nwindows() is one of the very few property setters that don't check dev->realized, and there's no reason for it to be special. Check dev->realized like the other setters. Signed-off-by: Eduardo Habkost Reviewed-by: Marc-André Lureau Message-Id: <20201211220529.2290218-6-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/sparc/cpu.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'target') diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index 701e794..6a32990 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -798,11 +798,17 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name, static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { + DeviceState *dev = DEVICE(obj); const int64_t min = MIN_NWINDOWS; const int64_t max = MAX_NWINDOWS; SPARCCPU *cpu = SPARC_CPU(obj); int64_t value; + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + if (!visit_type_int(v, name, &value, errp)) { return; } -- cgit v1.1