aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViktor Mihajlovski <mihajlov@linux.vnet.ibm.com>2017-07-03 13:48:49 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2017-07-05 19:44:24 +0200
commit38cba1f4d83525e728719d7ac6e9551cddfadee6 (patch)
treecc60193dc121839709faf15fc220a1c56b683ddb
parentc1976ae7a291956ba3d79228150e4c1d21f5d998 (diff)
s390x: return unavailable features via query-cpu-definitions
The response for query-cpu-definitions didn't include the unavailable-features field, which is used by libvirt to figure out whether a certain cpu model is usable on the host. The unavailable features are now computed by obtaining the host CPU model and comparing it against the known CPU models. The comparison takes into account the generation, the GA level and the feature bitmaps. In the case of a CPU generation/GA level mismatch a feature called "type" is reported to be missing. As a result, the output of virsh domcapabilities would change from something like ... <mode name='custom' supported='yes'> <model usable='unknown'>z10EC-base</model> <model usable='unknown'>z9EC-base</model> <model usable='unknown'>z196.2-base</model> <model usable='unknown'>z900-base</model> <model usable='unknown'>z990</model> ... to ... <mode name='custom' supported='yes'> <model usable='yes'>z10EC-base</model> <model usable='yes'>z9EC-base</model> <model usable='no'>z196.2-base</model> <model usable='yes'>z900-base</model> <model usable='yes'>z990</model> ... Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Message-Id: <1499082529-16970-1-git-send-email-mihajlov@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Acked-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--target/s390x/cpu_models.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 63903c2d6f..7cb55dc7e3 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -283,10 +283,41 @@ void s390_cpu_list(FILE *f, fprintf_function print)
}
}
+static S390CPUModel *get_max_cpu_model(Error **errp);
+
#ifndef CONFIG_USER_ONLY
+static void list_add_feat(const char *name, void *opaque);
+
+static void check_unavailable_features(const S390CPUModel *max_model,
+ const S390CPUModel *model,
+ strList **unavailable)
+{
+ S390FeatBitmap missing;
+
+ /* check general model compatibility */
+ if (max_model->def->gen < model->def->gen ||
+ (max_model->def->gen == model->def->gen &&
+ max_model->def->ec_ga < model->def->ec_ga)) {
+ list_add_feat("type", unavailable);
+ }
+
+ /* detect missing features if any to properly report them */
+ bitmap_andnot(missing, model->features, max_model->features,
+ S390_FEAT_MAX);
+ if (!bitmap_empty(missing, S390_FEAT_MAX)) {
+ s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat);
+ }
+}
+
+struct CpuDefinitionInfoListData {
+ CpuDefinitionInfoList *list;
+ S390CPUModel *model;
+};
+
static void create_cpu_model_list(ObjectClass *klass, void *opaque)
{
- CpuDefinitionInfoList **cpu_list = opaque;
+ struct CpuDefinitionInfoListData *cpu_list_data = opaque;
+ CpuDefinitionInfoList **cpu_list = &cpu_list_data->list;
CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
char *name = g_strdup(object_class_get_name(klass));
@@ -300,7 +331,19 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
info->migration_safe = scc->is_migration_safe;
info->q_static = scc->is_static;
info->q_typename = g_strdup(object_class_get_name(klass));
-
+ /* check for unavailable features */
+ if (cpu_list_data->model) {
+ Object *obj;
+ S390CPU *sc;
+ obj = object_new(object_class_get_name(klass));
+ sc = S390_CPU(obj);
+ if (sc->model) {
+ info->has_unavailable_features = true;
+ check_unavailable_features(cpu_list_data->model, sc->model,
+ &info->unavailable_features);
+ }
+ object_unref(obj);
+ }
entry = g_malloc0(sizeof(*entry));
entry->value = info;
@@ -310,11 +353,20 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
{
- CpuDefinitionInfoList *list = NULL;
+ struct CpuDefinitionInfoListData list_data = {
+ .list = NULL,
+ };
+
+ list_data.model = get_max_cpu_model(errp);
+ if (*errp) {
+ error_free(*errp);
+ *errp = NULL;
+ }
- object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, &list);
+ object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false,
+ &list_data);
- return list;
+ return list_data.list;
}
static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,