From nobody Thu Nov 6 19:47:12 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) client-ip=209.132.183.37; envelope-from=libvir-list-bounces@redhat.com; helo=mx5-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mx.zohomail.com with SMTPS id 1488212916993820.6024750960347; Mon, 27 Feb 2017 08:28:36 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1RGPQec028327; Mon, 27 Feb 2017 11:25:27 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1RGPPbW019549 for ; Mon, 27 Feb 2017 11:25:25 -0500 Received: from localhost (ovpn-116-24.gru2.redhat.com [10.97.116.24]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1RGPOlo022289; Mon, 27 Feb 2017 11:25:25 -0500 From: Eduardo Habkost To: Peter Maydell Date: Mon, 27 Feb 2017 13:25:00 -0300 Message-Id: <20170227162501.29280-11-ehabkost@redhat.com> In-Reply-To: <20170227162501.29280-1-ehabkost@redhat.com> References: <20170227162501.29280-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-loop: libvir-list@redhat.com Cc: libvir-list@redhat.com, Paolo Bonzini , Jiri Denemark , qemu-devel@nongnu.org, Richard Henderson Subject: [libvirt] [PULL 10/11] i386: Implement query-cpu-model-expansion QMP command X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Implement query-cpu-model-expansion for target-i386. This should meet all the requirements while being simple. In the case of static expansion, it will use the new "base" CPU model, and in the case of full expansion, it will keep the original CPU model name+props, and append extra properties. A future follow-up should improve the implementation of type=3Dfull, so that it returns more detailed data, including every writable QOM property in the CPU object. Cc: libvir-list@redhat.com Cc: Jiri Denemark Message-Id: <20170222190029.17243-3-ehabkost@redhat.com> Tested-by: Jiri Denemark Signed-off-by: Eduardo Habkost --- monitor.c | 4 +- target/i386/cpu.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index f8f4a07cfb..b68944d93c 100644 --- a/monitor.c +++ b/monitor.c @@ -984,8 +984,10 @@ static void qmp_unregister_commands_hack(void) #ifndef TARGET_ARM qmp_unregister_command("query-gic-capabilities"); #endif -#if !defined(TARGET_S390X) +#if !defined(TARGET_S390X) && !defined(TARGET_I386) qmp_unregister_command("query-cpu-model-expansion"); +#endif +#if !defined(TARGET_S390X) qmp_unregister_command("query-cpu-model-baseline"); qmp_unregister_command("query-cpu-model-comparison"); #endif diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 0a71594445..139b7ea12e 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -29,10 +29,16 @@ #include "qemu/option.h" #include "qemu/config-file.h" #include "qapi/qmp/qerror.h" +#include "qapi/qmp/qstring.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qfloat.h" =20 #include "qapi-types.h" #include "qapi-visit.h" #include "qapi/visitor.h" +#include "qom/qom-qobject.h" #include "sysemu/arch_init.h" =20 #if defined(CONFIG_KVM) @@ -2288,7 +2294,7 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValu= e *props) } } =20 -/* Load data from X86CPUDefinition +/* Load data from X86CPUDefinition into a X86CPU object */ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **e= rrp) { @@ -2297,6 +2303,11 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefi= nition *def, Error **errp) char host_vendor[CPUID_VENDOR_SZ + 1]; FeatureWord w; =20 + /*NOTE: any property set by this function should be returned by + * x86_cpu_static_props(), so static expansion of + * query-cpu-model-expansion is always complete. + */ + /* CPU models only set _minimum_ values for level/xlevel: */ object_property_set_int(OBJECT(cpu), def->level, "min-level", errp); object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp); @@ -2341,6 +2352,184 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDef= inition *def, Error **errp) =20 } =20 +/* Return a QDict containing keys for all properties that can be included + * in static expansion of CPU models. All properties set by x86_cpu_load_d= ef() + * must be included in the dictionary. + */ +static QDict *x86_cpu_static_props(void) +{ + FeatureWord w; + int i; + static const char *props[] =3D { + "min-level", + "min-xlevel", + "family", + "model", + "stepping", + "model-id", + "vendor", + "lmce", + NULL, + }; + static QDict *d; + + if (d) { + return d; + } + + d =3D qdict_new(); + for (i =3D 0; props[i]; i++) { + qdict_put_obj(d, props[i], qnull()); + } + + for (w =3D 0; w < FEATURE_WORDS; w++) { + FeatureWordInfo *fi =3D &feature_word_info[w]; + int bit; + for (bit =3D 0; bit < 32; bit++) { + if (!fi->feat_names[bit]) { + continue; + } + qdict_put_obj(d, fi->feat_names[bit], qnull()); + } + } + + return d; +} + +/* Add an entry to @props dict, with the value for property. */ +static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *pro= p) +{ + QObject *value =3D object_property_get_qobject(OBJECT(cpu), prop, + &error_abort); + + qdict_put_obj(props, prop, value); +} + +/* Convert CPU model data from X86CPU object to a property dictionary + * that can recreate exactly the same CPU model. + */ +static void x86_cpu_to_dict(X86CPU *cpu, QDict *props) +{ + QDict *sprops =3D x86_cpu_static_props(); + const QDictEntry *e; + + for (e =3D qdict_first(sprops); e; e =3D qdict_next(sprops, e)) { + const char *prop =3D qdict_entry_key(e); + x86_cpu_expand_prop(cpu, props, prop); + } +} + +static void object_apply_props(Object *obj, QDict *props, Error **errp) +{ + const QDictEntry *prop; + Error *err =3D NULL; + + for (prop =3D qdict_first(props); prop; prop =3D qdict_next(props, pro= p)) { + object_property_set_qobject(obj, qdict_entry_value(prop), + qdict_entry_key(prop), &err); + if (err) { + break; + } + } + + error_propagate(errp, err); +} + +/* Create X86CPU object according to model+props specification */ +static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error *= *errp) +{ + X86CPU *xc =3D NULL; + X86CPUClass *xcc; + Error *err =3D NULL; + + xcc =3D X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model)); + if (xcc =3D=3D NULL) { + error_setg(&err, "CPU model '%s' not found", model); + goto out; + } + + xc =3D X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc)))); + if (props) { + object_apply_props(OBJECT(xc), props, &err); + if (err) { + goto out; + } + } + + x86_cpu_expand_features(xc, &err); + if (err) { + goto out; + } + +out: + if (err) { + error_propagate(errp, err); + object_unref(OBJECT(xc)); + xc =3D NULL; + } + return xc; +} + +CpuModelExpansionInfo * +arch_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) +{ + X86CPU *xc =3D NULL; + Error *err =3D NULL; + CpuModelExpansionInfo *ret =3D g_new0(CpuModelExpansionInfo, 1); + QDict *props =3D NULL; + const char *base_name; + + xc =3D x86_cpu_from_model(model->name, + model->has_props ? + qobject_to_qdict(model->props) : + NULL, &err); + if (err) { + goto out; + } + + + switch (type) { + case CPU_MODEL_EXPANSION_TYPE_STATIC: + /* Static expansion will be based on "base" only */ + base_name =3D "base"; + break; + case CPU_MODEL_EXPANSION_TYPE_FULL: + /* As we don't return every single property, full expansion needs + * to keep the original model name+props, and add extra + * properties on top of that. + */ + base_name =3D model->name; + if (model->has_props && model->props) { + props =3D qdict_clone_shallow(qobject_to_qdict(model->props)); + } + break; + default: + error_setg(&err, "Unsupportted expansion type"); + goto out; + } + + if (!props) { + props =3D qdict_new(); + } + x86_cpu_to_dict(xc, props); + + ret->model =3D g_new0(CpuModelInfo, 1); + ret->model->name =3D g_strdup(base_name); + ret->model->props =3D QOBJECT(props); + ret->model->has_props =3D true; + +out: + object_unref(OBJECT(xc)); + if (err) { + error_propagate(errp, err); + qapi_free_CpuModelExpansionInfo(ret); + ret =3D NULL; + } + return ret; +} + X86CPU *cpu_x86_init(const char *cpu_model) { return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model)); --=20 2.11.0.259.g40922b1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list