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 "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 25 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 }, \ 38 } 39 40 /* 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. 45 */ 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 }; 79 80 void s390_cpudef_featoff(uint8_t gen, uint8_t ec_ga, S390Feat feat) 81 { 82 const S390CPUDef *def; 83 84 def = s390_find_cpu_def(0, gen, ec_ga, NULL); 85 clear_bit(feat, (unsigned long *)&def->default_feat); 86 } 87 88 void s390_cpudef_featoff_greater(uint8_t gen, uint8_t ec_ga, S390Feat feat) 89 { 90 int i; 91 92 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 93 const S390CPUDef *def = &s390_cpu_defs[i]; 94 95 if (def->gen < gen) { 96 continue; 97 } 98 if (def->gen == gen && def->ec_ga < ec_ga) { 99 continue; 100 } 101 102 clear_bit(feat, (unsigned long *)&def->default_feat); 103 } 104 } 105 106 uint32_t s390_get_hmfai(void) 107 { 108 static S390CPU *cpu; 109 110 if (!cpu) { 111 cpu = S390_CPU(qemu_get_cpu(0)); 112 } 113 114 if (!cpu || !cpu->model) { 115 return 0; 116 } 117 return cpu->model->def->hmfai; 118 } 119 120 uint8_t s390_get_mha_pow(void) 121 { 122 static S390CPU *cpu; 123 124 if (!cpu) { 125 cpu = S390_CPU(qemu_get_cpu(0)); 126 } 127 128 if (!cpu || !cpu->model) { 129 return 0; 130 } 131 return cpu->model->def->mha_pow; 132 } 133 134 uint32_t s390_get_ibc_val(void) 135 { 136 uint16_t unblocked_ibc, lowest_ibc; 137 static S390CPU *cpu; 138 139 if (!cpu) { 140 cpu = S390_CPU(qemu_get_cpu(0)); 141 } 142 143 if (!cpu || !cpu->model) { 144 return 0; 145 } 146 unblocked_ibc = s390_ibc_from_cpu_model(cpu->model); 147 lowest_ibc = cpu->model->lowest_ibc; 148 /* the lowest_ibc always has to be <= unblocked_ibc */ 149 if (!lowest_ibc || lowest_ibc > unblocked_ibc) { 150 return 0; 151 } 152 return ((uint32_t) lowest_ibc << 16) | unblocked_ibc; 153 } 154 155 void s390_get_feat_block(S390FeatType type, uint8_t *data) 156 { 157 static S390CPU *cpu; 158 159 if (!cpu) { 160 cpu = S390_CPU(qemu_get_cpu(0)); 161 } 162 163 if (!cpu || !cpu->model) { 164 return; 165 } 166 s390_fill_feat_block(cpu->model->features, type, data); 167 } 168 169 bool s390_has_feat(S390Feat feat) 170 { 171 static S390CPU *cpu; 172 173 if (!cpu) { 174 cpu = S390_CPU(qemu_get_cpu(0)); 175 } 176 177 if (!cpu || !cpu->model) { 178 #ifdef CONFIG_KVM 179 if (kvm_enabled()) { 180 if (feat == S390_FEAT_VECTOR) { 181 return kvm_check_extension(kvm_state, 182 KVM_CAP_S390_VECTOR_REGISTERS); 183 } 184 if (feat == S390_FEAT_RUNTIME_INSTRUMENTATION) { 185 return kvm_s390_get_ri(); 186 } 187 if (feat == S390_FEAT_MSA_EXT_3) { 188 return true; 189 } 190 } 191 #endif 192 return 0; 193 } 194 return test_bit(feat, cpu->model->features); 195 } 196 197 uint8_t s390_get_gen_for_cpu_type(uint16_t type) 198 { 199 int i; 200 201 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 202 if (s390_cpu_defs[i].type == type) { 203 return s390_cpu_defs[i].gen; 204 } 205 } 206 return 0; 207 } 208 209 const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga, 210 S390FeatBitmap features) 211 { 212 const S390CPUDef *last_compatible = NULL; 213 const S390CPUDef *matching_cpu_type = NULL; 214 int i; 215 216 if (!gen) { 217 ec_ga = 0; 218 } 219 if (!gen && type) { 220 gen = s390_get_gen_for_cpu_type(type); 221 } 222 223 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 224 const S390CPUDef *def = &s390_cpu_defs[i]; 225 S390FeatBitmap missing; 226 227 /* don't even try newer generations if we know the generation */ 228 if (gen) { 229 if (def->gen > gen) { 230 break; 231 } else if (def->gen == gen && ec_ga && def->ec_ga > ec_ga) { 232 break; 233 } 234 } 235 236 if (features) { 237 /* see if the model satisfies the minimum features */ 238 bitmap_andnot(missing, def->base_feat, features, S390_FEAT_MAX); 239 if (!bitmap_empty(missing, S390_FEAT_MAX)) { 240 break; 241 } 242 } 243 244 /* stop the search if we found the exact model */ 245 if (def->type == type && def->ec_ga == ec_ga) { 246 return def; 247 } 248 /* remember if we've at least seen one with the same cpu type */ 249 if (def->type == type) { 250 matching_cpu_type = def; 251 } 252 last_compatible = def; 253 } 254 /* prefer the model with the same cpu type, esp. don't take the BC for EC */ 255 if (matching_cpu_type) { 256 return matching_cpu_type; 257 } 258 return last_compatible; 259 } 260 261 struct S390PrintCpuListInfo { 262 FILE *f; 263 fprintf_function print; 264 }; 265 266 static void print_cpu_model_list(ObjectClass *klass, void *opaque) 267 { 268 struct S390PrintCpuListInfo *info = opaque; 269 S390CPUClass *scc = S390_CPU_CLASS(klass); 270 char *name = g_strdup(object_class_get_name(klass)); 271 const char *details = ""; 272 273 if (scc->is_static) { 274 details = "(static, migration-safe)"; 275 } else if (scc->is_migration_safe) { 276 details = "(migration-safe)"; 277 } 278 279 /* strip off the -s390-cpu */ 280 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; 281 (*info->print)(info->f, "s390 %-15s %-35s %s\n", name, scc->desc, 282 details); 283 g_free(name); 284 } 285 286 void s390_cpu_list(FILE *f, fprintf_function print) 287 { 288 struct S390PrintCpuListInfo info = { 289 .f = f, 290 .print = print, 291 }; 292 S390FeatGroup group; 293 S390Feat feat; 294 295 object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info); 296 297 (*print)(f, "\nRecognized feature flags:\n"); 298 for (feat = 0; feat < S390_FEAT_MAX; feat++) { 299 const S390FeatDef *def = s390_feat_def(feat); 300 301 (*print)(f, "%-20s %-50s\n", def->name, def->desc); 302 } 303 304 (*print)(f, "\nRecognized feature groups:\n"); 305 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { 306 const S390FeatGroupDef *def = s390_feat_group_def(group); 307 308 (*print)(f, "%-20s %-50s\n", def->name, def->desc); 309 } 310 } 311 312 static S390CPUModel *get_max_cpu_model(Error **errp); 313 314 #ifndef CONFIG_USER_ONLY 315 static void list_add_feat(const char *name, void *opaque); 316 317 static void check_unavailable_features(const S390CPUModel *max_model, 318 const S390CPUModel *model, 319 strList **unavailable) 320 { 321 S390FeatBitmap missing; 322 323 /* check general model compatibility */ 324 if (max_model->def->gen < model->def->gen || 325 (max_model->def->gen == model->def->gen && 326 max_model->def->ec_ga < model->def->ec_ga)) { 327 list_add_feat("type", unavailable); 328 } 329 330 /* detect missing features if any to properly report them */ 331 bitmap_andnot(missing, model->features, max_model->features, 332 S390_FEAT_MAX); 333 if (!bitmap_empty(missing, S390_FEAT_MAX)) { 334 s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat); 335 } 336 } 337 338 struct CpuDefinitionInfoListData { 339 CpuDefinitionInfoList *list; 340 S390CPUModel *model; 341 }; 342 343 static void create_cpu_model_list(ObjectClass *klass, void *opaque) 344 { 345 struct CpuDefinitionInfoListData *cpu_list_data = opaque; 346 CpuDefinitionInfoList **cpu_list = &cpu_list_data->list; 347 CpuDefinitionInfoList *entry; 348 CpuDefinitionInfo *info; 349 char *name = g_strdup(object_class_get_name(klass)); 350 S390CPUClass *scc = S390_CPU_CLASS(klass); 351 352 /* strip off the -s390-cpu */ 353 g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; 354 info = g_malloc0(sizeof(*info)); 355 info->name = name; 356 info->has_migration_safe = true; 357 info->migration_safe = scc->is_migration_safe; 358 info->q_static = scc->is_static; 359 info->q_typename = g_strdup(object_class_get_name(klass)); 360 /* check for unavailable features */ 361 if (cpu_list_data->model) { 362 Object *obj; 363 S390CPU *sc; 364 obj = object_new(object_class_get_name(klass)); 365 sc = S390_CPU(obj); 366 if (sc->model) { 367 info->has_unavailable_features = true; 368 check_unavailable_features(cpu_list_data->model, sc->model, 369 &info->unavailable_features); 370 } 371 object_unref(obj); 372 } 373 374 entry = g_malloc0(sizeof(*entry)); 375 entry->value = info; 376 entry->next = *cpu_list; 377 *cpu_list = entry; 378 } 379 380 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) 381 { 382 struct CpuDefinitionInfoListData list_data = { 383 .list = NULL, 384 }; 385 386 list_data.model = get_max_cpu_model(errp); 387 if (*errp) { 388 error_free(*errp); 389 *errp = NULL; 390 } 391 392 object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, 393 &list_data); 394 395 return list_data.list; 396 } 397 398 static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, 399 Error **errp) 400 { 401 const QDict *qdict = NULL; 402 const QDictEntry *e; 403 Visitor *visitor; 404 ObjectClass *oc; 405 S390CPU *cpu; 406 Object *obj; 407 408 if (info->props) { 409 qdict = qobject_to_qdict(info->props); 410 if (!qdict) { 411 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); 412 return; 413 } 414 } 415 416 oc = cpu_class_by_name(TYPE_S390_CPU, info->name); 417 if (!oc) { 418 error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name); 419 return; 420 } 421 if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) { 422 error_setg(errp, "The CPU definition '%s' requires KVM", info->name); 423 return; 424 } 425 obj = object_new(object_class_get_name(oc)); 426 cpu = S390_CPU(obj); 427 428 if (!cpu->model) { 429 error_setg(errp, "Details about the host CPU model are not available, " 430 "it cannot be used."); 431 object_unref(obj); 432 return; 433 } 434 435 if (qdict) { 436 visitor = qobject_input_visitor_new(info->props); 437 visit_start_struct(visitor, NULL, NULL, 0, errp); 438 if (*errp) { 439 object_unref(obj); 440 return; 441 } 442 for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { 443 object_property_set(obj, visitor, e->key, errp); 444 if (*errp) { 445 break; 446 } 447 } 448 if (!*errp) { 449 visit_check_struct(visitor, errp); 450 } 451 visit_end_struct(visitor, NULL); 452 visit_free(visitor); 453 if (*errp) { 454 object_unref(obj); 455 return; 456 } 457 } 458 459 /* copy the model and throw the cpu away */ 460 memcpy(model, cpu->model, sizeof(*model)); 461 object_unref(obj); 462 } 463 464 static void qdict_add_disabled_feat(const char *name, void *opaque) 465 { 466 qdict_put_bool(opaque, name, false); 467 } 468 469 static void qdict_add_enabled_feat(const char *name, void *opaque) 470 { 471 qdict_put_bool(opaque, name, true); 472 } 473 474 /* convert S390CPUDef into a static CpuModelInfo */ 475 static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model, 476 bool delta_changes) 477 { 478 QDict *qdict = qdict_new(); 479 S390FeatBitmap bitmap; 480 481 /* always fallback to the static base model */ 482 info->name = g_strdup_printf("%s-base", model->def->name); 483 484 if (delta_changes) { 485 /* features deleted from the base feature set */ 486 bitmap_andnot(bitmap, model->def->base_feat, model->features, 487 S390_FEAT_MAX); 488 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { 489 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); 490 } 491 492 /* features added to the base feature set */ 493 bitmap_andnot(bitmap, model->features, model->def->base_feat, 494 S390_FEAT_MAX); 495 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { 496 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat); 497 } 498 } else { 499 /* expand all features */ 500 s390_feat_bitmap_to_ascii(model->features, qdict, 501 qdict_add_enabled_feat); 502 bitmap_complement(bitmap, model->features, S390_FEAT_MAX); 503 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); 504 } 505 506 if (!qdict_size(qdict)) { 507 QDECREF(qdict); 508 } else { 509 info->props = QOBJECT(qdict); 510 info->has_props = true; 511 } 512 } 513 514 CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type, 515 CpuModelInfo *model, 516 Error **errp) 517 { 518 CpuModelExpansionInfo *expansion_info = NULL; 519 S390CPUModel s390_model; 520 bool delta_changes = false; 521 522 /* convert it to our internal representation */ 523 cpu_model_from_info(&s390_model, model, errp); 524 if (*errp) { 525 return NULL; 526 } 527 528 if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) { 529 delta_changes = true; 530 } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) { 531 error_setg(errp, "The requested expansion type is not supported."); 532 return NULL; 533 } 534 535 /* convert it back to a static representation */ 536 expansion_info = g_malloc0(sizeof(*expansion_info)); 537 expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); 538 cpu_info_from_model(expansion_info->model, &s390_model, delta_changes); 539 return expansion_info; 540 } 541 542 static void list_add_feat(const char *name, void *opaque) 543 { 544 strList **last = (strList **) opaque; 545 strList *entry; 546 547 entry = g_malloc0(sizeof(*entry)); 548 entry->value = g_strdup(name); 549 entry->next = *last; 550 *last = entry; 551 } 552 553 CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa, 554 CpuModelInfo *infob, 555 Error **errp) 556 { 557 CpuModelCompareResult feat_result, gen_result; 558 CpuModelCompareInfo *compare_info; 559 S390FeatBitmap missing, added; 560 S390CPUModel modela, modelb; 561 562 /* convert both models to our internal representation */ 563 cpu_model_from_info(&modela, infoa, errp); 564 if (*errp) { 565 return NULL; 566 } 567 cpu_model_from_info(&modelb, infob, errp); 568 if (*errp) { 569 return NULL; 570 } 571 compare_info = g_malloc0(sizeof(*compare_info)); 572 573 /* check the cpu generation and ga level */ 574 if (modela.def->gen == modelb.def->gen) { 575 if (modela.def->ec_ga == modelb.def->ec_ga) { 576 /* ec and corresponding bc are identical */ 577 gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; 578 } else if (modela.def->ec_ga < modelb.def->ec_ga) { 579 gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; 580 } else { 581 gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; 582 } 583 } else if (modela.def->gen < modelb.def->gen) { 584 gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; 585 } else { 586 gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; 587 } 588 if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) { 589 /* both models cannot be made identical */ 590 list_add_feat("type", &compare_info->responsible_properties); 591 } 592 593 /* check the feature set */ 594 if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) { 595 feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; 596 } else { 597 bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX); 598 s390_feat_bitmap_to_ascii(missing, 599 &compare_info->responsible_properties, 600 list_add_feat); 601 bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX); 602 s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties, 603 list_add_feat); 604 if (bitmap_empty(missing, S390_FEAT_MAX)) { 605 feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET; 606 } else if (bitmap_empty(added, S390_FEAT_MAX)) { 607 feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; 608 } else { 609 feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; 610 } 611 } 612 613 /* combine the results */ 614 if (gen_result == feat_result) { 615 compare_info->result = gen_result; 616 } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { 617 compare_info->result = gen_result; 618 } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { 619 compare_info->result = feat_result; 620 } else { 621 compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; 622 } 623 return compare_info; 624 } 625 626 CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *infoa, 627 CpuModelInfo *infob, 628 Error **errp) 629 { 630 CpuModelBaselineInfo *baseline_info; 631 S390CPUModel modela, modelb, model; 632 uint16_t cpu_type; 633 uint8_t max_gen_ga; 634 uint8_t max_gen; 635 636 /* convert both models to our internal representation */ 637 cpu_model_from_info(&modela, infoa, errp); 638 if (*errp) { 639 return NULL; 640 } 641 642 cpu_model_from_info(&modelb, infob, errp); 643 if (*errp) { 644 return NULL; 645 } 646 647 /* features both models support */ 648 bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX); 649 650 /* detect the maximum model not regarding features */ 651 if (modela.def->gen == modelb.def->gen) { 652 if (modela.def->type == modelb.def->type) { 653 cpu_type = modela.def->type; 654 } else { 655 cpu_type = 0; 656 } 657 max_gen = modela.def->gen; 658 max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga); 659 } else if (modela.def->gen > modelb.def->gen) { 660 cpu_type = modelb.def->type; 661 max_gen = modelb.def->gen; 662 max_gen_ga = modelb.def->ec_ga; 663 } else { 664 cpu_type = modela.def->type; 665 max_gen = modela.def->gen; 666 max_gen_ga = modela.def->ec_ga; 667 } 668 669 model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga, 670 model.features); 671 /* strip off features not part of the max model */ 672 bitmap_and(model.features, model.features, model.def->full_feat, 673 S390_FEAT_MAX); 674 675 baseline_info = g_malloc0(sizeof(*baseline_info)); 676 baseline_info->model = g_malloc0(sizeof(*baseline_info->model)); 677 cpu_info_from_model(baseline_info->model, &model, true); 678 return baseline_info; 679 } 680 #endif 681 682 static void check_consistency(const S390CPUModel *model) 683 { 684 static int dep[][2] = { 685 { S390_FEAT_IPTE_RANGE, S390_FEAT_DAT_ENH }, 686 { S390_FEAT_IDTE_SEGMENT, S390_FEAT_DAT_ENH }, 687 { S390_FEAT_IDTE_REGION, S390_FEAT_DAT_ENH }, 688 { S390_FEAT_IDTE_REGION, S390_FEAT_IDTE_SEGMENT }, 689 { S390_FEAT_LOCAL_TLB_CLEARING, S390_FEAT_DAT_ENH}, 690 { S390_FEAT_LONG_DISPLACEMENT_FAST, S390_FEAT_LONG_DISPLACEMENT }, 691 { S390_FEAT_DFP_FAST, S390_FEAT_DFP }, 692 { S390_FEAT_TRANSACTIONAL_EXE, S390_FEAT_STFLE_49 }, 693 { S390_FEAT_EDAT_2, S390_FEAT_EDAT}, 694 { S390_FEAT_MSA_EXT_5, S390_FEAT_KIMD_SHA_512 }, 695 { S390_FEAT_MSA_EXT_5, S390_FEAT_KLMD_SHA_512 }, 696 { S390_FEAT_MSA_EXT_4, S390_FEAT_MSA_EXT_3 }, 697 { S390_FEAT_SIE_CMMA, S390_FEAT_CMM }, 698 { S390_FEAT_SIE_CMMA, S390_FEAT_SIE_GSLS }, 699 { S390_FEAT_SIE_PFMFI, S390_FEAT_EDAT }, 700 { S390_FEAT_MSA_EXT_8, S390_FEAT_MSA_EXT_3 }, 701 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, 702 { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, 703 { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, 704 { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, 705 { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, 706 { S390_FEAT_CMM_NT, S390_FEAT_CMM }, 707 { S390_FEAT_GUARDED_STORAGE, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, 708 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_STORE_CLOCK_FAST }, 709 { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, 710 { S390_FEAT_SEMAPHORE_ASSIST, S390_FEAT_STFLE_49 }, 711 { S390_FEAT_KIMD_SHA3_224, S390_FEAT_MSA }, 712 { S390_FEAT_KIMD_SHA3_256, S390_FEAT_MSA }, 713 { S390_FEAT_KIMD_SHA3_384, S390_FEAT_MSA }, 714 { S390_FEAT_KIMD_SHA3_512, S390_FEAT_MSA }, 715 { S390_FEAT_KIMD_SHAKE_128, S390_FEAT_MSA }, 716 { S390_FEAT_KIMD_SHAKE_256, S390_FEAT_MSA }, 717 { S390_FEAT_KLMD_SHA3_224, S390_FEAT_MSA }, 718 { S390_FEAT_KLMD_SHA3_256, S390_FEAT_MSA }, 719 { S390_FEAT_KLMD_SHA3_384, S390_FEAT_MSA }, 720 { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, 721 { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, 722 { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, 723 { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, 724 { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, 725 }; 726 int i; 727 728 for (i = 0; i < ARRAY_SIZE(dep); i++) { 729 if (test_bit(dep[i][0], model->features) && 730 !test_bit(dep[i][1], model->features)) { 731 warn_report("\'%s\' requires \'%s\'.", 732 s390_feat_def(dep[i][0])->name, 733 s390_feat_def(dep[i][1])->name); 734 } 735 } 736 } 737 738 static void error_prepend_missing_feat(const char *name, void *opaque) 739 { 740 error_prepend((Error **) opaque, "%s ", name); 741 } 742 743 static void check_compatibility(const S390CPUModel *max_model, 744 const S390CPUModel *model, Error **errp) 745 { 746 S390FeatBitmap missing; 747 748 if (model->def->gen > max_model->def->gen) { 749 error_setg(errp, "Selected CPU generation is too new. Maximum " 750 "supported model in the configuration: \'%s\'", 751 max_model->def->name); 752 return; 753 } else if (model->def->gen == max_model->def->gen && 754 model->def->ec_ga > max_model->def->ec_ga) { 755 error_setg(errp, "Selected CPU GA level is too new. Maximum " 756 "supported model in the configuration: \'%s\'", 757 max_model->def->name); 758 return; 759 } 760 761 /* detect the missing features to properly report them */ 762 bitmap_andnot(missing, model->features, max_model->features, S390_FEAT_MAX); 763 if (bitmap_empty(missing, S390_FEAT_MAX)) { 764 return; 765 } 766 767 error_setg(errp, " "); 768 s390_feat_bitmap_to_ascii(missing, errp, error_prepend_missing_feat); 769 error_prepend(errp, "Some features requested in the CPU model are not " 770 "available in the configuration: "); 771 } 772 773 /** 774 * The base TCG CPU model "qemu" is based on the z900. However, we already 775 * can also emulate some additional features of later CPU generations, so 776 * we add these additional feature bits here. 777 */ 778 static void add_qemu_cpu_model_features(S390FeatBitmap fbm) 779 { 780 static const int feats[] = { 781 S390_FEAT_DAT_ENH, 782 S390_FEAT_STFLE, 783 S390_FEAT_EXTENDED_IMMEDIATE, 784 S390_FEAT_EXTENDED_TRANSLATION_2, 785 S390_FEAT_LONG_DISPLACEMENT, 786 S390_FEAT_LONG_DISPLACEMENT_FAST, 787 S390_FEAT_ETF2_ENH, 788 S390_FEAT_STORE_CLOCK_FAST, 789 S390_FEAT_MOVE_WITH_OPTIONAL_SPEC, 790 S390_FEAT_COMPARE_AND_SWAP_AND_STORE, 791 S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2, 792 S390_FEAT_GENERAL_INSTRUCTIONS_EXT, 793 S390_FEAT_EXECUTE_EXT, 794 S390_FEAT_FLOATING_POINT_SUPPPORT_ENH, 795 S390_FEAT_STFLE_45, 796 S390_FEAT_STFLE_49, 797 S390_FEAT_LOCAL_TLB_CLEARING, 798 S390_FEAT_STFLE_53, 799 }; 800 int i; 801 802 for (i = 0; i < ARRAY_SIZE(feats); i++) { 803 set_bit(feats[i], fbm); 804 } 805 } 806 807 static S390CPUModel *get_max_cpu_model(Error **errp) 808 { 809 static S390CPUModel max_model; 810 static bool cached; 811 812 if (cached) { 813 return &max_model; 814 } 815 816 if (kvm_enabled()) { 817 kvm_s390_get_host_cpu_model(&max_model, errp); 818 } else { 819 /* TCG emulates a z900 (with some optional additional features) */ 820 max_model.def = &s390_cpu_defs[0]; 821 bitmap_copy(max_model.features, max_model.def->default_feat, 822 S390_FEAT_MAX); 823 add_qemu_cpu_model_features(max_model.features); 824 } 825 if (!*errp) { 826 cached = true; 827 return &max_model; 828 } 829 return NULL; 830 } 831 832 static inline void apply_cpu_model(const S390CPUModel *model, Error **errp) 833 { 834 #ifndef CONFIG_USER_ONLY 835 static S390CPUModel applied_model; 836 static bool applied; 837 838 /* 839 * We have the same model for all VCPUs. KVM can only be configured before 840 * any VCPUs are defined in KVM. 841 */ 842 if (applied) { 843 if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) { 844 error_setg(errp, "Mixed CPU models are not supported on s390x."); 845 } 846 return; 847 } 848 849 if (kvm_enabled()) { 850 kvm_s390_apply_cpu_model(model, errp); 851 } 852 853 if (!*errp) { 854 applied = true; 855 if (model) { 856 applied_model = *model; 857 } 858 } 859 #endif 860 } 861 862 void s390_realize_cpu_model(CPUState *cs, Error **errp) 863 { 864 S390CPUClass *xcc = S390_CPU_GET_CLASS(cs); 865 S390CPU *cpu = S390_CPU(cs); 866 const S390CPUModel *max_model; 867 868 if (xcc->kvm_required && !kvm_enabled()) { 869 error_setg(errp, "CPU definition requires KVM"); 870 return; 871 } 872 873 if (!cpu->model) { 874 /* no host model support -> perform compatibility stuff */ 875 apply_cpu_model(NULL, errp); 876 return; 877 } 878 879 max_model = get_max_cpu_model(errp); 880 if (*errp) { 881 error_prepend(errp, "CPU models are not available: "); 882 return; 883 } 884 885 /* copy over properties that can vary */ 886 cpu->model->lowest_ibc = max_model->lowest_ibc; 887 cpu->model->cpu_id = max_model->cpu_id; 888 cpu->model->cpu_id_format = max_model->cpu_id_format; 889 cpu->model->cpu_ver = max_model->cpu_ver; 890 891 check_consistency(cpu->model); 892 check_compatibility(max_model, cpu->model, errp); 893 if (*errp) { 894 return; 895 } 896 897 apply_cpu_model(cpu->model, errp); 898 899 cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model); 900 if (tcg_enabled()) { 901 /* basic mode, write the cpu address into the first 4 bit of the ID */ 902 cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.cpu_num); 903 } 904 } 905 906 static void get_feature(Object *obj, Visitor *v, const char *name, 907 void *opaque, Error **errp) 908 { 909 S390Feat feat = (S390Feat) opaque; 910 S390CPU *cpu = S390_CPU(obj); 911 bool value; 912 913 if (!cpu->model) { 914 error_setg(errp, "Details about the host CPU model are not available, " 915 "features cannot be queried."); 916 return; 917 } 918 919 value = test_bit(feat, cpu->model->features); 920 visit_type_bool(v, name, &value, errp); 921 } 922 923 static void set_feature(Object *obj, Visitor *v, const char *name, 924 void *opaque, Error **errp) 925 { 926 S390Feat feat = (S390Feat) opaque; 927 DeviceState *dev = DEVICE(obj); 928 S390CPU *cpu = S390_CPU(obj); 929 bool value; 930 931 if (dev->realized) { 932 error_setg(errp, "Attempt to set property '%s' on '%s' after " 933 "it was realized", name, object_get_typename(obj)); 934 return; 935 } else if (!cpu->model) { 936 error_setg(errp, "Details about the host CPU model are not available, " 937 "features cannot be changed."); 938 return; 939 } 940 941 visit_type_bool(v, name, &value, errp); 942 if (*errp) { 943 return; 944 } 945 if (value) { 946 if (!test_bit(feat, cpu->model->def->full_feat)) { 947 error_setg(errp, "Feature '%s' is not available for CPU model '%s'," 948 " it was introduced with later models.", 949 name, cpu->model->def->name); 950 return; 951 } 952 set_bit(feat, cpu->model->features); 953 } else { 954 clear_bit(feat, cpu->model->features); 955 } 956 } 957 958 static void get_feature_group(Object *obj, Visitor *v, const char *name, 959 void *opaque, Error **errp) 960 { 961 S390FeatGroup group = (S390FeatGroup) opaque; 962 const S390FeatGroupDef *def = s390_feat_group_def(group); 963 S390CPU *cpu = S390_CPU(obj); 964 S390FeatBitmap tmp; 965 bool value; 966 967 if (!cpu->model) { 968 error_setg(errp, "Details about the host CPU model are not available, " 969 "features cannot be queried."); 970 return; 971 } 972 973 /* a group is enabled if all features are enabled */ 974 bitmap_and(tmp, cpu->model->features, def->feat, S390_FEAT_MAX); 975 value = bitmap_equal(tmp, def->feat, S390_FEAT_MAX); 976 visit_type_bool(v, name, &value, errp); 977 } 978 979 static void set_feature_group(Object *obj, Visitor *v, const char *name, 980 void *opaque, Error **errp) 981 { 982 S390FeatGroup group = (S390FeatGroup) opaque; 983 const S390FeatGroupDef *def = s390_feat_group_def(group); 984 DeviceState *dev = DEVICE(obj); 985 S390CPU *cpu = S390_CPU(obj); 986 bool value; 987 988 if (dev->realized) { 989 error_setg(errp, "Attempt to set property '%s' on '%s' after " 990 "it was realized", name, object_get_typename(obj)); 991 return; 992 } else if (!cpu->model) { 993 error_setg(errp, "Details about the host CPU model are not available, " 994 "features cannot be changed."); 995 return; 996 } 997 998 visit_type_bool(v, name, &value, errp); 999 if (*errp) { 1000 return; 1001 } 1002 if (value) { 1003 /* groups are added in one shot, so an intersect is sufficient */ 1004 if (!bitmap_intersects(def->feat, cpu->model->def->full_feat, 1005 S390_FEAT_MAX)) { 1006 error_setg(errp, "Group '%s' is not available for CPU model '%s'," 1007 " it was introduced with later models.", 1008 name, cpu->model->def->name); 1009 return; 1010 } 1011 bitmap_or(cpu->model->features, cpu->model->features, def->feat, 1012 S390_FEAT_MAX); 1013 } else { 1014 bitmap_andnot(cpu->model->features, cpu->model->features, def->feat, 1015 S390_FEAT_MAX); 1016 } 1017 } 1018 1019 void s390_cpu_model_register_props(Object *obj) 1020 { 1021 S390FeatGroup group; 1022 S390Feat feat; 1023 1024 for (feat = 0; feat < S390_FEAT_MAX; feat++) { 1025 const S390FeatDef *def = s390_feat_def(feat); 1026 object_property_add(obj, def->name, "bool", get_feature, 1027 set_feature, NULL, (void *) feat, NULL); 1028 object_property_set_description(obj, def->name, def->desc , NULL); 1029 } 1030 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { 1031 const S390FeatGroupDef *def = s390_feat_group_def(group); 1032 object_property_add(obj, def->name, "bool", get_feature_group, 1033 set_feature_group, NULL, (void *) group, NULL); 1034 object_property_set_description(obj, def->name, def->desc , NULL); 1035 } 1036 } 1037 1038 static void s390_cpu_model_initfn(Object *obj) 1039 { 1040 S390CPU *cpu = S390_CPU(obj); 1041 S390CPUClass *xcc = S390_CPU_GET_CLASS(cpu); 1042 1043 cpu->model = g_malloc0(sizeof(*cpu->model)); 1044 /* copy the model, so we can modify it */ 1045 cpu->model->def = xcc->cpu_def; 1046 if (xcc->is_static) { 1047 /* base model - features will never change */ 1048 bitmap_copy(cpu->model->features, cpu->model->def->base_feat, 1049 S390_FEAT_MAX); 1050 } else { 1051 /* latest model - features can change */ 1052 bitmap_copy(cpu->model->features, 1053 cpu->model->def->default_feat, S390_FEAT_MAX); 1054 } 1055 } 1056 1057 #ifdef CONFIG_KVM 1058 static void s390_host_cpu_model_initfn(Object *obj) 1059 { 1060 S390CPU *cpu = S390_CPU(obj); 1061 Error *err = NULL; 1062 1063 if (!kvm_enabled() || !kvm_s390_cpu_models_supported()) { 1064 return; 1065 } 1066 1067 cpu->model = g_malloc0(sizeof(*cpu->model)); 1068 kvm_s390_get_host_cpu_model(cpu->model, &err); 1069 if (err) { 1070 error_report_err(err); 1071 g_free(cpu->model); 1072 /* fallback to unsupported cpu models */ 1073 cpu->model = NULL; 1074 } 1075 } 1076 #endif 1077 1078 static void s390_qemu_cpu_model_initfn(Object *obj) 1079 { 1080 static S390CPUDef s390_qemu_cpu_defs; 1081 S390CPU *cpu = S390_CPU(obj); 1082 1083 cpu->model = g_malloc0(sizeof(*cpu->model)); 1084 /* TCG emulates a z900 (with some optional additional features) */ 1085 memcpy(&s390_qemu_cpu_defs, &s390_cpu_defs[0], sizeof(s390_qemu_cpu_defs)); 1086 add_qemu_cpu_model_features(s390_qemu_cpu_defs.full_feat); 1087 cpu->model->def = &s390_qemu_cpu_defs; 1088 bitmap_copy(cpu->model->features, cpu->model->def->default_feat, 1089 S390_FEAT_MAX); 1090 } 1091 1092 static void s390_cpu_model_finalize(Object *obj) 1093 { 1094 S390CPU *cpu = S390_CPU(obj); 1095 1096 g_free(cpu->model); 1097 cpu->model = NULL; 1098 } 1099 1100 static bool get_is_migration_safe(Object *obj, Error **errp) 1101 { 1102 return S390_CPU_GET_CLASS(obj)->is_migration_safe; 1103 } 1104 1105 static bool get_is_static(Object *obj, Error **errp) 1106 { 1107 return S390_CPU_GET_CLASS(obj)->is_static; 1108 } 1109 1110 static char *get_description(Object *obj, Error **errp) 1111 { 1112 return g_strdup(S390_CPU_GET_CLASS(obj)->desc); 1113 } 1114 1115 void s390_cpu_model_class_register_props(ObjectClass *oc) 1116 { 1117 object_class_property_add_bool(oc, "migration-safe", get_is_migration_safe, 1118 NULL, NULL); 1119 object_class_property_add_bool(oc, "static", get_is_static, 1120 NULL, NULL); 1121 object_class_property_add_str(oc, "description", get_description, NULL, 1122 NULL); 1123 } 1124 1125 #ifdef CONFIG_KVM 1126 static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) 1127 { 1128 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1129 1130 xcc->kvm_required = true; 1131 xcc->desc = "KVM only: All recognized features"; 1132 } 1133 #endif 1134 1135 static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data) 1136 { 1137 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1138 1139 /* all base models are migration safe */ 1140 xcc->cpu_def = (const S390CPUDef *) data; 1141 xcc->is_migration_safe = true; 1142 xcc->is_static = true; 1143 xcc->desc = xcc->cpu_def->desc; 1144 } 1145 1146 static void s390_cpu_model_class_init(ObjectClass *oc, void *data) 1147 { 1148 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1149 1150 /* model that can change between QEMU versions */ 1151 xcc->cpu_def = (const S390CPUDef *) data; 1152 xcc->is_migration_safe = true; 1153 xcc->desc = xcc->cpu_def->desc; 1154 } 1155 1156 static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data) 1157 { 1158 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1159 1160 xcc->is_migration_safe = true; 1161 xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s", 1162 qemu_hw_version()); 1163 } 1164 1165 #define S390_CPU_TYPE_SUFFIX "-" TYPE_S390_CPU 1166 #define S390_CPU_TYPE_NAME(name) (name S390_CPU_TYPE_SUFFIX) 1167 1168 /* Generate type name for a cpu model. Caller has to free the string. */ 1169 static char *s390_cpu_type_name(const char *model_name) 1170 { 1171 return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name); 1172 } 1173 1174 /* Generate type name for a base cpu model. Caller has to free the string. */ 1175 static char *s390_base_cpu_type_name(const char *model_name) 1176 { 1177 return g_strdup_printf(S390_CPU_TYPE_NAME("%s-base"), model_name); 1178 } 1179 1180 ObjectClass *s390_cpu_class_by_name(const char *name) 1181 { 1182 char *typename = s390_cpu_type_name(name); 1183 ObjectClass *oc; 1184 1185 oc = object_class_by_name(typename); 1186 g_free(typename); 1187 return oc; 1188 } 1189 1190 static const TypeInfo qemu_s390_cpu_type_info = { 1191 .name = S390_CPU_TYPE_NAME("qemu"), 1192 .parent = TYPE_S390_CPU, 1193 .instance_init = s390_qemu_cpu_model_initfn, 1194 .instance_finalize = s390_cpu_model_finalize, 1195 .class_init = s390_qemu_cpu_model_class_init, 1196 }; 1197 1198 #ifdef CONFIG_KVM 1199 static const TypeInfo host_s390_cpu_type_info = { 1200 .name = S390_CPU_TYPE_NAME("host"), 1201 .parent = TYPE_S390_CPU, 1202 .instance_init = s390_host_cpu_model_initfn, 1203 .instance_finalize = s390_cpu_model_finalize, 1204 .class_init = s390_host_cpu_model_class_init, 1205 }; 1206 #endif 1207 1208 static void register_types(void) 1209 { 1210 int i; 1211 1212 /* init all bitmaps from gnerated data initially */ 1213 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 1214 s390_init_feat_bitmap(s390_cpu_defs[i].base_init, 1215 s390_cpu_defs[i].base_feat); 1216 s390_init_feat_bitmap(s390_cpu_defs[i].default_init, 1217 s390_cpu_defs[i].default_feat); 1218 s390_init_feat_bitmap(s390_cpu_defs[i].full_init, 1219 s390_cpu_defs[i].full_feat); 1220 } 1221 1222 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 1223 char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name); 1224 TypeInfo ti_base = { 1225 .name = base_name, 1226 .parent = TYPE_S390_CPU, 1227 .instance_init = s390_cpu_model_initfn, 1228 .instance_finalize = s390_cpu_model_finalize, 1229 .class_init = s390_base_cpu_model_class_init, 1230 .class_data = (void *) &s390_cpu_defs[i], 1231 }; 1232 char *name = s390_cpu_type_name(s390_cpu_defs[i].name); 1233 TypeInfo ti = { 1234 .name = name, 1235 .parent = TYPE_S390_CPU, 1236 .instance_init = s390_cpu_model_initfn, 1237 .instance_finalize = s390_cpu_model_finalize, 1238 .class_init = s390_cpu_model_class_init, 1239 .class_data = (void *) &s390_cpu_defs[i], 1240 }; 1241 1242 type_register_static(&ti_base); 1243 type_register_static(&ti); 1244 g_free(base_name); 1245 g_free(name); 1246 } 1247 1248 type_register_static(&qemu_s390_cpu_type_info); 1249 #ifdef CONFIG_KVM 1250 type_register_static(&host_s390_cpu_type_info); 1251 #endif 1252 } 1253 1254 type_init(register_types) 1255