mirror of https://github.com/xemu-project/xemu.git
s390x/cpumodel: implement QMP interface "query-cpu-model-comparison"
Let's implement that interface by reusing our convertion code implemented for expansion. We use CPU generations and CPU features to calculate the result. This means, that a zEC12 cannot simply be converted into a z13 by stripping of features. This is required, as other magic values (e.g. maximum address sizes) belong to a CPU generation and cannot simply be emulated by an older generation. Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Message-Id: <20160905085244.99980-30-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
137974cea3
commit
4e82ef0502
|
@ -3232,7 +3232,8 @@
|
||||||
# global properties may affect expansion of CPU models. Using
|
# global properties may affect expansion of CPU models. Using
|
||||||
# query-cpu-model-expansion while using these is not advised.
|
# query-cpu-model-expansion while using these is not advised.
|
||||||
#
|
#
|
||||||
# Some architectures may not support comparing CPU models.
|
# Some architectures may not support comparing CPU models. s390x supports
|
||||||
|
# comparing CPU models.
|
||||||
#
|
#
|
||||||
# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
|
# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
|
||||||
# not supported, if a model cannot be used, if a model contains
|
# not supported, if a model cannot be used, if a model contains
|
||||||
|
|
|
@ -450,6 +450,90 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type
|
||||||
cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
|
cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
|
||||||
return expansion_info;
|
return expansion_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void list_add_feat(const char *name, void *opaque)
|
||||||
|
{
|
||||||
|
strList **last = (strList **) opaque;
|
||||||
|
strList *entry;
|
||||||
|
|
||||||
|
entry = g_malloc0(sizeof(*entry));
|
||||||
|
entry->value = g_strdup(name);
|
||||||
|
entry->next = *last;
|
||||||
|
*last = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa,
|
||||||
|
CpuModelInfo *infob,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
CpuModelCompareResult feat_result, gen_result;
|
||||||
|
CpuModelCompareInfo *compare_info;
|
||||||
|
S390FeatBitmap missing, added;
|
||||||
|
S390CPUModel modela, modelb;
|
||||||
|
|
||||||
|
/* convert both models to our internal representation */
|
||||||
|
cpu_model_from_info(&modela, infoa, errp);
|
||||||
|
if (*errp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cpu_model_from_info(&modelb, infob, errp);
|
||||||
|
if (*errp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
compare_info = g_malloc0(sizeof(*compare_info));
|
||||||
|
|
||||||
|
/* check the cpu generation and ga level */
|
||||||
|
if (modela.def->gen == modelb.def->gen) {
|
||||||
|
if (modela.def->ec_ga == modelb.def->ec_ga) {
|
||||||
|
/* ec and corresponding bc are identical */
|
||||||
|
gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
|
||||||
|
} else if (modela.def->ec_ga < modelb.def->ec_ga) {
|
||||||
|
gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
|
||||||
|
} else {
|
||||||
|
gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
|
||||||
|
}
|
||||||
|
} else if (modela.def->gen < modelb.def->gen) {
|
||||||
|
gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
|
||||||
|
} else {
|
||||||
|
gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
|
||||||
|
}
|
||||||
|
if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
|
||||||
|
/* both models cannot be made identical */
|
||||||
|
list_add_feat("type", &compare_info->responsible_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the feature set */
|
||||||
|
if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) {
|
||||||
|
feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
|
||||||
|
} else {
|
||||||
|
bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX);
|
||||||
|
s390_feat_bitmap_to_ascii(missing,
|
||||||
|
&compare_info->responsible_properties,
|
||||||
|
list_add_feat);
|
||||||
|
bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX);
|
||||||
|
s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties,
|
||||||
|
list_add_feat);
|
||||||
|
if (bitmap_empty(missing, S390_FEAT_MAX)) {
|
||||||
|
feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
|
||||||
|
} else if (bitmap_empty(added, S390_FEAT_MAX)) {
|
||||||
|
feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
|
||||||
|
} else {
|
||||||
|
feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* combine the results */
|
||||||
|
if (gen_result == feat_result) {
|
||||||
|
compare_info->result = gen_result;
|
||||||
|
} else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
|
||||||
|
compare_info->result = gen_result;
|
||||||
|
} else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
|
||||||
|
compare_info->result = feat_result;
|
||||||
|
} else {
|
||||||
|
compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
|
||||||
|
}
|
||||||
|
return compare_info;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void check_consistency(const S390CPUModel *model)
|
static void check_consistency(const S390CPUModel *model)
|
||||||
|
|
Loading…
Reference in New Issue