qxl: call qemu_spice_display_init_common for secondary devices
[qemu/ar7.git] / target / s390x / cpu_models.c
blobfa1338fc725f1bc31b55ae46fe47ae726dac4a75
1 /*
2 * CPU models for s390x
4 * Copyright 2016 IBM Corp.
6 * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or (at
9 * your option) any later version. See the COPYING file in the top-level
10 * directory.
13 #include "qemu/osdep.h"
14 #include "cpu.h"
15 #include "gen-features.h"
16 #include "qapi/error.h"
17 #include "qapi/visitor.h"
18 #include "qemu/error-report.h"
19 #include "qapi/qmp/qerror.h"
20 #include "qapi/qobject-input-visitor.h"
21 #include "qapi/qmp/qbool.h"
22 #ifndef CONFIG_USER_ONLY
23 #include "sysemu/arch_init.h"
24 #endif
26 #define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \
27 { \
28 .name = _name, \
29 .type = _type, \
30 .gen = _gen, \
31 .ec_ga = _ec_ga, \
32 .mha_pow = _mha_pow, \
33 .hmfai = _hmfai, \
34 .desc = _desc, \
35 .base_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _BASE }, \
36 .default_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _DEFAULT }, \
37 .full_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _FULL }, \
41 * CPU definiton list in order of release. For now, base features of a
42 * following release are always a subset of base features of the previous
43 * release. Same is correct for the other feature sets.
44 * A BC release always follows the corresponding EC release.
46 static S390CPUDef s390_cpu_defs[] = {
47 CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"),
48 CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"),
49 CPUDEF_INIT(0x2064, 7, 3, 38, 0x00000000U, "z900.3", "IBM zSeries 900 GA3"),
50 CPUDEF_INIT(0x2066, 7, 3, 38, 0x00000000U, "z800", "IBM zSeries 800 GA1"),
51 CPUDEF_INIT(0x2084, 8, 1, 38, 0x00000000U, "z990", "IBM zSeries 990 GA1"),
52 CPUDEF_INIT(0x2084, 8, 2, 38, 0x00000000U, "z990.2", "IBM zSeries 990 GA2"),
53 CPUDEF_INIT(0x2084, 8, 3, 38, 0x00000000U, "z990.3", "IBM zSeries 990 GA3"),
54 CPUDEF_INIT(0x2086, 8, 3, 38, 0x00000000U, "z890", "IBM zSeries 880 GA1"),
55 CPUDEF_INIT(0x2084, 8, 4, 38, 0x00000000U, "z990.4", "IBM zSeries 990 GA4"),
56 CPUDEF_INIT(0x2086, 8, 4, 38, 0x00000000U, "z890.2", "IBM zSeries 880 GA2"),
57 CPUDEF_INIT(0x2084, 8, 5, 38, 0x00000000U, "z990.5", "IBM zSeries 990 GA5"),
58 CPUDEF_INIT(0x2086, 8, 5, 38, 0x00000000U, "z890.3", "IBM zSeries 880 GA3"),
59 CPUDEF_INIT(0x2094, 9, 1, 40, 0x00000000U, "z9EC", "IBM System z9 EC GA1"),
60 CPUDEF_INIT(0x2094, 9, 2, 40, 0x00000000U, "z9EC.2", "IBM System z9 EC GA2"),
61 CPUDEF_INIT(0x2096, 9, 2, 40, 0x00000000U, "z9BC", "IBM System z9 BC GA1"),
62 CPUDEF_INIT(0x2094, 9, 3, 40, 0x00000000U, "z9EC.3", "IBM System z9 EC GA3"),
63 CPUDEF_INIT(0x2096, 9, 3, 40, 0x00000000U, "z9BC.2", "IBM System z9 BC GA2"),
64 CPUDEF_INIT(0x2097, 10, 1, 43, 0x00000000U, "z10EC", "IBM System z10 EC GA1"),
65 CPUDEF_INIT(0x2097, 10, 2, 43, 0x00000000U, "z10EC.2", "IBM System z10 EC GA2"),
66 CPUDEF_INIT(0x2098, 10, 2, 43, 0x00000000U, "z10BC", "IBM System z10 BC GA1"),
67 CPUDEF_INIT(0x2097, 10, 3, 43, 0x00000000U, "z10EC.3", "IBM System z10 EC GA3"),
68 CPUDEF_INIT(0x2098, 10, 3, 43, 0x00000000U, "z10BC.2", "IBM System z10 BC GA2"),
69 CPUDEF_INIT(0x2817, 11, 1, 44, 0x08000000U, "z196", "IBM zEnterprise 196 GA1"),
70 CPUDEF_INIT(0x2817, 11, 2, 44, 0x08000000U, "z196.2", "IBM zEnterprise 196 GA2"),
71 CPUDEF_INIT(0x2818, 11, 2, 44, 0x08000000U, "z114", "IBM zEnterprise 114 GA1"),
72 CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"),
73 CPUDEF_INIT(0x2827, 12, 2, 44, 0x08000000U, "zEC12.2", "IBM zEnterprise EC12 GA2"),
74 CPUDEF_INIT(0x2828, 12, 2, 44, 0x08000000U, "zBC12", "IBM zEnterprise BC12 GA1"),
75 CPUDEF_INIT(0x2964, 13, 1, 47, 0x08000000U, "z13", "IBM z13 GA1"),
76 CPUDEF_INIT(0x2964, 13, 2, 47, 0x08000000U, "z13.2", "IBM z13 GA2"),
77 CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
78 CPUDEF_INIT(0x3906, 14, 1, 47, 0x08000000U, "z14", "IBM z14 GA1"),
81 /* features part of a base model but not relevant for finding a base model */
82 S390FeatBitmap ignored_base_feat;
84 void s390_cpudef_featoff(uint8_t gen, uint8_t ec_ga, S390Feat feat)
86 const S390CPUDef *def;
88 def = s390_find_cpu_def(0, gen, ec_ga, NULL);
89 clear_bit(feat, (unsigned long *)&def->default_feat);
92 void s390_cpudef_featoff_greater(uint8_t gen, uint8_t ec_ga, S390Feat feat)
94 int i;
96 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
97 const S390CPUDef *def = &s390_cpu_defs[i];
99 if (def->gen < gen) {
100 continue;
102 if (def->gen == gen && def->ec_ga < ec_ga) {
103 continue;
106 clear_bit(feat, (unsigned long *)&def->default_feat);
110 uint32_t s390_get_hmfai(void)
112 static S390CPU *cpu;
114 if (!cpu) {
115 cpu = S390_CPU(qemu_get_cpu(0));
118 if (!cpu || !cpu->model) {
119 return 0;
121 return cpu->model->def->hmfai;
124 uint8_t s390_get_mha_pow(void)
126 static S390CPU *cpu;
128 if (!cpu) {
129 cpu = S390_CPU(qemu_get_cpu(0));
132 if (!cpu || !cpu->model) {
133 return 0;
135 return cpu->model->def->mha_pow;
138 uint32_t s390_get_ibc_val(void)
140 uint16_t unblocked_ibc, lowest_ibc;
141 static S390CPU *cpu;
143 if (!cpu) {
144 cpu = S390_CPU(qemu_get_cpu(0));
147 if (!cpu || !cpu->model) {
148 return 0;
150 unblocked_ibc = s390_ibc_from_cpu_model(cpu->model);
151 lowest_ibc = cpu->model->lowest_ibc;
152 /* the lowest_ibc always has to be <= unblocked_ibc */
153 if (!lowest_ibc || lowest_ibc > unblocked_ibc) {
154 return 0;
156 return ((uint32_t) lowest_ibc << 16) | unblocked_ibc;
159 void s390_get_feat_block(S390FeatType type, uint8_t *data)
161 static S390CPU *cpu;
163 if (!cpu) {
164 cpu = S390_CPU(qemu_get_cpu(0));
167 if (!cpu || !cpu->model) {
168 return;
170 s390_fill_feat_block(cpu->model->features, type, data);
173 bool s390_has_feat(S390Feat feat)
175 static S390CPU *cpu;
177 if (!cpu) {
178 cpu = S390_CPU(qemu_get_cpu(0));
181 if (!cpu || !cpu->model) {
182 #ifdef CONFIG_KVM
183 if (kvm_enabled()) {
184 if (feat == S390_FEAT_VECTOR) {
185 return kvm_check_extension(kvm_state,
186 KVM_CAP_S390_VECTOR_REGISTERS);
188 if (feat == S390_FEAT_RUNTIME_INSTRUMENTATION) {
189 return kvm_s390_get_ri();
191 if (feat == S390_FEAT_MSA_EXT_3) {
192 return true;
195 #endif
196 return 0;
198 return test_bit(feat, cpu->model->features);
201 uint8_t s390_get_gen_for_cpu_type(uint16_t type)
203 int i;
205 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
206 if (s390_cpu_defs[i].type == type) {
207 return s390_cpu_defs[i].gen;
210 return 0;
213 const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
214 S390FeatBitmap features)
216 const S390CPUDef *last_compatible = NULL;
217 const S390CPUDef *matching_cpu_type = NULL;
218 int i;
220 if (!gen) {
221 ec_ga = 0;
223 if (!gen && type) {
224 gen = s390_get_gen_for_cpu_type(type);
227 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
228 const S390CPUDef *def = &s390_cpu_defs[i];
229 S390FeatBitmap missing;
231 /* don't even try newer generations if we know the generation */
232 if (gen) {
233 if (def->gen > gen) {
234 break;
235 } else if (def->gen == gen && ec_ga && def->ec_ga > ec_ga) {
236 break;
240 if (features) {
241 /* see if the model satisfies the minimum features */
242 bitmap_andnot(missing, def->base_feat, features, S390_FEAT_MAX);
244 * Ignore certain features that are in the base model, but not
245 * relevant for the search (esp. MSA subfunctions).
247 bitmap_andnot(missing, missing, ignored_base_feat, S390_FEAT_MAX);
248 if (!bitmap_empty(missing, S390_FEAT_MAX)) {
249 break;
253 /* stop the search if we found the exact model */
254 if (def->type == type && def->ec_ga == ec_ga) {
255 return def;
257 /* remember if we've at least seen one with the same cpu type */
258 if (def->type == type) {
259 matching_cpu_type = def;
261 last_compatible = def;
263 /* prefer the model with the same cpu type, esp. don't take the BC for EC */
264 if (matching_cpu_type) {
265 return matching_cpu_type;
267 return last_compatible;
270 struct S390PrintCpuListInfo {
271 FILE *f;
272 fprintf_function print;
275 static void print_cpu_model_list(ObjectClass *klass, void *opaque)
277 struct S390PrintCpuListInfo *info = opaque;
278 S390CPUClass *scc = S390_CPU_CLASS(klass);
279 char *name = g_strdup(object_class_get_name(klass));
280 const char *details = "";
282 if (scc->is_static) {
283 details = "(static, migration-safe)";
284 } else if (scc->is_migration_safe) {
285 details = "(migration-safe)";
288 /* strip off the -s390-cpu */
289 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
290 (*info->print)(info->f, "s390 %-15s %-35s %s\n", name, scc->desc,
291 details);
292 g_free(name);
295 void s390_cpu_list(FILE *f, fprintf_function print)
297 struct S390PrintCpuListInfo info = {
298 .f = f,
299 .print = print,
301 S390FeatGroup group;
302 S390Feat feat;
304 object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info);
306 (*print)(f, "\nRecognized feature flags:\n");
307 for (feat = 0; feat < S390_FEAT_MAX; feat++) {
308 const S390FeatDef *def = s390_feat_def(feat);
310 (*print)(f, "%-20s %-50s\n", def->name, def->desc);
313 (*print)(f, "\nRecognized feature groups:\n");
314 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
315 const S390FeatGroupDef *def = s390_feat_group_def(group);
317 (*print)(f, "%-20s %-50s\n", def->name, def->desc);
321 static S390CPUModel *get_max_cpu_model(Error **errp);
323 #ifndef CONFIG_USER_ONLY
324 static void list_add_feat(const char *name, void *opaque);
326 static void check_unavailable_features(const S390CPUModel *max_model,
327 const S390CPUModel *model,
328 strList **unavailable)
330 S390FeatBitmap missing;
332 /* check general model compatibility */
333 if (max_model->def->gen < model->def->gen ||
334 (max_model->def->gen == model->def->gen &&
335 max_model->def->ec_ga < model->def->ec_ga)) {
336 list_add_feat("type", unavailable);
339 /* detect missing features if any to properly report them */
340 bitmap_andnot(missing, model->features, max_model->features,
341 S390_FEAT_MAX);
342 if (!bitmap_empty(missing, S390_FEAT_MAX)) {
343 s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat);
347 struct CpuDefinitionInfoListData {
348 CpuDefinitionInfoList *list;
349 S390CPUModel *model;
352 static void create_cpu_model_list(ObjectClass *klass, void *opaque)
354 struct CpuDefinitionInfoListData *cpu_list_data = opaque;
355 CpuDefinitionInfoList **cpu_list = &cpu_list_data->list;
356 CpuDefinitionInfoList *entry;
357 CpuDefinitionInfo *info;
358 char *name = g_strdup(object_class_get_name(klass));
359 S390CPUClass *scc = S390_CPU_CLASS(klass);
361 /* strip off the -s390-cpu */
362 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
363 info = g_malloc0(sizeof(*info));
364 info->name = name;
365 info->has_migration_safe = true;
366 info->migration_safe = scc->is_migration_safe;
367 info->q_static = scc->is_static;
368 info->q_typename = g_strdup(object_class_get_name(klass));
369 /* check for unavailable features */
370 if (cpu_list_data->model) {
371 Object *obj;
372 S390CPU *sc;
373 obj = object_new(object_class_get_name(klass));
374 sc = S390_CPU(obj);
375 if (sc->model) {
376 info->has_unavailable_features = true;
377 check_unavailable_features(cpu_list_data->model, sc->model,
378 &info->unavailable_features);
380 object_unref(obj);
383 entry = g_malloc0(sizeof(*entry));
384 entry->value = info;
385 entry->next = *cpu_list;
386 *cpu_list = entry;
389 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
391 struct CpuDefinitionInfoListData list_data = {
392 .list = NULL,
395 list_data.model = get_max_cpu_model(errp);
396 if (*errp) {
397 error_free(*errp);
398 *errp = NULL;
401 object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false,
402 &list_data);
404 return list_data.list;
407 static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
408 Error **errp)
410 const QDict *qdict = NULL;
411 const QDictEntry *e;
412 Visitor *visitor;
413 ObjectClass *oc;
414 S390CPU *cpu;
415 Object *obj;
417 if (info->props) {
418 qdict = qobject_to_qdict(info->props);
419 if (!qdict) {
420 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
421 return;
425 oc = cpu_class_by_name(TYPE_S390_CPU, info->name);
426 if (!oc) {
427 error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name);
428 return;
430 if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) {
431 error_setg(errp, "The CPU definition '%s' requires KVM", info->name);
432 return;
434 obj = object_new(object_class_get_name(oc));
435 cpu = S390_CPU(obj);
437 if (!cpu->model) {
438 error_setg(errp, "Details about the host CPU model are not available, "
439 "it cannot be used.");
440 object_unref(obj);
441 return;
444 if (qdict) {
445 visitor = qobject_input_visitor_new(info->props);
446 visit_start_struct(visitor, NULL, NULL, 0, errp);
447 if (*errp) {
448 object_unref(obj);
449 return;
451 for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
452 object_property_set(obj, visitor, e->key, errp);
453 if (*errp) {
454 break;
457 if (!*errp) {
458 visit_check_struct(visitor, errp);
460 visit_end_struct(visitor, NULL);
461 visit_free(visitor);
462 if (*errp) {
463 object_unref(obj);
464 return;
468 /* copy the model and throw the cpu away */
469 memcpy(model, cpu->model, sizeof(*model));
470 object_unref(obj);
473 static void qdict_add_disabled_feat(const char *name, void *opaque)
475 qdict_put_bool(opaque, name, false);
478 static void qdict_add_enabled_feat(const char *name, void *opaque)
480 qdict_put_bool(opaque, name, true);
483 /* convert S390CPUDef into a static CpuModelInfo */
484 static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
485 bool delta_changes)
487 QDict *qdict = qdict_new();
488 S390FeatBitmap bitmap;
490 /* always fallback to the static base model */
491 info->name = g_strdup_printf("%s-base", model->def->name);
493 if (delta_changes) {
494 /* features deleted from the base feature set */
495 bitmap_andnot(bitmap, model->def->base_feat, model->features,
496 S390_FEAT_MAX);
497 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
498 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
501 /* features added to the base feature set */
502 bitmap_andnot(bitmap, model->features, model->def->base_feat,
503 S390_FEAT_MAX);
504 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
505 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
507 } else {
508 /* expand all features */
509 s390_feat_bitmap_to_ascii(model->features, qdict,
510 qdict_add_enabled_feat);
511 bitmap_complement(bitmap, model->features, S390_FEAT_MAX);
512 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
515 if (!qdict_size(qdict)) {
516 QDECREF(qdict);
517 } else {
518 info->props = QOBJECT(qdict);
519 info->has_props = true;
523 CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
524 CpuModelInfo *model,
525 Error **errp)
527 CpuModelExpansionInfo *expansion_info = NULL;
528 S390CPUModel s390_model;
529 bool delta_changes = false;
531 /* convert it to our internal representation */
532 cpu_model_from_info(&s390_model, model, errp);
533 if (*errp) {
534 return NULL;
537 if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) {
538 delta_changes = true;
539 } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
540 error_setg(errp, "The requested expansion type is not supported.");
541 return NULL;
544 /* convert it back to a static representation */
545 expansion_info = g_malloc0(sizeof(*expansion_info));
546 expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
547 cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
548 return expansion_info;
551 static void list_add_feat(const char *name, void *opaque)
553 strList **last = (strList **) opaque;
554 strList *entry;
556 entry = g_malloc0(sizeof(*entry));
557 entry->value = g_strdup(name);
558 entry->next = *last;
559 *last = entry;
562 CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa,
563 CpuModelInfo *infob,
564 Error **errp)
566 CpuModelCompareResult feat_result, gen_result;
567 CpuModelCompareInfo *compare_info;
568 S390FeatBitmap missing, added;
569 S390CPUModel modela, modelb;
571 /* convert both models to our internal representation */
572 cpu_model_from_info(&modela, infoa, errp);
573 if (*errp) {
574 return NULL;
576 cpu_model_from_info(&modelb, infob, errp);
577 if (*errp) {
578 return NULL;
580 compare_info = g_malloc0(sizeof(*compare_info));
582 /* check the cpu generation and ga level */
583 if (modela.def->gen == modelb.def->gen) {
584 if (modela.def->ec_ga == modelb.def->ec_ga) {
585 /* ec and corresponding bc are identical */
586 gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
587 } else if (modela.def->ec_ga < modelb.def->ec_ga) {
588 gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
589 } else {
590 gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
592 } else if (modela.def->gen < modelb.def->gen) {
593 gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
594 } else {
595 gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
597 if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
598 /* both models cannot be made identical */
599 list_add_feat("type", &compare_info->responsible_properties);
602 /* check the feature set */
603 if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) {
604 feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
605 } else {
606 bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX);
607 s390_feat_bitmap_to_ascii(missing,
608 &compare_info->responsible_properties,
609 list_add_feat);
610 bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX);
611 s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties,
612 list_add_feat);
613 if (bitmap_empty(missing, S390_FEAT_MAX)) {
614 feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
615 } else if (bitmap_empty(added, S390_FEAT_MAX)) {
616 feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
617 } else {
618 feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
622 /* combine the results */
623 if (gen_result == feat_result) {
624 compare_info->result = gen_result;
625 } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
626 compare_info->result = gen_result;
627 } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
628 compare_info->result = feat_result;
629 } else {
630 compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
632 return compare_info;
635 CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *infoa,
636 CpuModelInfo *infob,
637 Error **errp)
639 CpuModelBaselineInfo *baseline_info;
640 S390CPUModel modela, modelb, model;
641 uint16_t cpu_type;
642 uint8_t max_gen_ga;
643 uint8_t max_gen;
645 /* convert both models to our internal representation */
646 cpu_model_from_info(&modela, infoa, errp);
647 if (*errp) {
648 return NULL;
651 cpu_model_from_info(&modelb, infob, errp);
652 if (*errp) {
653 return NULL;
656 /* features both models support */
657 bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX);
659 /* detect the maximum model not regarding features */
660 if (modela.def->gen == modelb.def->gen) {
661 if (modela.def->type == modelb.def->type) {
662 cpu_type = modela.def->type;
663 } else {
664 cpu_type = 0;
666 max_gen = modela.def->gen;
667 max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga);
668 } else if (modela.def->gen > modelb.def->gen) {
669 cpu_type = modelb.def->type;
670 max_gen = modelb.def->gen;
671 max_gen_ga = modelb.def->ec_ga;
672 } else {
673 cpu_type = modela.def->type;
674 max_gen = modela.def->gen;
675 max_gen_ga = modela.def->ec_ga;
678 model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga,
679 model.features);
680 /* strip off features not part of the max model */
681 bitmap_and(model.features, model.features, model.def->full_feat,
682 S390_FEAT_MAX);
684 baseline_info = g_malloc0(sizeof(*baseline_info));
685 baseline_info->model = g_malloc0(sizeof(*baseline_info->model));
686 cpu_info_from_model(baseline_info->model, &model, true);
687 return baseline_info;
689 #endif
691 static void check_consistency(const S390CPUModel *model)
693 static int dep[][2] = {
694 { S390_FEAT_IPTE_RANGE, S390_FEAT_DAT_ENH },
695 { S390_FEAT_IDTE_SEGMENT, S390_FEAT_DAT_ENH },
696 { S390_FEAT_IDTE_REGION, S390_FEAT_DAT_ENH },
697 { S390_FEAT_IDTE_REGION, S390_FEAT_IDTE_SEGMENT },
698 { S390_FEAT_LOCAL_TLB_CLEARING, S390_FEAT_DAT_ENH},
699 { S390_FEAT_LONG_DISPLACEMENT_FAST, S390_FEAT_LONG_DISPLACEMENT },
700 { S390_FEAT_DFP_FAST, S390_FEAT_DFP },
701 { S390_FEAT_TRANSACTIONAL_EXE, S390_FEAT_STFLE_49 },
702 { S390_FEAT_EDAT_2, S390_FEAT_EDAT},
703 { S390_FEAT_MSA_EXT_5, S390_FEAT_KIMD_SHA_512 },
704 { S390_FEAT_MSA_EXT_5, S390_FEAT_KLMD_SHA_512 },
705 { S390_FEAT_MSA_EXT_4, S390_FEAT_MSA_EXT_3 },
706 { S390_FEAT_SIE_CMMA, S390_FEAT_CMM },
707 { S390_FEAT_SIE_CMMA, S390_FEAT_SIE_GSLS },
708 { S390_FEAT_SIE_PFMFI, S390_FEAT_EDAT },
709 { S390_FEAT_MSA_EXT_8, S390_FEAT_MSA_EXT_3 },
710 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING },
711 { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR },
712 { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR },
713 { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 },
714 { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP },
715 { S390_FEAT_CMM_NT, S390_FEAT_CMM },
716 { S390_FEAT_GUARDED_STORAGE, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 },
717 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_STORE_CLOCK_FAST },
718 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING },
719 { S390_FEAT_SEMAPHORE_ASSIST, S390_FEAT_STFLE_49 },
720 { S390_FEAT_KIMD_SHA3_224, S390_FEAT_MSA },
721 { S390_FEAT_KIMD_SHA3_256, S390_FEAT_MSA },
722 { S390_FEAT_KIMD_SHA3_384, S390_FEAT_MSA },
723 { S390_FEAT_KIMD_SHA3_512, S390_FEAT_MSA },
724 { S390_FEAT_KIMD_SHAKE_128, S390_FEAT_MSA },
725 { S390_FEAT_KIMD_SHAKE_256, S390_FEAT_MSA },
726 { S390_FEAT_KLMD_SHA3_224, S390_FEAT_MSA },
727 { S390_FEAT_KLMD_SHA3_256, S390_FEAT_MSA },
728 { S390_FEAT_KLMD_SHA3_384, S390_FEAT_MSA },
729 { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA },
730 { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA },
731 { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA },
732 { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 },
733 { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 },
734 { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 },
736 int i;
738 for (i = 0; i < ARRAY_SIZE(dep); i++) {
739 if (test_bit(dep[i][0], model->features) &&
740 !test_bit(dep[i][1], model->features)) {
741 warn_report("\'%s\' requires \'%s\'.",
742 s390_feat_def(dep[i][0])->name,
743 s390_feat_def(dep[i][1])->name);
748 static void error_prepend_missing_feat(const char *name, void *opaque)
750 error_prepend((Error **) opaque, "%s ", name);
753 static void check_compatibility(const S390CPUModel *max_model,
754 const S390CPUModel *model, Error **errp)
756 S390FeatBitmap missing;
758 if (model->def->gen > max_model->def->gen) {
759 error_setg(errp, "Selected CPU generation is too new. Maximum "
760 "supported model in the configuration: \'%s\'",
761 max_model->def->name);
762 return;
763 } else if (model->def->gen == max_model->def->gen &&
764 model->def->ec_ga > max_model->def->ec_ga) {
765 error_setg(errp, "Selected CPU GA level is too new. Maximum "
766 "supported model in the configuration: \'%s\'",
767 max_model->def->name);
768 return;
771 /* detect the missing features to properly report them */
772 bitmap_andnot(missing, model->features, max_model->features, S390_FEAT_MAX);
773 if (bitmap_empty(missing, S390_FEAT_MAX)) {
774 return;
777 error_setg(errp, " ");
778 s390_feat_bitmap_to_ascii(missing, errp, error_prepend_missing_feat);
779 error_prepend(errp, "Some features requested in the CPU model are not "
780 "available in the configuration: ");
784 * The base TCG CPU model "qemu" is based on the z900. However, we already
785 * can also emulate some additional features of later CPU generations, so
786 * we add these additional feature bits here.
788 static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
790 static const int feats[] = {
791 S390_FEAT_DAT_ENH,
792 S390_FEAT_IDTE_SEGMENT,
793 S390_FEAT_STFLE,
794 S390_FEAT_EXTENDED_IMMEDIATE,
795 S390_FEAT_EXTENDED_TRANSLATION_2,
796 S390_FEAT_EXTENDED_TRANSLATION_3,
797 S390_FEAT_LONG_DISPLACEMENT,
798 S390_FEAT_LONG_DISPLACEMENT_FAST,
799 S390_FEAT_ETF2_ENH,
800 S390_FEAT_STORE_CLOCK_FAST,
801 S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
802 S390_FEAT_ETF3_ENH,
803 S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
804 S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
805 S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
806 S390_FEAT_EXECUTE_EXT,
807 S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
808 S390_FEAT_STFLE_45,
809 S390_FEAT_STFLE_49,
810 S390_FEAT_LOCAL_TLB_CLEARING,
811 S390_FEAT_STFLE_53,
813 int i;
815 for (i = 0; i < ARRAY_SIZE(feats); i++) {
816 set_bit(feats[i], fbm);
820 static S390CPUModel *get_max_cpu_model(Error **errp)
822 static S390CPUModel max_model;
823 static bool cached;
825 if (cached) {
826 return &max_model;
829 if (kvm_enabled()) {
830 kvm_s390_get_host_cpu_model(&max_model, errp);
831 } else {
832 /* TCG emulates a z900 (with some optional additional features) */
833 max_model.def = &s390_cpu_defs[0];
834 bitmap_copy(max_model.features, max_model.def->default_feat,
835 S390_FEAT_MAX);
836 add_qemu_cpu_model_features(max_model.features);
838 if (!*errp) {
839 cached = true;
840 return &max_model;
842 return NULL;
845 static inline void apply_cpu_model(const S390CPUModel *model, Error **errp)
847 #ifndef CONFIG_USER_ONLY
848 static S390CPUModel applied_model;
849 static bool applied;
852 * We have the same model for all VCPUs. KVM can only be configured before
853 * any VCPUs are defined in KVM.
855 if (applied) {
856 if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) {
857 error_setg(errp, "Mixed CPU models are not supported on s390x.");
859 return;
862 if (kvm_enabled()) {
863 kvm_s390_apply_cpu_model(model, errp);
866 if (!*errp) {
867 applied = true;
868 if (model) {
869 applied_model = *model;
872 #endif
875 void s390_realize_cpu_model(CPUState *cs, Error **errp)
877 S390CPUClass *xcc = S390_CPU_GET_CLASS(cs);
878 S390CPU *cpu = S390_CPU(cs);
879 const S390CPUModel *max_model;
881 if (xcc->kvm_required && !kvm_enabled()) {
882 error_setg(errp, "CPU definition requires KVM");
883 return;
886 if (!cpu->model) {
887 /* no host model support -> perform compatibility stuff */
888 apply_cpu_model(NULL, errp);
889 return;
892 max_model = get_max_cpu_model(errp);
893 if (*errp) {
894 error_prepend(errp, "CPU models are not available: ");
895 return;
898 /* copy over properties that can vary */
899 cpu->model->lowest_ibc = max_model->lowest_ibc;
900 cpu->model->cpu_id = max_model->cpu_id;
901 cpu->model->cpu_id_format = max_model->cpu_id_format;
902 cpu->model->cpu_ver = max_model->cpu_ver;
904 check_consistency(cpu->model);
905 check_compatibility(max_model, cpu->model, errp);
906 if (*errp) {
907 return;
910 apply_cpu_model(cpu->model, errp);
912 cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model);
913 if (tcg_enabled()) {
914 /* basic mode, write the cpu address into the first 4 bit of the ID */
915 cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.cpu_num);
919 static void get_feature(Object *obj, Visitor *v, const char *name,
920 void *opaque, Error **errp)
922 S390Feat feat = (S390Feat) opaque;
923 S390CPU *cpu = S390_CPU(obj);
924 bool value;
926 if (!cpu->model) {
927 error_setg(errp, "Details about the host CPU model are not available, "
928 "features cannot be queried.");
929 return;
932 value = test_bit(feat, cpu->model->features);
933 visit_type_bool(v, name, &value, errp);
936 static void set_feature(Object *obj, Visitor *v, const char *name,
937 void *opaque, Error **errp)
939 S390Feat feat = (S390Feat) opaque;
940 DeviceState *dev = DEVICE(obj);
941 S390CPU *cpu = S390_CPU(obj);
942 bool value;
944 if (dev->realized) {
945 error_setg(errp, "Attempt to set property '%s' on '%s' after "
946 "it was realized", name, object_get_typename(obj));
947 return;
948 } else if (!cpu->model) {
949 error_setg(errp, "Details about the host CPU model are not available, "
950 "features cannot be changed.");
951 return;
954 visit_type_bool(v, name, &value, errp);
955 if (*errp) {
956 return;
958 if (value) {
959 if (!test_bit(feat, cpu->model->def->full_feat)) {
960 error_setg(errp, "Feature '%s' is not available for CPU model '%s',"
961 " it was introduced with later models.",
962 name, cpu->model->def->name);
963 return;
965 set_bit(feat, cpu->model->features);
966 } else {
967 clear_bit(feat, cpu->model->features);
971 static void get_feature_group(Object *obj, Visitor *v, const char *name,
972 void *opaque, Error **errp)
974 S390FeatGroup group = (S390FeatGroup) opaque;
975 const S390FeatGroupDef *def = s390_feat_group_def(group);
976 S390CPU *cpu = S390_CPU(obj);
977 S390FeatBitmap tmp;
978 bool value;
980 if (!cpu->model) {
981 error_setg(errp, "Details about the host CPU model are not available, "
982 "features cannot be queried.");
983 return;
986 /* a group is enabled if all features are enabled */
987 bitmap_and(tmp, cpu->model->features, def->feat, S390_FEAT_MAX);
988 value = bitmap_equal(tmp, def->feat, S390_FEAT_MAX);
989 visit_type_bool(v, name, &value, errp);
992 static void set_feature_group(Object *obj, Visitor *v, const char *name,
993 void *opaque, Error **errp)
995 S390FeatGroup group = (S390FeatGroup) opaque;
996 const S390FeatGroupDef *def = s390_feat_group_def(group);
997 DeviceState *dev = DEVICE(obj);
998 S390CPU *cpu = S390_CPU(obj);
999 bool value;
1001 if (dev->realized) {
1002 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1003 "it was realized", name, object_get_typename(obj));
1004 return;
1005 } else if (!cpu->model) {
1006 error_setg(errp, "Details about the host CPU model are not available, "
1007 "features cannot be changed.");
1008 return;
1011 visit_type_bool(v, name, &value, errp);
1012 if (*errp) {
1013 return;
1015 if (value) {
1016 /* groups are added in one shot, so an intersect is sufficient */
1017 if (!bitmap_intersects(def->feat, cpu->model->def->full_feat,
1018 S390_FEAT_MAX)) {
1019 error_setg(errp, "Group '%s' is not available for CPU model '%s',"
1020 " it was introduced with later models.",
1021 name, cpu->model->def->name);
1022 return;
1024 bitmap_or(cpu->model->features, cpu->model->features, def->feat,
1025 S390_FEAT_MAX);
1026 } else {
1027 bitmap_andnot(cpu->model->features, cpu->model->features, def->feat,
1028 S390_FEAT_MAX);
1032 void s390_cpu_model_register_props(Object *obj)
1034 S390FeatGroup group;
1035 S390Feat feat;
1037 for (feat = 0; feat < S390_FEAT_MAX; feat++) {
1038 const S390FeatDef *def = s390_feat_def(feat);
1039 object_property_add(obj, def->name, "bool", get_feature,
1040 set_feature, NULL, (void *) feat, NULL);
1041 object_property_set_description(obj, def->name, def->desc , NULL);
1043 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
1044 const S390FeatGroupDef *def = s390_feat_group_def(group);
1045 object_property_add(obj, def->name, "bool", get_feature_group,
1046 set_feature_group, NULL, (void *) group, NULL);
1047 object_property_set_description(obj, def->name, def->desc , NULL);
1051 static void s390_cpu_model_initfn(Object *obj)
1053 S390CPU *cpu = S390_CPU(obj);
1054 S390CPUClass *xcc = S390_CPU_GET_CLASS(cpu);
1056 cpu->model = g_malloc0(sizeof(*cpu->model));
1057 /* copy the model, so we can modify it */
1058 cpu->model->def = xcc->cpu_def;
1059 if (xcc->is_static) {
1060 /* base model - features will never change */
1061 bitmap_copy(cpu->model->features, cpu->model->def->base_feat,
1062 S390_FEAT_MAX);
1063 } else {
1064 /* latest model - features can change */
1065 bitmap_copy(cpu->model->features,
1066 cpu->model->def->default_feat, S390_FEAT_MAX);
1070 #ifdef CONFIG_KVM
1071 static void s390_host_cpu_model_initfn(Object *obj)
1073 S390CPU *cpu = S390_CPU(obj);
1074 Error *err = NULL;
1076 if (!kvm_enabled() || !kvm_s390_cpu_models_supported()) {
1077 return;
1080 cpu->model = g_malloc0(sizeof(*cpu->model));
1081 kvm_s390_get_host_cpu_model(cpu->model, &err);
1082 if (err) {
1083 error_report_err(err);
1084 g_free(cpu->model);
1085 /* fallback to unsupported cpu models */
1086 cpu->model = NULL;
1089 #endif
1091 static void s390_qemu_cpu_model_initfn(Object *obj)
1093 static S390CPUDef s390_qemu_cpu_defs;
1094 S390CPU *cpu = S390_CPU(obj);
1096 cpu->model = g_malloc0(sizeof(*cpu->model));
1097 /* TCG emulates a z900 (with some optional additional features) */
1098 memcpy(&s390_qemu_cpu_defs, &s390_cpu_defs[0], sizeof(s390_qemu_cpu_defs));
1099 add_qemu_cpu_model_features(s390_qemu_cpu_defs.full_feat);
1100 cpu->model->def = &s390_qemu_cpu_defs;
1101 bitmap_copy(cpu->model->features, cpu->model->def->default_feat,
1102 S390_FEAT_MAX);
1105 static void s390_cpu_model_finalize(Object *obj)
1107 S390CPU *cpu = S390_CPU(obj);
1109 g_free(cpu->model);
1110 cpu->model = NULL;
1113 static bool get_is_migration_safe(Object *obj, Error **errp)
1115 return S390_CPU_GET_CLASS(obj)->is_migration_safe;
1118 static bool get_is_static(Object *obj, Error **errp)
1120 return S390_CPU_GET_CLASS(obj)->is_static;
1123 static char *get_description(Object *obj, Error **errp)
1125 return g_strdup(S390_CPU_GET_CLASS(obj)->desc);
1128 void s390_cpu_model_class_register_props(ObjectClass *oc)
1130 object_class_property_add_bool(oc, "migration-safe", get_is_migration_safe,
1131 NULL, NULL);
1132 object_class_property_add_bool(oc, "static", get_is_static,
1133 NULL, NULL);
1134 object_class_property_add_str(oc, "description", get_description, NULL,
1135 NULL);
1138 #ifdef CONFIG_KVM
1139 static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
1141 S390CPUClass *xcc = S390_CPU_CLASS(oc);
1143 xcc->kvm_required = true;
1144 xcc->desc = "KVM only: All recognized features";
1146 #endif
1148 static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
1150 S390CPUClass *xcc = S390_CPU_CLASS(oc);
1152 /* all base models are migration safe */
1153 xcc->cpu_def = (const S390CPUDef *) data;
1154 xcc->is_migration_safe = true;
1155 xcc->is_static = true;
1156 xcc->desc = xcc->cpu_def->desc;
1159 static void s390_cpu_model_class_init(ObjectClass *oc, void *data)
1161 S390CPUClass *xcc = S390_CPU_CLASS(oc);
1163 /* model that can change between QEMU versions */
1164 xcc->cpu_def = (const S390CPUDef *) data;
1165 xcc->is_migration_safe = true;
1166 xcc->desc = xcc->cpu_def->desc;
1169 static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
1171 S390CPUClass *xcc = S390_CPU_CLASS(oc);
1173 xcc->is_migration_safe = true;
1174 xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s",
1175 qemu_hw_version());
1178 #define S390_CPU_TYPE_SUFFIX "-" TYPE_S390_CPU
1179 #define S390_CPU_TYPE_NAME(name) (name S390_CPU_TYPE_SUFFIX)
1181 /* Generate type name for a cpu model. Caller has to free the string. */
1182 static char *s390_cpu_type_name(const char *model_name)
1184 return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name);
1187 /* Generate type name for a base cpu model. Caller has to free the string. */
1188 static char *s390_base_cpu_type_name(const char *model_name)
1190 return g_strdup_printf(S390_CPU_TYPE_NAME("%s-base"), model_name);
1193 ObjectClass *s390_cpu_class_by_name(const char *name)
1195 char *typename = s390_cpu_type_name(name);
1196 ObjectClass *oc;
1198 oc = object_class_by_name(typename);
1199 g_free(typename);
1200 return oc;
1203 static const TypeInfo qemu_s390_cpu_type_info = {
1204 .name = S390_CPU_TYPE_NAME("qemu"),
1205 .parent = TYPE_S390_CPU,
1206 .instance_init = s390_qemu_cpu_model_initfn,
1207 .instance_finalize = s390_cpu_model_finalize,
1208 .class_init = s390_qemu_cpu_model_class_init,
1211 #ifdef CONFIG_KVM
1212 static const TypeInfo host_s390_cpu_type_info = {
1213 .name = S390_CPU_TYPE_NAME("host"),
1214 .parent = TYPE_S390_CPU,
1215 .instance_init = s390_host_cpu_model_initfn,
1216 .instance_finalize = s390_cpu_model_finalize,
1217 .class_init = s390_host_cpu_model_class_init,
1219 #endif
1221 static void init_ignored_base_feat(void)
1223 static const int feats[] = {
1224 /* MSA subfunctions that could not be available on certain machines */
1225 S390_FEAT_KMAC_DEA,
1226 S390_FEAT_KMAC_TDEA_128,
1227 S390_FEAT_KMAC_TDEA_192,
1228 S390_FEAT_KMC_DEA,
1229 S390_FEAT_KMC_TDEA_128,
1230 S390_FEAT_KMC_TDEA_192,
1231 S390_FEAT_KM_DEA,
1232 S390_FEAT_KM_TDEA_128,
1233 S390_FEAT_KM_TDEA_192,
1234 S390_FEAT_KIMD_SHA_1,
1235 S390_FEAT_KLMD_SHA_1,
1237 int i;
1239 for (i = 0; i < ARRAY_SIZE(feats); i++) {
1240 set_bit(feats[i], ignored_base_feat);
1244 static void register_types(void)
1246 int i;
1248 init_ignored_base_feat();
1250 /* init all bitmaps from gnerated data initially */
1251 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
1252 s390_init_feat_bitmap(s390_cpu_defs[i].base_init,
1253 s390_cpu_defs[i].base_feat);
1254 s390_init_feat_bitmap(s390_cpu_defs[i].default_init,
1255 s390_cpu_defs[i].default_feat);
1256 s390_init_feat_bitmap(s390_cpu_defs[i].full_init,
1257 s390_cpu_defs[i].full_feat);
1260 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
1261 char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name);
1262 TypeInfo ti_base = {
1263 .name = base_name,
1264 .parent = TYPE_S390_CPU,
1265 .instance_init = s390_cpu_model_initfn,
1266 .instance_finalize = s390_cpu_model_finalize,
1267 .class_init = s390_base_cpu_model_class_init,
1268 .class_data = (void *) &s390_cpu_defs[i],
1270 char *name = s390_cpu_type_name(s390_cpu_defs[i].name);
1271 TypeInfo ti = {
1272 .name = name,
1273 .parent = TYPE_S390_CPU,
1274 .instance_init = s390_cpu_model_initfn,
1275 .instance_finalize = s390_cpu_model_finalize,
1276 .class_init = s390_cpu_model_class_init,
1277 .class_data = (void *) &s390_cpu_defs[i],
1280 type_register_static(&ti_base);
1281 type_register_static(&ti);
1282 g_free(base_name);
1283 g_free(name);
1286 type_register_static(&qemu_s390_cpu_type_info);
1287 #ifdef CONFIG_KVM
1288 type_register_static(&host_s390_cpu_type_info);
1289 #endif
1292 type_init(register_types)