Commit 0788a56b authored by Eduardo Habkost's avatar Eduardo Habkost
Browse files

i386: Make unversioned CPU models be aliases



This will make unversioned CPU models behavior depend on the
machine type:

* "pc-*-4.0" and older will not report them as aliases.
  This is done to keep compatibility with older QEMU versions
  after management software starts translating aliases.

* "pc-*-4.1" will translate unversioned CPU models to -v1.
  This is done to keep compatibility with existing management
  software, that still relies on CPU model runnability promises.

* "none" will translate unversioned CPU models to their latest
  version.  This is planned become the default in future machine
  types (probably in pc-*-4.3).

Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
Message-Id: <20190628002844.24894-8-ehabkost@redhat.com>
Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
parent 53db89d9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1645,6 +1645,9 @@ void pc_cpus_init(PCMachineState *pcms)
    const CPUArchIdList *possible_cpus;
    MachineState *ms = MACHINE(pcms);
    MachineClass *mc = MACHINE_GET_CLASS(pcms);
    PCMachineClass *pcmc = PC_MACHINE_CLASS(mc);

    x86_cpu_set_default_version(pcmc->default_cpu_version);

    /* Calculates the limit to CPU APIC ID values
     *
+4 −0
Original line number Diff line number Diff line
@@ -429,9 +429,11 @@ static void pc_i440fx_machine_options(MachineClass *m)

static void pc_i440fx_4_1_machine_options(MachineClass *m)
{
    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
    pc_i440fx_machine_options(m);
    m->alias = "pc";
    m->is_default = 1;
    pcmc->default_cpu_version = 1;
}

DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL,
@@ -439,9 +441,11 @@ DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL,

static void pc_i440fx_4_0_machine_options(MachineClass *m)
{
    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
    pc_i440fx_4_1_machine_options(m);
    m->alias = NULL;
    m->is_default = 0;
    pcmc->default_cpu_version = CPU_VERSION_LEGACY;
    compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
    compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
}
+4 −0
Original line number Diff line number Diff line
@@ -367,8 +367,10 @@ static void pc_q35_machine_options(MachineClass *m)

static void pc_q35_4_1_machine_options(MachineClass *m)
{
    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
    pc_q35_machine_options(m);
    m->alias = "q35";
    pcmc->default_cpu_version = 1;
}

DEFINE_Q35_MACHINE(v4_1, "pc-q35-4.1", NULL,
@@ -376,8 +378,10 @@ DEFINE_Q35_MACHINE(v4_1, "pc-q35-4.1", NULL,

static void pc_q35_4_0_1_machine_options(MachineClass *m)
{
    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
    pc_q35_4_1_machine_options(m);
    m->alias = NULL;
    pcmc->default_cpu_version = CPU_VERSION_LEGACY;
    /*
     * This is the default machine for the 4.0-stable branch. It is basically
     * a 4.0 that doesn't use split irqchip by default. It MUST hence apply the
+3 −0
Original line number Diff line number Diff line
@@ -109,6 +109,9 @@ typedef struct PCMachineClass {

    /* Compat options: */

    /* Default CPU model version.  See x86_cpu_set_default_version(). */
    int default_cpu_version;

    /* ACPI compat: */
    bool has_acpi_build;
    bool rsdp_in_ram;
+51 −1
Original line number Diff line number Diff line
@@ -1470,6 +1470,11 @@ struct X86CPUModel {
    X86CPUDefinition *cpudef;
    /* CPU model version */
    X86CPUVersion version;
    /*
     * If true, this is an alias CPU model.
     * This matters only for "-cpu help" and query-cpu-definitions
     */
    bool is_alias;
};

/* Get full model name for CPU version */
@@ -2835,6 +2840,15 @@ static PropValue tcg_default_props[] = {
};


X86CPUVersion default_cpu_version = CPU_VERSION_LATEST;

void x86_cpu_set_default_version(X86CPUVersion version)
{
    /* Translating CPU_VERSION_AUTO to CPU_VERSION_AUTO doesn't make sense */
    assert(version != CPU_VERSION_AUTO);
    default_cpu_version = version;
}

static X86CPUVersion x86_cpu_model_last_version(const X86CPUModel *model)
{
    int v = 0;
@@ -2851,6 +2865,9 @@ static X86CPUVersion x86_cpu_model_last_version(const X86CPUModel *model)
static X86CPUVersion x86_cpu_model_resolve_version(const X86CPUModel *model)
{
    X86CPUVersion v = model->version;
    if (v == CPU_VERSION_AUTO) {
        v = default_cpu_version;
    }
    if (v == CPU_VERSION_LATEST) {
        return x86_cpu_model_last_version(model);
    }
@@ -3589,13 +3606,35 @@ static char *x86_cpu_class_get_model_id(X86CPUClass *xc)
    return r;
}

static char *x86_cpu_class_get_alias_of(X86CPUClass *cc)
{
    X86CPUVersion version;

    if (!cc->model || !cc->model->is_alias) {
        return NULL;
    }
    version = x86_cpu_model_resolve_version(cc->model);
    if (version <= 0) {
        return NULL;
    }
    return x86_cpu_versioned_model_name(cc->model->cpudef, version);
}

static void x86_cpu_list_entry(gpointer data, gpointer user_data)
{
    ObjectClass *oc = data;
    X86CPUClass *cc = X86_CPU_CLASS(oc);
    char *name = x86_cpu_class_get_model_name(cc);
    char *desc = g_strdup(cc->model_description);
    char *alias_of = x86_cpu_class_get_alias_of(cc);

    if (!desc && alias_of) {
        if (cc->model && cc->model->version == CPU_VERSION_AUTO) {
            desc = g_strdup("(alias configured by machine type)");
        } else {
            desc = g_strdup_printf("(alias of %s)", alias_of);
        }
    }
    if (!desc) {
        desc = x86_cpu_class_get_model_id(cc);
    }
@@ -3603,6 +3642,7 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data)
    qemu_printf("x86 %-20s  %-48s\n", name, desc);
    g_free(name);
    g_free(desc);
    g_free(alias_of);
}

/* list available CPU models and flags */
@@ -3651,6 +3691,14 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
    info->migration_safe = cc->migration_safe;
    info->has_migration_safe = true;
    info->q_static = cc->static_model;
    /*
     * Old machine types won't report aliases, so that alias translation
     * doesn't break compatibility with previous QEMU versions.
     */
    if (default_cpu_version != CPU_VERSION_LEGACY) {
        info->alias_of = x86_cpu_class_get_alias_of(cc);
        info->has_alias_of = !!info->alias_of;
    }

    entry = g_malloc0(sizeof(*entry));
    entry->value = info;
@@ -4070,7 +4118,8 @@ static void x86_register_cpudef_types(X86CPUDefinition *def)
    /* Unversioned model: */
    m = g_new0(X86CPUModel, 1);
    m->cpudef = def;
    m->version = CPU_VERSION_LEGACY;
    m->version = CPU_VERSION_AUTO;
    m->is_alias = true;
    x86_register_cpu_model_type(def->name, m);

    /* Versioned models: */
@@ -4087,6 +4136,7 @@ static void x86_register_cpudef_types(X86CPUDefinition *def)
            X86CPUModel *am = g_new0(X86CPUModel, 1);
            am->cpudef = def;
            am->version = vdef->version;
            am->is_alias = true;
            x86_register_cpu_model_type(vdef->alias, am);
        }
    }
Loading