1 /* 2 * CPU models for s390x 3 * 4 * Copyright 2016 IBM Corp. 5 * 6 * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com> 7 * 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. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "cpu.h" 15 #include "internal.h" 16 #include "kvm_s390x.h" 17 #include "sysemu/kvm.h" 18 #include "qapi/error.h" 19 #include "qapi/visitor.h" 20 #include "qemu/error-report.h" 21 #include "qapi/qmp/qerror.h" 22 #include "qapi/qobject-input-visitor.h" 23 #include "qapi/qmp/qbool.h" 24 #ifndef CONFIG_USER_ONLY 25 #include "sysemu/arch_init.h" 26 #endif 27 28 #define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \ 29 { \ 30 .name = _name, \ 31 .type = _type, \ 32 .gen = _gen, \ 33 .ec_ga = _ec_ga, \ 34 .mha_pow = _mha_pow, \ 35 .hmfai = _hmfai, \ 36 .desc = _desc, \ 37 .base_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _BASE }, \ 38 .default_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _DEFAULT }, \ 39 .full_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _FULL }, \ 40 } 41 42 /* 43 * CPU definiton list in order of release. For now, base features of a 44 * following release are always a subset of base features of the previous 45 * release. Same is correct for the other feature sets. 46 * A BC release always follows the corresponding EC release. 47 */ 48 static S390CPUDef s390_cpu_defs[] = { 49 CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"), 50 CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"), 51 CPUDEF_INIT(0x2064, 7, 3, 38, 0x00000000U, "z900.3", "IBM zSeries 900 GA3"), 52 CPUDEF_INIT(0x2066, 7, 3, 38, 0x00000000U, "z800", "IBM zSeries 800 GA1"), 53 CPUDEF_INIT(0x2084, 8, 1, 38, 0x00000000U, "z990", "IBM zSeries 990 GA1"), 54 CPUDEF_INIT(0x2084, 8, 2, 38, 0x00000000U, "z990.2", "IBM zSeries 990 GA2"), 55 CPUDEF_INIT(0x2084, 8, 3, 38, 0x00000000U, "z990.3", "IBM zSeries 990 GA3"), 56 CPUDEF_INIT(0x2086, 8, 3, 38, 0x00000000U, "z890", "IBM zSeries 880 GA1"), 57 CPUDEF_INIT(0x2084, 8, 4, 38, 0x00000000U, "z990.4", "IBM zSeries 990 GA4"), 58 CPUDEF_INIT(0x2086, 8, 4, 38, 0x00000000U, "z890.2", "IBM zSeries 880 GA2"), 59 CPUDEF_INIT(0x2084, 8, 5, 38, 0x00000000U, "z990.5", "IBM zSeries 990 GA5"), 60 CPUDEF_INIT(0x2086, 8, 5, 38, 0x00000000U, "z890.3", "IBM zSeries 880 GA3"), 61 CPUDEF_INIT(0x2094, 9, 1, 40, 0x00000000U, "z9EC", "IBM System z9 EC GA1"), 62 CPUDEF_INIT(0x2094, 9, 2, 40, 0x00000000U, "z9EC.2", "IBM System z9 EC GA2"), 63 CPUDEF_INIT(0x2096, 9, 2, 40, 0x00000000U, "z9BC", "IBM System z9 BC GA1"), 64 CPUDEF_INIT(0x2094, 9, 3, 40, 0x00000000U, "z9EC.3", "IBM System z9 EC GA3"), 65 CPUDEF_INIT(0x2096, 9, 3, 40, 0x00000000U, "z9BC.2", "IBM System z9 BC GA2"), 66 CPUDEF_INIT(0x2097, 10, 1, 43, 0x00000000U, "z10EC", "IBM System z10 EC GA1"), 67 CPUDEF_INIT(0x2097, 10, 2, 43, 0x00000000U, "z10EC.2", "IBM System z10 EC GA2"), 68 CPUDEF_INIT(0x2098, 10, 2, 43, 0x00000000U, "z10BC", "IBM System z10 BC GA1"), 69 CPUDEF_INIT(0x2097, 10, 3, 43, 0x00000000U, "z10EC.3", "IBM System z10 EC GA3"), 70 CPUDEF_INIT(0x2098, 10, 3, 43, 0x00000000U, "z10BC.2", "IBM System z10 BC GA2"), 71 CPUDEF_INIT(0x2817, 11, 1, 44, 0x08000000U, "z196", "IBM zEnterprise 196 GA1"), 72 CPUDEF_INIT(0x2817, 11, 2, 44, 0x08000000U, "z196.2", "IBM zEnterprise 196 GA2"), 73 CPUDEF_INIT(0x2818, 11, 2, 44, 0x08000000U, "z114", "IBM zEnterprise 114 GA1"), 74 CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"), 75 CPUDEF_INIT(0x2827, 12, 2, 44, 0x08000000U, "zEC12.2", "IBM zEnterprise EC12 GA2"), 76 CPUDEF_INIT(0x2828, 12, 2, 44, 0x08000000U, "zBC12", "IBM zEnterprise BC12 GA1"), 77 CPUDEF_INIT(0x2964, 13, 1, 47, 0x08000000U, "z13", "IBM z13 GA1"), 78 CPUDEF_INIT(0x2964, 13, 2, 47, 0x08000000U, "z13.2", "IBM z13 GA2"), 79 CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"), 80 CPUDEF_INIT(0x3906, 14, 1, 47, 0x08000000U, "z14", "IBM z14 GA1"), 81 }; 82 83 #define QEMU_MAX_CPU_TYPE 0x2827 84 #define QEMU_MAX_CPU_GEN 12 85 #define QEMU_MAX_CPU_EC_GA 2 86 static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX }; 87 static S390FeatBitmap qemu_max_cpu_feat; 88 89 /* features part of a base model but not relevant for finding a base model */ 90 S390FeatBitmap ignored_base_feat; 91 92 void s390_cpudef_featoff(uint8_t gen, uint8_t ec_ga, S390Feat feat) 93 { 94 const S390CPUDef *def; 95 96 def = s390_find_cpu_def(0, gen, ec_ga, NULL); 97 clear_bit(feat, (unsigned long *)&def->default_feat); 98 } 99 100 void s390_cpudef_featoff_greater(uint8_t gen, uint8_t ec_ga, S390Feat feat) 101 { 102 int i; 103 104 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 105 const S390CPUDef *def = &s390_cpu_defs[i]; 106 107 if (def->gen < gen) { 108 continue; 109 } 110 if (def->gen == gen && def->ec_ga < ec_ga) { 111 continue; 112 } 113 114 clear_bit(feat, (unsigned long *)&def->default_feat); 115 } 116 } 117 118 uint32_t s390_get_hmfai(void) 119 { 120 static S390CPU *cpu; 121 122 if (!cpu) { 123 cpu = S390_CPU(qemu_get_cpu(0)); 124 } 125 126 if (!cpu || !cpu->model) { 127 return 0; 128 } 129 return cpu->model->def->hmfai; 130 } 131 132 uint8_t s390_get_mha_pow(void) 133 { 134 static S390CPU *cpu; 135 136 if (!cpu) { 137 cpu = S390_CPU(qemu_get_cpu(0)); 138 } 139 140 if (!cpu || !cpu->model) { 141 return 0; 142 } 143 return cpu->model->def->mha_pow; 144 } 145 146 uint32_t s390_get_ibc_val(void) 147 { 148 uint16_t unblocked_ibc, lowest_ibc; 149 static S390CPU *cpu; 150 151 if (!cpu) { 152 cpu = S390_CPU(qemu_get_cpu(0)); 153 } 154 155 if (!cpu || !cpu->model) { 156 return 0; 157 } 158 unblocked_ibc = s390_ibc_from_cpu_model(cpu->model); 159 lowest_ibc = cpu->model->lowest_ibc; 160 /* the lowest_ibc always has to be <= unblocked_ibc */ 161 if (!lowest_ibc || lowest_ibc > unblocked_ibc) { 162 return 0; 163 } 164 return ((uint32_t) lowest_ibc << 16) | unblocked_ibc; 165 } 166 167 void s390_get_feat_block(S390FeatType type, uint8_t *data) 168 { 169 static S390CPU *cpu; 170 171 if (!cpu) { 172 cpu = S390_CPU(qemu_get_cpu(0)); 173 } 174 175 if (!cpu || !cpu->model) { 176 return; 177 } 178 s390_fill_feat_block(cpu->model->features, type, data); 179 } 180 181 bool s390_has_feat(S390Feat feat) 182 { 183 static S390CPU *cpu; 184 185 if (!cpu) { 186 cpu = S390_CPU(qemu_get_cpu(0)); 187 } 188 189 if (!cpu || !cpu->model) { 190 #ifdef CONFIG_KVM 191 if (kvm_enabled()) { 192 if (feat == S390_FEAT_VECTOR) { 193 return kvm_check_extension(kvm_state, 194 KVM_CAP_S390_VECTOR_REGISTERS); 195 } 196 if (feat == S390_FEAT_RUNTIME_INSTRUMENTATION) { 197 return kvm_s390_get_ri(); 198 } 199 if (feat == S390_FEAT_MSA_EXT_3) { 200 return true; 201 } 202 } 203 #endif 204 if (feat == S390_FEAT_ZPCI) { 205 return true; 206 } 207 return 0; 208 } 209 return test_bit(feat, cpu->model->features); 210 } 211 212 uint8_t s390_get_gen_for_cpu_type(uint16_t type) 213 { 214 int i; 215 216 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 217 if (s390_cpu_defs[i].type == type) { 218 return s390_cpu_defs[i].gen; 219 } 220 } 221 return 0; 222 } 223 224 const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga, 225 S390FeatBitmap features) 226 { 227 const S390CPUDef *last_compatible = NULL; 228 const S390CPUDef *matching_cpu_type = NULL; 229 int i; 230 231 if (!gen) { 232 ec_ga = 0; 233 } 234 if (!gen && type) { 235 gen = s390_get_gen_for_cpu_type(type); 236 } 237 238 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 239 const S390CPUDef *def = &s390_cpu_defs[i]; 240 S390FeatBitmap missing; 241 242 /* don't even try newer generations if we know the generation */ 243 if (gen) { 244 if (def->gen > gen) { 245 break; 246 } else if (def->gen == gen && ec_ga && def->ec_ga > ec_ga) { 247 break; 248 } 249 } 250 251 if (features) { 252 /* see if the model satisfies the minimum features */ 253 bitmap_andnot(missing, def->base_feat, features, S390_FEAT_MAX); 254 /* 255 * Ignore certain features that are in the base model, but not 256 * relevant for the search (esp. MSA subfunctions). 257 */ 258 bitmap_andnot(missing, missing, ignored_base_feat, S390_FEAT_MAX); 259 if (!bitmap_empty(missing, S390_FEAT_MAX)) { 260 break; 261 } 262 } 263 264 /* stop the search if we found the exact model */ 265 if (def->type == type && def->ec_ga == ec_ga) { 266 return def; 267 } 268 /* remember if we've at least seen one with the same cpu type */ 269 if (def->type == type) { 270 matching_cpu_type = def; 271 } 272 last_compatible = def; 273 } 274 /* prefer the model with the same cpu type, esp. don't take the BC for EC */ 275 if (matching_cpu_type) { 276 return matching_cpu_type; 277 } 278 return last_compatible; 279 } 280 281 static void s390_print_cpu_model_list_entry(gpointer data, gpointer user_data) 282 { 283 CPUListState *s = user_data; 284 const S390CPUClass *scc = S390_CPU_CLASS((ObjectClass *)data); 285 char *name = g_strdup(object_class_get_name((ObjectClass *)data)); 286 const char *details = ""; 287 288 if (scc->is_static) { 289 details = "(static, migration-safe)"; 290 } else if (scc->is_migration_safe) { 291 details = "(migration-safe)"; 292 } 293 294 /* strip off the -s390x-cpu */ 295 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; 296 (*s->cpu_fprintf)(s->file, "s390 %-15s %-35s %s\n", name, scc->desc, 297 details); 298 g_free(name); 299 } 300 301 static gint s390_cpu_list_compare(gconstpointer a, gconstpointer b) 302 { 303 const S390CPUClass *cc_a = S390_CPU_CLASS((ObjectClass *)a); 304 const S390CPUClass *cc_b = S390_CPU_CLASS((ObjectClass *)b); 305 const char *name_a = object_class_get_name((ObjectClass *)a); 306 const char *name_b = object_class_get_name((ObjectClass *)b); 307 308 /* move qemu and host to the top of the list, qemu first, host second */ 309 if (name_a[0] == 'q') { 310 return -1; 311 } else if (name_b[0] == 'q') { 312 return 1; 313 } else if (name_a[0] == 'h') { 314 return -1; 315 } else if (name_b[0] == 'h') { 316 return 1; 317 } 318 319 /* keep the same order we have in our table (sorted by release date) */ 320 if (cc_a->cpu_def != cc_b->cpu_def) { 321 return cc_a->cpu_def - cc_b->cpu_def; 322 } 323 324 /* exact same definition - list base model first */ 325 return cc_a->is_static ? -1 : 1; 326 } 327 328 void s390_cpu_list(FILE *f, fprintf_function print) 329 { 330 CPUListState s = { 331 .file = f, 332 .cpu_fprintf = print, 333 }; 334 S390FeatGroup group; 335 S390Feat feat; 336 GSList *list; 337 338 list = object_class_get_list(TYPE_S390_CPU, false); 339 list = g_slist_sort(list, s390_cpu_list_compare); 340 g_slist_foreach(list, s390_print_cpu_model_list_entry, &s); 341 g_slist_free(list); 342 343 (*print)(f, "\nRecognized feature flags:\n"); 344 for (feat = 0; feat < S390_FEAT_MAX; feat++) { 345 const S390FeatDef *def = s390_feat_def(feat); 346 347 (*print)(f, "%-20s %-50s\n", def->name, def->desc); 348 } 349 350 (*print)(f, "\nRecognized feature groups:\n"); 351 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { 352 const S390FeatGroupDef *def = s390_feat_group_def(group); 353 354 (*print)(f, "%-20s %-50s\n", def->name, def->desc); 355 } 356 } 357 358 static S390CPUModel *get_max_cpu_model(Error **errp); 359 360 #ifndef CONFIG_USER_ONLY 361 static void list_add_feat(const char *name, void *opaque); 362 363 static void check_unavailable_features(const S390CPUModel *max_model, 364 const S390CPUModel *model, 365 strList **unavailable) 366 { 367 S390FeatBitmap missing; 368 369 /* check general model compatibility */ 370 if (max_model->def->gen < model->def->gen || 371 (max_model->def->gen == model->def->gen && 372 max_model->def->ec_ga < model->def->ec_ga)) { 373 list_add_feat("type", unavailable); 374 } 375 376 /* detect missing features if any to properly report them */ 377 bitmap_andnot(missing, model->features, max_model->features, 378 S390_FEAT_MAX); 379 if (!bitmap_empty(missing, S390_FEAT_MAX)) { 380 s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat); 381 } 382 } 383 384 struct CpuDefinitionInfoListData { 385 CpuDefinitionInfoList *list; 386 S390CPUModel *model; 387 }; 388 389 static void create_cpu_model_list(ObjectClass *klass, void *opaque) 390 { 391 struct CpuDefinitionInfoListData *cpu_list_data = opaque; 392 CpuDefinitionInfoList **cpu_list = &cpu_list_data->list; 393 CpuDefinitionInfoList *entry; 394 CpuDefinitionInfo *info; 395 char *name = g_strdup(object_class_get_name(klass)); 396 S390CPUClass *scc = S390_CPU_CLASS(klass); 397 398 /* strip off the -s390x-cpu */ 399 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; 400 info = g_new0(CpuDefinitionInfo, 1); 401 info->name = name; 402 info->has_migration_safe = true; 403 info->migration_safe = scc->is_migration_safe; 404 info->q_static = scc->is_static; 405 info->q_typename = g_strdup(object_class_get_name(klass)); 406 /* check for unavailable features */ 407 if (cpu_list_data->model) { 408 Object *obj; 409 S390CPU *sc; 410 obj = object_new(object_class_get_name(klass)); 411 sc = S390_CPU(obj); 412 if (sc->model) { 413 info->has_unavailable_features = true; 414 check_unavailable_features(cpu_list_data->model, sc->model, 415 &info->unavailable_features); 416 } 417 object_unref(obj); 418 } 419 420 entry = g_new0(CpuDefinitionInfoList, 1); 421 entry->value = info; 422 entry->next = *cpu_list; 423 *cpu_list = entry; 424 } 425 426 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) 427 { 428 struct CpuDefinitionInfoListData list_data = { 429 .list = NULL, 430 }; 431 432 list_data.model = get_max_cpu_model(errp); 433 if (*errp) { 434 error_free(*errp); 435 *errp = NULL; 436 } 437 438 object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, 439 &list_data); 440 441 return list_data.list; 442 } 443 444 static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, 445 Error **errp) 446 { 447 const QDict *qdict = NULL; 448 const QDictEntry *e; 449 Visitor *visitor; 450 ObjectClass *oc; 451 S390CPU *cpu; 452 Object *obj; 453 454 if (info->props) { 455 qdict = qobject_to_qdict(info->props); 456 if (!qdict) { 457 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); 458 return; 459 } 460 } 461 462 oc = cpu_class_by_name(TYPE_S390_CPU, info->name); 463 if (!oc) { 464 error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name); 465 return; 466 } 467 if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) { 468 error_setg(errp, "The CPU definition '%s' requires KVM", info->name); 469 return; 470 } 471 obj = object_new(object_class_get_name(oc)); 472 cpu = S390_CPU(obj); 473 474 if (!cpu->model) { 475 error_setg(errp, "Details about the host CPU model are not available, " 476 "it cannot be used."); 477 object_unref(obj); 478 return; 479 } 480 481 if (qdict) { 482 visitor = qobject_input_visitor_new(info->props); 483 visit_start_struct(visitor, NULL, NULL, 0, errp); 484 if (*errp) { 485 object_unref(obj); 486 return; 487 } 488 for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { 489 object_property_set(obj, visitor, e->key, errp); 490 if (*errp) { 491 break; 492 } 493 } 494 if (!*errp) { 495 visit_check_struct(visitor, errp); 496 } 497 visit_end_struct(visitor, NULL); 498 visit_free(visitor); 499 if (*errp) { 500 object_unref(obj); 501 return; 502 } 503 } 504 505 /* copy the model and throw the cpu away */ 506 memcpy(model, cpu->model, sizeof(*model)); 507 object_unref(obj); 508 } 509 510 static void qdict_add_disabled_feat(const char *name, void *opaque) 511 { 512 qdict_put_bool(opaque, name, false); 513 } 514 515 static void qdict_add_enabled_feat(const char *name, void *opaque) 516 { 517 qdict_put_bool(opaque, name, true); 518 } 519 520 /* convert S390CPUDef into a static CpuModelInfo */ 521 static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model, 522 bool delta_changes) 523 { 524 QDict *qdict = qdict_new(); 525 S390FeatBitmap bitmap; 526 527 /* always fallback to the static base model */ 528 info->name = g_strdup_printf("%s-base", model->def->name); 529 530 if (delta_changes) { 531 /* features deleted from the base feature set */ 532 bitmap_andnot(bitmap, model->def->base_feat, model->features, 533 S390_FEAT_MAX); 534 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { 535 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); 536 } 537 538 /* features added to the base feature set */ 539 bitmap_andnot(bitmap, model->features, model->def->base_feat, 540 S390_FEAT_MAX); 541 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { 542 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat); 543 } 544 } else { 545 /* expand all features */ 546 s390_feat_bitmap_to_ascii(model->features, qdict, 547 qdict_add_enabled_feat); 548 bitmap_complement(bitmap, model->features, S390_FEAT_MAX); 549 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); 550 } 551 552 if (!qdict_size(qdict)) { 553 QDECREF(qdict); 554 } else { 555 info->props = QOBJECT(qdict); 556 info->has_props = true; 557 } 558 } 559 560 CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type, 561 CpuModelInfo *model, 562 Error **errp) 563 { 564 CpuModelExpansionInfo *expansion_info = NULL; 565 S390CPUModel s390_model; 566 bool delta_changes = false; 567 568 /* convert it to our internal representation */ 569 cpu_model_from_info(&s390_model, model, errp); 570 if (*errp) { 571 return NULL; 572 } 573 574 if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) { 575 delta_changes = true; 576 } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) { 577 error_setg(errp, "The requested expansion type is not supported."); 578 return NULL; 579 } 580 581 /* convert it back to a static representation */ 582 expansion_info = g_new0(CpuModelExpansionInfo, 1); 583 expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); 584 cpu_info_from_model(expansion_info->model, &s390_model, delta_changes); 585 return expansion_info; 586 } 587 588 static void list_add_feat(const char *name, void *opaque) 589 { 590 strList **last = (strList **) opaque; 591 strList *entry; 592 593 entry = g_new0(strList, 1); 594 entry->value = g_strdup(name); 595 entry->next = *last; 596 *last = entry; 597 } 598 599 CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa, 600 CpuModelInfo *infob, 601 Error **errp) 602 { 603 CpuModelCompareResult feat_result, gen_result; 604 CpuModelCompareInfo *compare_info; 605 S390FeatBitmap missing, added; 606 S390CPUModel modela, modelb; 607 608 /* convert both models to our internal representation */ 609 cpu_model_from_info(&modela, infoa, errp); 610 if (*errp) { 611 return NULL; 612 } 613 cpu_model_from_info(&modelb, infob, errp); 614 if (*errp) { 615 return NULL; 616 } 617 compare_info = g_new0(CpuModelCompareInfo, 1); 618 619 /* check the cpu generation and ga level */ 620 if (modela.def->gen == modelb.def->gen) { 621 if (modela.def->ec_ga == modelb.def->ec_ga) { 622 /* ec and corresponding bc are identical */ 623 gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; 624 } else if (modela.def->ec_ga < modelb.def->ec_ga) { 625 gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; 626 } else { 627 gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; 628 } 629 } else if (modela.def->gen < modelb.def->gen) { 630 gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; 631 } else { 632 gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; 633 } 634 if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) { 635 /* both models cannot be made identical */ 636 list_add_feat("type", &compare_info->responsible_properties); 637 } 638 639 /* check the feature set */ 640 if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) { 641 feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; 642 } else { 643 bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX); 644 s390_feat_bitmap_to_ascii(missing, 645 &compare_info->responsible_properties, 646 list_add_feat); 647 bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX); 648 s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties, 649 list_add_feat); 650 if (bitmap_empty(missing, S390_FEAT_MAX)) { 651 feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET; 652 } else if (bitmap_empty(added, S390_FEAT_MAX)) { 653 feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; 654 } else { 655 feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; 656 } 657 } 658 659 /* combine the results */ 660 if (gen_result == feat_result) { 661 compare_info->result = gen_result; 662 } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { 663 compare_info->result = gen_result; 664 } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { 665 compare_info->result = feat_result; 666 } else { 667 compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; 668 } 669 return compare_info; 670 } 671 672 CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *infoa, 673 CpuModelInfo *infob, 674 Error **errp) 675 { 676 CpuModelBaselineInfo *baseline_info; 677 S390CPUModel modela, modelb, model; 678 uint16_t cpu_type; 679 uint8_t max_gen_ga; 680 uint8_t max_gen; 681 682 /* convert both models to our internal representation */ 683 cpu_model_from_info(&modela, infoa, errp); 684 if (*errp) { 685 return NULL; 686 } 687 688 cpu_model_from_info(&modelb, infob, errp); 689 if (*errp) { 690 return NULL; 691 } 692 693 /* features both models support */ 694 bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX); 695 696 /* detect the maximum model not regarding features */ 697 if (modela.def->gen == modelb.def->gen) { 698 if (modela.def->type == modelb.def->type) { 699 cpu_type = modela.def->type; 700 } else { 701 cpu_type = 0; 702 } 703 max_gen = modela.def->gen; 704 max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga); 705 } else if (modela.def->gen > modelb.def->gen) { 706 cpu_type = modelb.def->type; 707 max_gen = modelb.def->gen; 708 max_gen_ga = modelb.def->ec_ga; 709 } else { 710 cpu_type = modela.def->type; 711 max_gen = modela.def->gen; 712 max_gen_ga = modela.def->ec_ga; 713 } 714 715 model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga, 716 model.features); 717 /* strip off features not part of the max model */ 718 bitmap_and(model.features, model.features, model.def->full_feat, 719 S390_FEAT_MAX); 720 721 baseline_info = g_new0(CpuModelBaselineInfo, 1); 722 baseline_info->model = g_malloc0(sizeof(*baseline_info->model)); 723 cpu_info_from_model(baseline_info->model, &model, true); 724 return baseline_info; 725 } 726 #endif 727 728 static void check_consistency(const S390CPUModel *model) 729 { 730 static int dep[][2] = { 731 { S390_FEAT_IPTE_RANGE, S390_FEAT_DAT_ENH }, 732 { S390_FEAT_IDTE_SEGMENT, S390_FEAT_DAT_ENH }, 733 { S390_FEAT_IDTE_REGION, S390_FEAT_DAT_ENH }, 734 { S390_FEAT_IDTE_REGION, S390_FEAT_IDTE_SEGMENT }, 735 { S390_FEAT_LOCAL_TLB_CLEARING, S390_FEAT_DAT_ENH}, 736 { S390_FEAT_LONG_DISPLACEMENT_FAST, S390_FEAT_LONG_DISPLACEMENT }, 737 { S390_FEAT_DFP_FAST, S390_FEAT_DFP }, 738 { S390_FEAT_TRANSACTIONAL_EXE, S390_FEAT_STFLE_49 }, 739 { S390_FEAT_EDAT_2, S390_FEAT_EDAT}, 740 { S390_FEAT_MSA_EXT_5, S390_FEAT_KIMD_SHA_512 }, 741 { S390_FEAT_MSA_EXT_5, S390_FEAT_KLMD_SHA_512 }, 742 { S390_FEAT_MSA_EXT_4, S390_FEAT_MSA_EXT_3 }, 743 { S390_FEAT_SIE_CMMA, S390_FEAT_CMM }, 744 { S390_FEAT_SIE_CMMA, S390_FEAT_SIE_GSLS }, 745 { S390_FEAT_SIE_PFMFI, S390_FEAT_EDAT }, 746 { S390_FEAT_MSA_EXT_8, S390_FEAT_MSA_EXT_3 }, 747 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, 748 { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, 749 { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, 750 { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, 751 { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, 752 { S390_FEAT_CMM_NT, S390_FEAT_CMM }, 753 { S390_FEAT_GUARDED_STORAGE, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, 754 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_STORE_CLOCK_FAST }, 755 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, 756 { S390_FEAT_SEMAPHORE_ASSIST, S390_FEAT_STFLE_49 }, 757 { S390_FEAT_KIMD_SHA3_224, S390_FEAT_MSA }, 758 { S390_FEAT_KIMD_SHA3_256, S390_FEAT_MSA }, 759 { S390_FEAT_KIMD_SHA3_384, S390_FEAT_MSA }, 760 { S390_FEAT_KIMD_SHA3_512, S390_FEAT_MSA }, 761 { S390_FEAT_KIMD_SHAKE_128, S390_FEAT_MSA }, 762 { S390_FEAT_KIMD_SHAKE_256, S390_FEAT_MSA }, 763 { S390_FEAT_KLMD_SHA3_224, S390_FEAT_MSA }, 764 { S390_FEAT_KLMD_SHA3_256, S390_FEAT_MSA }, 765 { S390_FEAT_KLMD_SHA3_384, S390_FEAT_MSA }, 766 { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, 767 { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, 768 { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, 769 { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, 770 { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, 771 { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 }, 772 }; 773 int i; 774 775 for (i = 0; i < ARRAY_SIZE(dep); i++) { 776 if (test_bit(dep[i][0], model->features) && 777 !test_bit(dep[i][1], model->features)) { 778 warn_report("\'%s\' requires \'%s\'.", 779 s390_feat_def(dep[i][0])->name, 780 s390_feat_def(dep[i][1])->name); 781 } 782 } 783 } 784 785 static void error_prepend_missing_feat(const char *name, void *opaque) 786 { 787 error_prepend((Error **) opaque, "%s ", name); 788 } 789 790 static void check_compatibility(const S390CPUModel *max_model, 791 const S390CPUModel *model, Error **errp) 792 { 793 S390FeatBitmap missing; 794 795 if (model->def->gen > max_model->def->gen) { 796 error_setg(errp, "Selected CPU generation is too new. Maximum " 797 "supported model in the configuration: \'%s\'", 798 max_model->def->name); 799 return; 800 } else if (model->def->gen == max_model->def->gen && 801 model->def->ec_ga > max_model->def->ec_ga) { 802 error_setg(errp, "Selected CPU GA level is too new. Maximum " 803 "supported model in the configuration: \'%s\'", 804 max_model->def->name); 805 return; 806 } 807 808 /* detect the missing features to properly report them */ 809 bitmap_andnot(missing, model->features, max_model->features, S390_FEAT_MAX); 810 if (bitmap_empty(missing, S390_FEAT_MAX)) { 811 return; 812 } 813 814 error_setg(errp, " "); 815 s390_feat_bitmap_to_ascii(missing, errp, error_prepend_missing_feat); 816 error_prepend(errp, "Some features requested in the CPU model are not " 817 "available in the configuration: "); 818 } 819 820 static S390CPUModel *get_max_cpu_model(Error **errp) 821 { 822 static S390CPUModel max_model; 823 static bool cached; 824 825 if (cached) { 826 return &max_model; 827 } 828 829 if (kvm_enabled()) { 830 kvm_s390_get_host_cpu_model(&max_model, errp); 831 } else { 832 max_model.def = s390_find_cpu_def(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN, 833 QEMU_MAX_CPU_EC_GA, NULL); 834 bitmap_copy(max_model.features, qemu_max_cpu_feat, S390_FEAT_MAX); 835 } 836 if (!*errp) { 837 cached = true; 838 return &max_model; 839 } 840 return NULL; 841 } 842 843 static inline void apply_cpu_model(const S390CPUModel *model, Error **errp) 844 { 845 #ifndef CONFIG_USER_ONLY 846 static S390CPUModel applied_model; 847 static bool applied; 848 849 /* 850 * We have the same model for all VCPUs. KVM can only be configured before 851 * any VCPUs are defined in KVM. 852 */ 853 if (applied) { 854 if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) { 855 error_setg(errp, "Mixed CPU models are not supported on s390x."); 856 } 857 return; 858 } 859 860 if (kvm_enabled()) { 861 kvm_s390_apply_cpu_model(model, errp); 862 } 863 864 if (!*errp) { 865 applied = true; 866 if (model) { 867 applied_model = *model; 868 } 869 } 870 #endif 871 } 872 873 void s390_realize_cpu_model(CPUState *cs, Error **errp) 874 { 875 S390CPUClass *xcc = S390_CPU_GET_CLASS(cs); 876 S390CPU *cpu = S390_CPU(cs); 877 const S390CPUModel *max_model; 878 879 if (xcc->kvm_required && !kvm_enabled()) { 880 error_setg(errp, "CPU definition requires KVM"); 881 return; 882 } 883 884 if (!cpu->model) { 885 /* no host model support -> perform compatibility stuff */ 886 apply_cpu_model(NULL, errp); 887 return; 888 } 889 890 max_model = get_max_cpu_model(errp); 891 if (*errp) { 892 error_prepend(errp, "CPU models are not available: "); 893 return; 894 } 895 896 /* copy over properties that can vary */ 897 cpu->model->lowest_ibc = max_model->lowest_ibc; 898 cpu->model->cpu_id = max_model->cpu_id; 899 cpu->model->cpu_id_format = max_model->cpu_id_format; 900 cpu->model->cpu_ver = max_model->cpu_ver; 901 902 check_consistency(cpu->model); 903 check_compatibility(max_model, cpu->model, errp); 904 if (*errp) { 905 return; 906 } 907 908 apply_cpu_model(cpu->model, errp); 909 910 #if !defined(CONFIG_USER_ONLY) 911 cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model); 912 if (tcg_enabled()) { 913 /* basic mode, write the cpu address into the first 4 bit of the ID */ 914 cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.core_id); 915 } 916 #endif 917 } 918 919 static void get_feature(Object *obj, Visitor *v, const char *name, 920 void *opaque, Error **errp) 921 { 922 S390Feat feat = (S390Feat) opaque; 923 S390CPU *cpu = S390_CPU(obj); 924 bool value; 925 926 if (!cpu->model) { 927 error_setg(errp, "Details about the host CPU model are not available, " 928 "features cannot be queried."); 929 return; 930 } 931 932 value = test_bit(feat, cpu->model->features); 933 visit_type_bool(v, name, &value, errp); 934 } 935 936 static void set_feature(Object *obj, Visitor *v, const char *name, 937 void *opaque, Error **errp) 938 { 939 S390Feat feat = (S390Feat) opaque; 940 DeviceState *dev = DEVICE(obj); 941 S390CPU *cpu = S390_CPU(obj); 942 bool value; 943 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; 952 } 953 954 visit_type_bool(v, name, &value, errp); 955 if (*errp) { 956 return; 957 } 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; 964 } 965 set_bit(feat, cpu->model->features); 966 } else { 967 clear_bit(feat, cpu->model->features); 968 } 969 } 970 971 static void get_feature_group(Object *obj, Visitor *v, const char *name, 972 void *opaque, Error **errp) 973 { 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; 979 980 if (!cpu->model) { 981 error_setg(errp, "Details about the host CPU model are not available, " 982 "features cannot be queried."); 983 return; 984 } 985 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); 990 } 991 992 static void set_feature_group(Object *obj, Visitor *v, const char *name, 993 void *opaque, Error **errp) 994 { 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; 1000 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; 1009 } 1010 1011 visit_type_bool(v, name, &value, errp); 1012 if (*errp) { 1013 return; 1014 } 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; 1023 } 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); 1029 } 1030 } 1031 1032 void s390_cpu_model_register_props(Object *obj) 1033 { 1034 S390FeatGroup group; 1035 S390Feat feat; 1036 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); 1042 } 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); 1048 } 1049 } 1050 1051 static void s390_cpu_model_initfn(Object *obj) 1052 { 1053 S390CPU *cpu = S390_CPU(obj); 1054 S390CPUClass *xcc = S390_CPU_GET_CLASS(cpu); 1055 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); 1067 } 1068 } 1069 1070 #ifdef CONFIG_KVM 1071 static void s390_host_cpu_model_initfn(Object *obj) 1072 { 1073 S390CPU *cpu = S390_CPU(obj); 1074 Error *err = NULL; 1075 1076 if (!kvm_enabled() || !kvm_s390_cpu_models_supported()) { 1077 return; 1078 } 1079 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; 1087 } 1088 } 1089 #endif 1090 1091 static S390CPUDef s390_qemu_cpu_def; 1092 static S390CPUModel s390_qemu_cpu_model; 1093 1094 /* Set the qemu CPU model (on machine initialization). Must not be called 1095 * once CPUs have been created. 1096 */ 1097 void s390_set_qemu_cpu_model(uint16_t type, uint8_t gen, uint8_t ec_ga, 1098 const S390FeatInit feat_init) 1099 { 1100 const S390CPUDef *def = s390_find_cpu_def(type, gen, ec_ga, NULL); 1101 1102 g_assert(def); 1103 g_assert(QTAILQ_EMPTY(&cpus)); 1104 1105 /* TCG emulates some features that can usually not be enabled with 1106 * the emulated machine generation. Make sure they can be enabled 1107 * when using the QEMU model by adding them to full_feat. We have 1108 * to copy the definition to do that. 1109 */ 1110 memcpy(&s390_qemu_cpu_def, def, sizeof(s390_qemu_cpu_def)); 1111 bitmap_or(s390_qemu_cpu_def.full_feat, s390_qemu_cpu_def.full_feat, 1112 qemu_max_cpu_feat, S390_FEAT_MAX); 1113 1114 /* build the CPU model */ 1115 s390_qemu_cpu_model.def = &s390_qemu_cpu_def; 1116 bitmap_zero(s390_qemu_cpu_model.features, S390_FEAT_MAX); 1117 s390_init_feat_bitmap(feat_init, s390_qemu_cpu_model.features); 1118 } 1119 1120 static void s390_qemu_cpu_model_initfn(Object *obj) 1121 { 1122 S390CPU *cpu = S390_CPU(obj); 1123 1124 cpu->model = g_malloc0(sizeof(*cpu->model)); 1125 /* copy the CPU model so we can modify it */ 1126 memcpy(cpu->model, &s390_qemu_cpu_model, sizeof(*cpu->model)); 1127 } 1128 1129 static void s390_cpu_model_finalize(Object *obj) 1130 { 1131 S390CPU *cpu = S390_CPU(obj); 1132 1133 g_free(cpu->model); 1134 cpu->model = NULL; 1135 } 1136 1137 static bool get_is_migration_safe(Object *obj, Error **errp) 1138 { 1139 return S390_CPU_GET_CLASS(obj)->is_migration_safe; 1140 } 1141 1142 static bool get_is_static(Object *obj, Error **errp) 1143 { 1144 return S390_CPU_GET_CLASS(obj)->is_static; 1145 } 1146 1147 static char *get_description(Object *obj, Error **errp) 1148 { 1149 return g_strdup(S390_CPU_GET_CLASS(obj)->desc); 1150 } 1151 1152 void s390_cpu_model_class_register_props(ObjectClass *oc) 1153 { 1154 object_class_property_add_bool(oc, "migration-safe", get_is_migration_safe, 1155 NULL, NULL); 1156 object_class_property_add_bool(oc, "static", get_is_static, 1157 NULL, NULL); 1158 object_class_property_add_str(oc, "description", get_description, NULL, 1159 NULL); 1160 } 1161 1162 #ifdef CONFIG_KVM 1163 static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) 1164 { 1165 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1166 1167 xcc->kvm_required = true; 1168 xcc->desc = "KVM only: All recognized features"; 1169 } 1170 #endif 1171 1172 static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data) 1173 { 1174 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1175 1176 /* all base models are migration safe */ 1177 xcc->cpu_def = (const S390CPUDef *) data; 1178 xcc->is_migration_safe = true; 1179 xcc->is_static = true; 1180 xcc->desc = xcc->cpu_def->desc; 1181 } 1182 1183 static void s390_cpu_model_class_init(ObjectClass *oc, void *data) 1184 { 1185 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1186 1187 /* model that can change between QEMU versions */ 1188 xcc->cpu_def = (const S390CPUDef *) data; 1189 xcc->is_migration_safe = true; 1190 xcc->desc = xcc->cpu_def->desc; 1191 } 1192 1193 static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data) 1194 { 1195 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1196 1197 xcc->is_migration_safe = true; 1198 xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s", 1199 qemu_hw_version()); 1200 } 1201 1202 /* Generate type name for a cpu model. Caller has to free the string. */ 1203 static char *s390_cpu_type_name(const char *model_name) 1204 { 1205 return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name); 1206 } 1207 1208 /* Generate type name for a base cpu model. Caller has to free the string. */ 1209 static char *s390_base_cpu_type_name(const char *model_name) 1210 { 1211 return g_strdup_printf(S390_CPU_TYPE_NAME("%s-base"), model_name); 1212 } 1213 1214 ObjectClass *s390_cpu_class_by_name(const char *name) 1215 { 1216 char *typename = s390_cpu_type_name(name); 1217 ObjectClass *oc; 1218 1219 oc = object_class_by_name(typename); 1220 g_free(typename); 1221 return oc; 1222 } 1223 1224 static const TypeInfo qemu_s390_cpu_type_info = { 1225 .name = S390_CPU_TYPE_NAME("qemu"), 1226 .parent = TYPE_S390_CPU, 1227 .instance_init = s390_qemu_cpu_model_initfn, 1228 .instance_finalize = s390_cpu_model_finalize, 1229 .class_init = s390_qemu_cpu_model_class_init, 1230 }; 1231 1232 #ifdef CONFIG_KVM 1233 static const TypeInfo host_s390_cpu_type_info = { 1234 .name = S390_CPU_TYPE_NAME("host"), 1235 .parent = TYPE_S390_CPU, 1236 .instance_init = s390_host_cpu_model_initfn, 1237 .instance_finalize = s390_cpu_model_finalize, 1238 .class_init = s390_host_cpu_model_class_init, 1239 }; 1240 #endif 1241 1242 static void init_ignored_base_feat(void) 1243 { 1244 static const int feats[] = { 1245 /* MSA subfunctions that could not be available on certain machines */ 1246 S390_FEAT_KMAC_DEA, 1247 S390_FEAT_KMAC_TDEA_128, 1248 S390_FEAT_KMAC_TDEA_192, 1249 S390_FEAT_KMC_DEA, 1250 S390_FEAT_KMC_TDEA_128, 1251 S390_FEAT_KMC_TDEA_192, 1252 S390_FEAT_KM_DEA, 1253 S390_FEAT_KM_TDEA_128, 1254 S390_FEAT_KM_TDEA_192, 1255 S390_FEAT_KIMD_SHA_1, 1256 S390_FEAT_KLMD_SHA_1, 1257 }; 1258 int i; 1259 1260 for (i = 0; i < ARRAY_SIZE(feats); i++) { 1261 set_bit(feats[i], ignored_base_feat); 1262 } 1263 } 1264 1265 static void register_types(void) 1266 { 1267 static const S390FeatInit qemu_latest_init = { S390_FEAT_LIST_QEMU_LATEST }; 1268 int i; 1269 1270 init_ignored_base_feat(); 1271 1272 /* init all bitmaps from gnerated data initially */ 1273 s390_init_feat_bitmap(qemu_max_cpu_feat_init, qemu_max_cpu_feat); 1274 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 1275 s390_init_feat_bitmap(s390_cpu_defs[i].base_init, 1276 s390_cpu_defs[i].base_feat); 1277 s390_init_feat_bitmap(s390_cpu_defs[i].default_init, 1278 s390_cpu_defs[i].default_feat); 1279 s390_init_feat_bitmap(s390_cpu_defs[i].full_init, 1280 s390_cpu_defs[i].full_feat); 1281 } 1282 1283 /* initialize the qemu model with latest definition */ 1284 s390_set_qemu_cpu_model(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN, 1285 QEMU_MAX_CPU_EC_GA, qemu_latest_init); 1286 1287 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 1288 char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name); 1289 TypeInfo ti_base = { 1290 .name = base_name, 1291 .parent = TYPE_S390_CPU, 1292 .instance_init = s390_cpu_model_initfn, 1293 .instance_finalize = s390_cpu_model_finalize, 1294 .class_init = s390_base_cpu_model_class_init, 1295 .class_data = (void *) &s390_cpu_defs[i], 1296 }; 1297 char *name = s390_cpu_type_name(s390_cpu_defs[i].name); 1298 TypeInfo ti = { 1299 .name = name, 1300 .parent = TYPE_S390_CPU, 1301 .instance_init = s390_cpu_model_initfn, 1302 .instance_finalize = s390_cpu_model_finalize, 1303 .class_init = s390_cpu_model_class_init, 1304 .class_data = (void *) &s390_cpu_defs[i], 1305 }; 1306 1307 type_register_static(&ti_base); 1308 type_register_static(&ti); 1309 g_free(base_name); 1310 g_free(name); 1311 } 1312 1313 type_register_static(&qemu_s390_cpu_type_info); 1314 #ifdef CONFIG_KVM 1315 type_register_static(&host_s390_cpu_type_info); 1316 #endif 1317 } 1318 1319 type_init(register_types) 1320