132cad1ffSPhilippe Mathieu-Daudé /*
232cad1ffSPhilippe Mathieu-Daudé * i386 CPUID, CPU class, definitions, models: system-only code
332cad1ffSPhilippe Mathieu-Daudé *
432cad1ffSPhilippe Mathieu-Daudé * Copyright (c) 2003 Fabrice Bellard
532cad1ffSPhilippe Mathieu-Daudé *
632cad1ffSPhilippe Mathieu-Daudé * This library is free software; you can redistribute it and/or
732cad1ffSPhilippe Mathieu-Daudé * modify it under the terms of the GNU Lesser General Public
832cad1ffSPhilippe Mathieu-Daudé * License as published by the Free Software Foundation; either
932cad1ffSPhilippe Mathieu-Daudé * version 2.1 of the License, or (at your option) any later version.
1032cad1ffSPhilippe Mathieu-Daudé *
1132cad1ffSPhilippe Mathieu-Daudé * This library is distributed in the hope that it will be useful,
1232cad1ffSPhilippe Mathieu-Daudé * but WITHOUT ANY WARRANTY; without even the implied warranty of
1332cad1ffSPhilippe Mathieu-Daudé * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1432cad1ffSPhilippe Mathieu-Daudé * Lesser General Public License for more details.
1532cad1ffSPhilippe Mathieu-Daudé *
1632cad1ffSPhilippe Mathieu-Daudé * You should have received a copy of the GNU Lesser General Public
1732cad1ffSPhilippe Mathieu-Daudé * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1832cad1ffSPhilippe Mathieu-Daudé */
1932cad1ffSPhilippe Mathieu-Daudé
2032cad1ffSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
2132cad1ffSPhilippe Mathieu-Daudé #include "cpu.h"
2232cad1ffSPhilippe Mathieu-Daudé #include "qapi/error.h"
2332cad1ffSPhilippe Mathieu-Daudé #include "qapi/qapi-visit-run-state.h"
24*407bc4bfSDaniel P. Berrangé #include "qobject/qdict.h"
2532cad1ffSPhilippe Mathieu-Daudé #include "qapi/qobject-input-visitor.h"
2632cad1ffSPhilippe Mathieu-Daudé #include "qom/qom-qobject.h"
2732cad1ffSPhilippe Mathieu-Daudé #include "qapi/qapi-commands-machine-target.h"
2832cad1ffSPhilippe Mathieu-Daudé
2932cad1ffSPhilippe Mathieu-Daudé #include "cpu-internal.h"
3032cad1ffSPhilippe Mathieu-Daudé
3132cad1ffSPhilippe Mathieu-Daudé /* Return a QDict containing keys for all properties that can be included
3232cad1ffSPhilippe Mathieu-Daudé * in static expansion of CPU models. All properties set by x86_cpu_load_model()
3332cad1ffSPhilippe Mathieu-Daudé * must be included in the dictionary.
3432cad1ffSPhilippe Mathieu-Daudé */
x86_cpu_static_props(void)3532cad1ffSPhilippe Mathieu-Daudé static QDict *x86_cpu_static_props(void)
3632cad1ffSPhilippe Mathieu-Daudé {
3732cad1ffSPhilippe Mathieu-Daudé FeatureWord w;
3832cad1ffSPhilippe Mathieu-Daudé int i;
3932cad1ffSPhilippe Mathieu-Daudé static const char *props[] = {
4032cad1ffSPhilippe Mathieu-Daudé "min-level",
4132cad1ffSPhilippe Mathieu-Daudé "min-xlevel",
4232cad1ffSPhilippe Mathieu-Daudé "family",
4332cad1ffSPhilippe Mathieu-Daudé "model",
4432cad1ffSPhilippe Mathieu-Daudé "stepping",
4532cad1ffSPhilippe Mathieu-Daudé "model-id",
4632cad1ffSPhilippe Mathieu-Daudé "vendor",
4732cad1ffSPhilippe Mathieu-Daudé "lmce",
4832cad1ffSPhilippe Mathieu-Daudé NULL,
4932cad1ffSPhilippe Mathieu-Daudé };
5032cad1ffSPhilippe Mathieu-Daudé static QDict *d;
5132cad1ffSPhilippe Mathieu-Daudé
5232cad1ffSPhilippe Mathieu-Daudé if (d) {
5332cad1ffSPhilippe Mathieu-Daudé return d;
5432cad1ffSPhilippe Mathieu-Daudé }
5532cad1ffSPhilippe Mathieu-Daudé
5632cad1ffSPhilippe Mathieu-Daudé d = qdict_new();
5732cad1ffSPhilippe Mathieu-Daudé for (i = 0; props[i]; i++) {
5832cad1ffSPhilippe Mathieu-Daudé qdict_put_null(d, props[i]);
5932cad1ffSPhilippe Mathieu-Daudé }
6032cad1ffSPhilippe Mathieu-Daudé
6132cad1ffSPhilippe Mathieu-Daudé for (w = 0; w < FEATURE_WORDS; w++) {
6232cad1ffSPhilippe Mathieu-Daudé FeatureWordInfo *fi = &feature_word_info[w];
6332cad1ffSPhilippe Mathieu-Daudé int bit;
6432cad1ffSPhilippe Mathieu-Daudé for (bit = 0; bit < 64; bit++) {
6532cad1ffSPhilippe Mathieu-Daudé if (!fi->feat_names[bit]) {
6632cad1ffSPhilippe Mathieu-Daudé continue;
6732cad1ffSPhilippe Mathieu-Daudé }
6832cad1ffSPhilippe Mathieu-Daudé qdict_put_null(d, fi->feat_names[bit]);
6932cad1ffSPhilippe Mathieu-Daudé }
7032cad1ffSPhilippe Mathieu-Daudé }
7132cad1ffSPhilippe Mathieu-Daudé
7232cad1ffSPhilippe Mathieu-Daudé return d;
7332cad1ffSPhilippe Mathieu-Daudé }
7432cad1ffSPhilippe Mathieu-Daudé
7532cad1ffSPhilippe Mathieu-Daudé /* Add an entry to @props dict, with the value for property. */
x86_cpu_expand_prop(X86CPU * cpu,QDict * props,const char * prop)7632cad1ffSPhilippe Mathieu-Daudé static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *prop)
7732cad1ffSPhilippe Mathieu-Daudé {
7832cad1ffSPhilippe Mathieu-Daudé QObject *value = object_property_get_qobject(OBJECT(cpu), prop,
7932cad1ffSPhilippe Mathieu-Daudé &error_abort);
8032cad1ffSPhilippe Mathieu-Daudé
8132cad1ffSPhilippe Mathieu-Daudé qdict_put_obj(props, prop, value);
8232cad1ffSPhilippe Mathieu-Daudé }
8332cad1ffSPhilippe Mathieu-Daudé
8432cad1ffSPhilippe Mathieu-Daudé /* Convert CPU model data from X86CPU object to a property dictionary
8532cad1ffSPhilippe Mathieu-Daudé * that can recreate exactly the same CPU model.
8632cad1ffSPhilippe Mathieu-Daudé */
x86_cpu_to_dict(X86CPU * cpu,QDict * props)8732cad1ffSPhilippe Mathieu-Daudé static void x86_cpu_to_dict(X86CPU *cpu, QDict *props)
8832cad1ffSPhilippe Mathieu-Daudé {
8932cad1ffSPhilippe Mathieu-Daudé QDict *sprops = x86_cpu_static_props();
9032cad1ffSPhilippe Mathieu-Daudé const QDictEntry *e;
9132cad1ffSPhilippe Mathieu-Daudé
9232cad1ffSPhilippe Mathieu-Daudé for (e = qdict_first(sprops); e; e = qdict_next(sprops, e)) {
9332cad1ffSPhilippe Mathieu-Daudé const char *prop = qdict_entry_key(e);
9432cad1ffSPhilippe Mathieu-Daudé x86_cpu_expand_prop(cpu, props, prop);
9532cad1ffSPhilippe Mathieu-Daudé }
9632cad1ffSPhilippe Mathieu-Daudé }
9732cad1ffSPhilippe Mathieu-Daudé
9832cad1ffSPhilippe Mathieu-Daudé /* Convert CPU model data from X86CPU object to a property dictionary
9932cad1ffSPhilippe Mathieu-Daudé * that can recreate exactly the same CPU model, including every
10032cad1ffSPhilippe Mathieu-Daudé * writable QOM property.
10132cad1ffSPhilippe Mathieu-Daudé */
x86_cpu_to_dict_full(X86CPU * cpu,QDict * props)10232cad1ffSPhilippe Mathieu-Daudé static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props)
10332cad1ffSPhilippe Mathieu-Daudé {
10432cad1ffSPhilippe Mathieu-Daudé ObjectPropertyIterator iter;
10532cad1ffSPhilippe Mathieu-Daudé ObjectProperty *prop;
10632cad1ffSPhilippe Mathieu-Daudé
10732cad1ffSPhilippe Mathieu-Daudé object_property_iter_init(&iter, OBJECT(cpu));
10832cad1ffSPhilippe Mathieu-Daudé while ((prop = object_property_iter_next(&iter))) {
10932cad1ffSPhilippe Mathieu-Daudé /* skip read-only or write-only properties */
11032cad1ffSPhilippe Mathieu-Daudé if (!prop->get || !prop->set) {
11132cad1ffSPhilippe Mathieu-Daudé continue;
11232cad1ffSPhilippe Mathieu-Daudé }
11332cad1ffSPhilippe Mathieu-Daudé
11432cad1ffSPhilippe Mathieu-Daudé /* "hotplugged" is the only property that is configurable
11532cad1ffSPhilippe Mathieu-Daudé * on the command-line but will be set differently on CPUs
11632cad1ffSPhilippe Mathieu-Daudé * created using "-cpu ... -smp ..." and by CPUs created
11732cad1ffSPhilippe Mathieu-Daudé * on the fly by x86_cpu_from_model() for querying. Skip it.
11832cad1ffSPhilippe Mathieu-Daudé */
11932cad1ffSPhilippe Mathieu-Daudé if (!strcmp(prop->name, "hotplugged")) {
12032cad1ffSPhilippe Mathieu-Daudé continue;
12132cad1ffSPhilippe Mathieu-Daudé }
12232cad1ffSPhilippe Mathieu-Daudé x86_cpu_expand_prop(cpu, props, prop->name);
12332cad1ffSPhilippe Mathieu-Daudé }
12432cad1ffSPhilippe Mathieu-Daudé }
12532cad1ffSPhilippe Mathieu-Daudé
object_apply_props(Object * obj,QObject * props,const char * props_arg_name,Error ** errp)12632cad1ffSPhilippe Mathieu-Daudé static void object_apply_props(Object *obj, QObject *props,
12732cad1ffSPhilippe Mathieu-Daudé const char *props_arg_name, Error **errp)
12832cad1ffSPhilippe Mathieu-Daudé {
12932cad1ffSPhilippe Mathieu-Daudé Visitor *visitor;
13032cad1ffSPhilippe Mathieu-Daudé QDict *qdict;
13132cad1ffSPhilippe Mathieu-Daudé const QDictEntry *prop;
13232cad1ffSPhilippe Mathieu-Daudé
13332cad1ffSPhilippe Mathieu-Daudé visitor = qobject_input_visitor_new(props);
13432cad1ffSPhilippe Mathieu-Daudé if (!visit_start_struct(visitor, props_arg_name, NULL, 0, errp)) {
13532cad1ffSPhilippe Mathieu-Daudé visit_free(visitor);
13632cad1ffSPhilippe Mathieu-Daudé return;
13732cad1ffSPhilippe Mathieu-Daudé }
13832cad1ffSPhilippe Mathieu-Daudé
13932cad1ffSPhilippe Mathieu-Daudé qdict = qobject_to(QDict, props);
14032cad1ffSPhilippe Mathieu-Daudé for (prop = qdict_first(qdict); prop; prop = qdict_next(qdict, prop)) {
14132cad1ffSPhilippe Mathieu-Daudé if (!object_property_set(obj, qdict_entry_key(prop),
14232cad1ffSPhilippe Mathieu-Daudé visitor, errp)) {
14332cad1ffSPhilippe Mathieu-Daudé goto out;
14432cad1ffSPhilippe Mathieu-Daudé }
14532cad1ffSPhilippe Mathieu-Daudé }
14632cad1ffSPhilippe Mathieu-Daudé
14732cad1ffSPhilippe Mathieu-Daudé visit_check_struct(visitor, errp);
14832cad1ffSPhilippe Mathieu-Daudé out:
14932cad1ffSPhilippe Mathieu-Daudé visit_end_struct(visitor, NULL);
15032cad1ffSPhilippe Mathieu-Daudé visit_free(visitor);
15132cad1ffSPhilippe Mathieu-Daudé }
15232cad1ffSPhilippe Mathieu-Daudé
15332cad1ffSPhilippe Mathieu-Daudé /* Create X86CPU object according to model+props specification */
x86_cpu_from_model(const char * model,QObject * props,const char * props_arg_name,Error ** errp)15432cad1ffSPhilippe Mathieu-Daudé static X86CPU *x86_cpu_from_model(const char *model, QObject *props,
15532cad1ffSPhilippe Mathieu-Daudé const char *props_arg_name, Error **errp)
15632cad1ffSPhilippe Mathieu-Daudé {
15732cad1ffSPhilippe Mathieu-Daudé X86CPU *xc = NULL;
15832cad1ffSPhilippe Mathieu-Daudé X86CPUClass *xcc;
15932cad1ffSPhilippe Mathieu-Daudé Error *err = NULL;
16032cad1ffSPhilippe Mathieu-Daudé
16132cad1ffSPhilippe Mathieu-Daudé xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model));
16232cad1ffSPhilippe Mathieu-Daudé if (xcc == NULL) {
16332cad1ffSPhilippe Mathieu-Daudé error_setg(&err, "CPU model '%s' not found", model);
16432cad1ffSPhilippe Mathieu-Daudé goto out;
16532cad1ffSPhilippe Mathieu-Daudé }
16632cad1ffSPhilippe Mathieu-Daudé
16732cad1ffSPhilippe Mathieu-Daudé xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
16832cad1ffSPhilippe Mathieu-Daudé if (props) {
16932cad1ffSPhilippe Mathieu-Daudé object_apply_props(OBJECT(xc), props, props_arg_name, &err);
17032cad1ffSPhilippe Mathieu-Daudé if (err) {
17132cad1ffSPhilippe Mathieu-Daudé goto out;
17232cad1ffSPhilippe Mathieu-Daudé }
17332cad1ffSPhilippe Mathieu-Daudé }
17432cad1ffSPhilippe Mathieu-Daudé
17532cad1ffSPhilippe Mathieu-Daudé x86_cpu_expand_features(xc, &err);
17632cad1ffSPhilippe Mathieu-Daudé if (err) {
17732cad1ffSPhilippe Mathieu-Daudé goto out;
17832cad1ffSPhilippe Mathieu-Daudé }
17932cad1ffSPhilippe Mathieu-Daudé
18032cad1ffSPhilippe Mathieu-Daudé out:
18132cad1ffSPhilippe Mathieu-Daudé if (err) {
18232cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, err);
18332cad1ffSPhilippe Mathieu-Daudé object_unref(OBJECT(xc));
18432cad1ffSPhilippe Mathieu-Daudé xc = NULL;
18532cad1ffSPhilippe Mathieu-Daudé }
18632cad1ffSPhilippe Mathieu-Daudé return xc;
18732cad1ffSPhilippe Mathieu-Daudé }
18832cad1ffSPhilippe Mathieu-Daudé
18932cad1ffSPhilippe Mathieu-Daudé CpuModelExpansionInfo *
qmp_query_cpu_model_expansion(CpuModelExpansionType type,CpuModelInfo * model,Error ** errp)19032cad1ffSPhilippe Mathieu-Daudé qmp_query_cpu_model_expansion(CpuModelExpansionType type,
19132cad1ffSPhilippe Mathieu-Daudé CpuModelInfo *model,
19232cad1ffSPhilippe Mathieu-Daudé Error **errp)
19332cad1ffSPhilippe Mathieu-Daudé {
19432cad1ffSPhilippe Mathieu-Daudé X86CPU *xc = NULL;
19532cad1ffSPhilippe Mathieu-Daudé Error *err = NULL;
19632cad1ffSPhilippe Mathieu-Daudé CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
19732cad1ffSPhilippe Mathieu-Daudé QDict *props = NULL;
19832cad1ffSPhilippe Mathieu-Daudé const char *base_name;
19932cad1ffSPhilippe Mathieu-Daudé
20032cad1ffSPhilippe Mathieu-Daudé xc = x86_cpu_from_model(model->name, model->props, "model.props", &err);
20132cad1ffSPhilippe Mathieu-Daudé if (err) {
20232cad1ffSPhilippe Mathieu-Daudé goto out;
20332cad1ffSPhilippe Mathieu-Daudé }
20432cad1ffSPhilippe Mathieu-Daudé
20532cad1ffSPhilippe Mathieu-Daudé props = qdict_new();
20632cad1ffSPhilippe Mathieu-Daudé ret->model = g_new0(CpuModelInfo, 1);
20732cad1ffSPhilippe Mathieu-Daudé ret->model->props = QOBJECT(props);
20832cad1ffSPhilippe Mathieu-Daudé
20932cad1ffSPhilippe Mathieu-Daudé switch (type) {
21032cad1ffSPhilippe Mathieu-Daudé case CPU_MODEL_EXPANSION_TYPE_STATIC:
21132cad1ffSPhilippe Mathieu-Daudé /* Static expansion will be based on "base" only */
21232cad1ffSPhilippe Mathieu-Daudé base_name = "base";
21332cad1ffSPhilippe Mathieu-Daudé x86_cpu_to_dict(xc, props);
21432cad1ffSPhilippe Mathieu-Daudé break;
21532cad1ffSPhilippe Mathieu-Daudé case CPU_MODEL_EXPANSION_TYPE_FULL:
21632cad1ffSPhilippe Mathieu-Daudé /* As we don't return every single property, full expansion needs
21732cad1ffSPhilippe Mathieu-Daudé * to keep the original model name+props, and add extra
21832cad1ffSPhilippe Mathieu-Daudé * properties on top of that.
21932cad1ffSPhilippe Mathieu-Daudé */
22032cad1ffSPhilippe Mathieu-Daudé base_name = model->name;
22132cad1ffSPhilippe Mathieu-Daudé x86_cpu_to_dict_full(xc, props);
22232cad1ffSPhilippe Mathieu-Daudé break;
22332cad1ffSPhilippe Mathieu-Daudé default:
22432cad1ffSPhilippe Mathieu-Daudé error_setg(&err, "Unsupported expansion type");
22532cad1ffSPhilippe Mathieu-Daudé goto out;
22632cad1ffSPhilippe Mathieu-Daudé }
22732cad1ffSPhilippe Mathieu-Daudé
22832cad1ffSPhilippe Mathieu-Daudé x86_cpu_to_dict(xc, props);
22932cad1ffSPhilippe Mathieu-Daudé
23032cad1ffSPhilippe Mathieu-Daudé ret->model->name = g_strdup(base_name);
23132cad1ffSPhilippe Mathieu-Daudé
23232cad1ffSPhilippe Mathieu-Daudé out:
23332cad1ffSPhilippe Mathieu-Daudé object_unref(OBJECT(xc));
23432cad1ffSPhilippe Mathieu-Daudé if (err) {
23532cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, err);
23632cad1ffSPhilippe Mathieu-Daudé qapi_free_CpuModelExpansionInfo(ret);
23732cad1ffSPhilippe Mathieu-Daudé ret = NULL;
23832cad1ffSPhilippe Mathieu-Daudé }
23932cad1ffSPhilippe Mathieu-Daudé return ret;
24032cad1ffSPhilippe Mathieu-Daudé }
24132cad1ffSPhilippe Mathieu-Daudé
cpu_clear_apic_feature(CPUX86State * env)24232cad1ffSPhilippe Mathieu-Daudé void cpu_clear_apic_feature(CPUX86State *env)
24332cad1ffSPhilippe Mathieu-Daudé {
24432cad1ffSPhilippe Mathieu-Daudé env->features[FEAT_1_EDX] &= ~CPUID_APIC;
24532cad1ffSPhilippe Mathieu-Daudé }
24632cad1ffSPhilippe Mathieu-Daudé
cpu_set_apic_feature(CPUX86State * env)24732cad1ffSPhilippe Mathieu-Daudé void cpu_set_apic_feature(CPUX86State *env)
24832cad1ffSPhilippe Mathieu-Daudé {
24932cad1ffSPhilippe Mathieu-Daudé env->features[FEAT_1_EDX] |= CPUID_APIC;
25032cad1ffSPhilippe Mathieu-Daudé }
25132cad1ffSPhilippe Mathieu-Daudé
cpu_has_x2apic_feature(CPUX86State * env)25232cad1ffSPhilippe Mathieu-Daudé bool cpu_has_x2apic_feature(CPUX86State *env)
25332cad1ffSPhilippe Mathieu-Daudé {
25432cad1ffSPhilippe Mathieu-Daudé return env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
25532cad1ffSPhilippe Mathieu-Daudé }
25632cad1ffSPhilippe Mathieu-Daudé
cpu_is_bsp(X86CPU * cpu)25732cad1ffSPhilippe Mathieu-Daudé bool cpu_is_bsp(X86CPU *cpu)
25832cad1ffSPhilippe Mathieu-Daudé {
25932cad1ffSPhilippe Mathieu-Daudé return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
26032cad1ffSPhilippe Mathieu-Daudé }
26132cad1ffSPhilippe Mathieu-Daudé
26232cad1ffSPhilippe Mathieu-Daudé /* TODO: remove me, when reset over QOM tree is implemented */
x86_cpu_machine_reset_cb(void * opaque)26332cad1ffSPhilippe Mathieu-Daudé void x86_cpu_machine_reset_cb(void *opaque)
26432cad1ffSPhilippe Mathieu-Daudé {
26532cad1ffSPhilippe Mathieu-Daudé X86CPU *cpu = opaque;
26632cad1ffSPhilippe Mathieu-Daudé cpu_reset(CPU(cpu));
26732cad1ffSPhilippe Mathieu-Daudé }
26832cad1ffSPhilippe Mathieu-Daudé
x86_cpu_get_crash_info(CPUState * cs)26932cad1ffSPhilippe Mathieu-Daudé GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
27032cad1ffSPhilippe Mathieu-Daudé {
27132cad1ffSPhilippe Mathieu-Daudé X86CPU *cpu = X86_CPU(cs);
27232cad1ffSPhilippe Mathieu-Daudé CPUX86State *env = &cpu->env;
27332cad1ffSPhilippe Mathieu-Daudé GuestPanicInformation *panic_info = NULL;
27432cad1ffSPhilippe Mathieu-Daudé
27532cad1ffSPhilippe Mathieu-Daudé if (hyperv_feat_enabled(cpu, HYPERV_FEAT_CRASH)) {
27632cad1ffSPhilippe Mathieu-Daudé panic_info = g_new0(GuestPanicInformation, 1);
27732cad1ffSPhilippe Mathieu-Daudé
27832cad1ffSPhilippe Mathieu-Daudé panic_info->type = GUEST_PANIC_INFORMATION_TYPE_HYPER_V;
27932cad1ffSPhilippe Mathieu-Daudé
28032cad1ffSPhilippe Mathieu-Daudé assert(HV_CRASH_PARAMS >= 5);
28132cad1ffSPhilippe Mathieu-Daudé panic_info->u.hyper_v.arg1 = env->msr_hv_crash_params[0];
28232cad1ffSPhilippe Mathieu-Daudé panic_info->u.hyper_v.arg2 = env->msr_hv_crash_params[1];
28332cad1ffSPhilippe Mathieu-Daudé panic_info->u.hyper_v.arg3 = env->msr_hv_crash_params[2];
28432cad1ffSPhilippe Mathieu-Daudé panic_info->u.hyper_v.arg4 = env->msr_hv_crash_params[3];
28532cad1ffSPhilippe Mathieu-Daudé panic_info->u.hyper_v.arg5 = env->msr_hv_crash_params[4];
28632cad1ffSPhilippe Mathieu-Daudé }
28732cad1ffSPhilippe Mathieu-Daudé
28832cad1ffSPhilippe Mathieu-Daudé return panic_info;
28932cad1ffSPhilippe Mathieu-Daudé }
x86_cpu_get_crash_info_qom(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)29032cad1ffSPhilippe Mathieu-Daudé void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
29132cad1ffSPhilippe Mathieu-Daudé const char *name, void *opaque,
29232cad1ffSPhilippe Mathieu-Daudé Error **errp)
29332cad1ffSPhilippe Mathieu-Daudé {
29432cad1ffSPhilippe Mathieu-Daudé CPUState *cs = CPU(obj);
29532cad1ffSPhilippe Mathieu-Daudé GuestPanicInformation *panic_info;
29632cad1ffSPhilippe Mathieu-Daudé
29732cad1ffSPhilippe Mathieu-Daudé if (!cs->crash_occurred) {
29832cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "No crash occurred");
29932cad1ffSPhilippe Mathieu-Daudé return;
30032cad1ffSPhilippe Mathieu-Daudé }
30132cad1ffSPhilippe Mathieu-Daudé
30232cad1ffSPhilippe Mathieu-Daudé panic_info = x86_cpu_get_crash_info(cs);
30332cad1ffSPhilippe Mathieu-Daudé if (panic_info == NULL) {
30432cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "No crash information");
30532cad1ffSPhilippe Mathieu-Daudé return;
30632cad1ffSPhilippe Mathieu-Daudé }
30732cad1ffSPhilippe Mathieu-Daudé
30832cad1ffSPhilippe Mathieu-Daudé visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
30932cad1ffSPhilippe Mathieu-Daudé errp);
31032cad1ffSPhilippe Mathieu-Daudé qapi_free_GuestPanicInformation(panic_info);
31132cad1ffSPhilippe Mathieu-Daudé }
312d3bb5d0dSXiaoyao Li
cpu_x86_get_msr_core_thread_count(X86CPU * cpu)313d3bb5d0dSXiaoyao Li uint64_t cpu_x86_get_msr_core_thread_count(X86CPU *cpu)
314d3bb5d0dSXiaoyao Li {
31584b71a13SXiaoyao Li CPUX86State *env = &cpu->env;
316d3bb5d0dSXiaoyao Li uint64_t val;
317d3bb5d0dSXiaoyao Li
31884b71a13SXiaoyao Li val = x86_threads_per_pkg(&env->topo_info); /* thread count, bits 15..0 */
31984b71a13SXiaoyao Li val |= x86_cores_per_pkg(&env->topo_info) << 16; /* core count, bits 31..16 */
320d3bb5d0dSXiaoyao Li
321d3bb5d0dSXiaoyao Li return val;
322d3bb5d0dSXiaoyao Li }
323