This is RFC because there is another implementation option: it is possible to implement this functionality in the object_finalize for all available targets. All targets change will require more testing. Please let me know if all targets should be changed at once.
This patch changes qmp_device_list_properties and only target-i386 to allow TYPE_CPU class properties to be quered with QMP interface and with -device core2duo-x86_64-cpu,help command line. Signed-off-by: Valentin Rakush <valentin.rak...@gmail.com> Cc: Luiz Capitulino <lcapitul...@redhat.com> Cc: Eric Blake <ebl...@redhat.com> Cc: Markus Armbruster <arm...@redhat.com> Cc: Andreas Färber <afaer...@suse.de> Cc: Daniel P. Berrange <berra...@redhat.com> Cc: Eduardo Habkost <ehabk...@redhat.com> --- qmp.c | 19 +++++++++++++++++++ target-i386/cpu.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/qmp.c b/qmp.c index 6ae7230..2721f16 100644 --- a/qmp.c +++ b/qmp.c @@ -516,6 +516,7 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, Error **errp) { ObjectClass *klass; + ObjectClass *cpu_klass; Object *obj; ObjectProperty *prop; ObjectPropertyIterator iter; @@ -580,6 +581,24 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, prop_list = entry; } + cpu_klass = object_class_dynamic_cast(klass, TYPE_CPU); + if (cpu_klass) { + CPUState *tmp_cpu = CPU(obj); + CPUState *cs = first_cpu; + + CPU_FOREACH(cs) { + if (tmp_cpu->cpu_index == cs->cpu_index) { +#if defined(CONFIG_USER_ONLY) + cpu_list_lock(); +#endif + QTAILQ_REMOVE(&cpus, cs, node); +#if defined(CONFIG_USER_ONLY) + cpu_list_unlock(); +#endif + } + } + } + object_unref(obj); return prop_list; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 3fa14bf..8c32794 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1479,7 +1479,7 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data) dc->props = host_x86_cpu_properties; /* Reason: host_x86_cpu_initfn() dies when !kvm_enabled() */ - dc->cannot_destroy_with_object_finalize_yet = true; + dc->cannot_destroy_with_object_finalize_yet = false; } static void host_x86_cpu_initfn(Object *obj) @@ -3225,11 +3225,39 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->cpu_exec_enter = x86_cpu_exec_enter; cc->cpu_exec_exit = x86_cpu_exec_exit; + object_class_property_add(oc, "family", "int", + x86_cpuid_version_get_family, + x86_cpuid_version_set_family, NULL, NULL, NULL); + object_class_property_add(oc, "model", "int", + x86_cpuid_version_get_model, + x86_cpuid_version_set_model, NULL, NULL, NULL); + object_class_property_add(oc, "stepping", "int", + x86_cpuid_version_get_stepping, + x86_cpuid_version_set_stepping, NULL, NULL, NULL); + object_class_property_add_str(oc, "vendor", + x86_cpuid_get_vendor, + x86_cpuid_set_vendor, NULL); + object_class_property_add_str(oc, "model-id", + x86_cpuid_get_model_id, + x86_cpuid_set_model_id, NULL); + object_class_property_add(oc, "tsc-frequency", "int", + x86_cpuid_get_tsc_freq, + x86_cpuid_set_tsc_freq, NULL, NULL, NULL); + object_class_property_add(oc, "apic-id", "int", + x86_cpuid_get_apic_id, + x86_cpuid_set_apic_id, NULL, NULL, NULL); + object_class_property_add(oc, "feature-words", "X86CPUFeatureWordInfo", + x86_cpu_get_feature_words, + NULL, NULL, NULL, NULL); + object_class_property_add(oc, "filtered-features", "X86CPUFeatureWordInfo", + x86_cpu_get_feature_words, + NULL, NULL, NULL, NULL); + /* * Reason: x86_cpu_initfn() calls cpu_exec_init(), which saves the * object in cpus -> dangling pointer after final object_unref(). */ - dc->cannot_destroy_with_object_finalize_yet = true; + dc->cannot_destroy_with_object_finalize_yet = false; } static const TypeInfo x86_cpu_type_info = { -- 1.8.3.1