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_GENERAL_INSTRUCTIONS_EXT, 791 S390_FEAT_EXECUTE_EXT, 792 S390_FEAT_FLOATING_POINT_SUPPPORT_ENH, 793 S390_FEAT_STFLE_45, 794 S390_FEAT_STFLE_49, 795 S390_FEAT_LOCAL_TLB_CLEARING, 796 S390_FEAT_STFLE_53, 797 }; 798 int i; 799 800 for (i = 0; i < ARRAY_SIZE(feats); i++) { 801 set_bit(feats[i], fbm); 802 } 803 } 804 805 static S390CPUModel *get_max_cpu_model(Error **errp) 806 { 807 static S390CPUModel max_model; 808 static bool cached; 809 810 if (cached) { 811 return &max_model; 812 } 813 814 if (kvm_enabled()) { 815 kvm_s390_get_host_cpu_model(&max_model, errp); 816 } else { 817 /* TCG emulates a z900 (with some optional additional features) */ 818 max_model.def = &s390_cpu_defs[0]; 819 bitmap_copy(max_model.features, max_model.def->default_feat, 820 S390_FEAT_MAX); 821 add_qemu_cpu_model_features(max_model.features); 822 } 823 if (!*errp) { 824 cached = true; 825 return &max_model; 826 } 827 return NULL; 828 } 829 830 static inline void apply_cpu_model(const S390CPUModel *model, Error **errp) 831 { 832 #ifndef CONFIG_USER_ONLY 833 static S390CPUModel applied_model; 834 static bool applied; 835 836 /* 837 * We have the same model for all VCPUs. KVM can only be configured before 838 * any VCPUs are defined in KVM. 839 */ 840 if (applied) { 841 if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) { 842 error_setg(errp, "Mixed CPU models are not supported on s390x."); 843 } 844 return; 845 } 846 847 if (kvm_enabled()) { 848 kvm_s390_apply_cpu_model(model, errp); 849 } 850 851 if (!*errp) { 852 applied = true; 853 if (model) { 854 applied_model = *model; 855 } 856 } 857 #endif 858 } 859 860 void s390_realize_cpu_model(CPUState *cs, Error **errp) 861 { 862 S390CPUClass *xcc = S390_CPU_GET_CLASS(cs); 863 S390CPU *cpu = S390_CPU(cs); 864 const S390CPUModel *max_model; 865 866 if (xcc->kvm_required && !kvm_enabled()) { 867 error_setg(errp, "CPU definition requires KVM"); 868 return; 869 } 870 871 if (!cpu->model) { 872 /* no host model support -> perform compatibility stuff */ 873 apply_cpu_model(NULL, errp); 874 return; 875 } 876 877 max_model = get_max_cpu_model(errp); 878 if (*errp) { 879 error_prepend(errp, "CPU models are not available: "); 880 return; 881 } 882 883 /* copy over properties that can vary */ 884 cpu->model->lowest_ibc = max_model->lowest_ibc; 885 cpu->model->cpu_id = max_model->cpu_id; 886 cpu->model->cpu_id_format = max_model->cpu_id_format; 887 cpu->model->cpu_ver = max_model->cpu_ver; 888 889 check_consistency(cpu->model); 890 check_compatibility(max_model, cpu->model, errp); 891 if (*errp) { 892 return; 893 } 894 895 apply_cpu_model(cpu->model, errp); 896 897 cpu->env.cpuid = s390_cpuid_from_cpu_model(cpu->model); 898 if (tcg_enabled()) { 899 /* basic mode, write the cpu address into the first 4 bit of the ID */ 900 cpu->env.cpuid = deposit64(cpu->env.cpuid, 54, 4, cpu->env.cpu_num); 901 } 902 } 903 904 static void get_feature(Object *obj, Visitor *v, const char *name, 905 void *opaque, Error **errp) 906 { 907 S390Feat feat = (S390Feat) opaque; 908 S390CPU *cpu = S390_CPU(obj); 909 bool value; 910 911 if (!cpu->model) { 912 error_setg(errp, "Details about the host CPU model are not available, " 913 "features cannot be queried."); 914 return; 915 } 916 917 value = test_bit(feat, cpu->model->features); 918 visit_type_bool(v, name, &value, errp); 919 } 920 921 static void set_feature(Object *obj, Visitor *v, const char *name, 922 void *opaque, Error **errp) 923 { 924 S390Feat feat = (S390Feat) opaque; 925 DeviceState *dev = DEVICE(obj); 926 S390CPU *cpu = S390_CPU(obj); 927 bool value; 928 929 if (dev->realized) { 930 error_setg(errp, "Attempt to set property '%s' on '%s' after " 931 "it was realized", name, object_get_typename(obj)); 932 return; 933 } else if (!cpu->model) { 934 error_setg(errp, "Details about the host CPU model are not available, " 935 "features cannot be changed."); 936 return; 937 } 938 939 visit_type_bool(v, name, &value, errp); 940 if (*errp) { 941 return; 942 } 943 if (value) { 944 if (!test_bit(feat, cpu->model->def->full_feat)) { 945 error_setg(errp, "Feature '%s' is not available for CPU model '%s'," 946 " it was introduced with later models.", 947 name, cpu->model->def->name); 948 return; 949 } 950 set_bit(feat, cpu->model->features); 951 } else { 952 clear_bit(feat, cpu->model->features); 953 } 954 } 955 956 static void get_feature_group(Object *obj, Visitor *v, const char *name, 957 void *opaque, Error **errp) 958 { 959 S390FeatGroup group = (S390FeatGroup) opaque; 960 const S390FeatGroupDef *def = s390_feat_group_def(group); 961 S390CPU *cpu = S390_CPU(obj); 962 S390FeatBitmap tmp; 963 bool value; 964 965 if (!cpu->model) { 966 error_setg(errp, "Details about the host CPU model are not available, " 967 "features cannot be queried."); 968 return; 969 } 970 971 /* a group is enabled if all features are enabled */ 972 bitmap_and(tmp, cpu->model->features, def->feat, S390_FEAT_MAX); 973 value = bitmap_equal(tmp, def->feat, S390_FEAT_MAX); 974 visit_type_bool(v, name, &value, errp); 975 } 976 977 static void set_feature_group(Object *obj, Visitor *v, const char *name, 978 void *opaque, Error **errp) 979 { 980 S390FeatGroup group = (S390FeatGroup) opaque; 981 const S390FeatGroupDef *def = s390_feat_group_def(group); 982 DeviceState *dev = DEVICE(obj); 983 S390CPU *cpu = S390_CPU(obj); 984 bool value; 985 986 if (dev->realized) { 987 error_setg(errp, "Attempt to set property '%s' on '%s' after " 988 "it was realized", name, object_get_typename(obj)); 989 return; 990 } else if (!cpu->model) { 991 error_setg(errp, "Details about the host CPU model are not available, " 992 "features cannot be changed."); 993 return; 994 } 995 996 visit_type_bool(v, name, &value, errp); 997 if (*errp) { 998 return; 999 } 1000 if (value) { 1001 /* groups are added in one shot, so an intersect is sufficient */ 1002 if (!bitmap_intersects(def->feat, cpu->model->def->full_feat, 1003 S390_FEAT_MAX)) { 1004 error_setg(errp, "Group '%s' is not available for CPU model '%s'," 1005 " it was introduced with later models.", 1006 name, cpu->model->def->name); 1007 return; 1008 } 1009 bitmap_or(cpu->model->features, cpu->model->features, def->feat, 1010 S390_FEAT_MAX); 1011 } else { 1012 bitmap_andnot(cpu->model->features, cpu->model->features, def->feat, 1013 S390_FEAT_MAX); 1014 } 1015 } 1016 1017 void s390_cpu_model_register_props(Object *obj) 1018 { 1019 S390FeatGroup group; 1020 S390Feat feat; 1021 1022 for (feat = 0; feat < S390_FEAT_MAX; feat++) { 1023 const S390FeatDef *def = s390_feat_def(feat); 1024 object_property_add(obj, def->name, "bool", get_feature, 1025 set_feature, NULL, (void *) feat, NULL); 1026 object_property_set_description(obj, def->name, def->desc , NULL); 1027 } 1028 for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { 1029 const S390FeatGroupDef *def = s390_feat_group_def(group); 1030 object_property_add(obj, def->name, "bool", get_feature_group, 1031 set_feature_group, NULL, (void *) group, NULL); 1032 object_property_set_description(obj, def->name, def->desc , NULL); 1033 } 1034 } 1035 1036 static void s390_cpu_model_initfn(Object *obj) 1037 { 1038 S390CPU *cpu = S390_CPU(obj); 1039 S390CPUClass *xcc = S390_CPU_GET_CLASS(cpu); 1040 1041 cpu->model = g_malloc0(sizeof(*cpu->model)); 1042 /* copy the model, so we can modify it */ 1043 cpu->model->def = xcc->cpu_def; 1044 if (xcc->is_static) { 1045 /* base model - features will never change */ 1046 bitmap_copy(cpu->model->features, cpu->model->def->base_feat, 1047 S390_FEAT_MAX); 1048 } else { 1049 /* latest model - features can change */ 1050 bitmap_copy(cpu->model->features, 1051 cpu->model->def->default_feat, S390_FEAT_MAX); 1052 } 1053 } 1054 1055 #ifdef CONFIG_KVM 1056 static void s390_host_cpu_model_initfn(Object *obj) 1057 { 1058 S390CPU *cpu = S390_CPU(obj); 1059 Error *err = NULL; 1060 1061 if (!kvm_enabled() || !kvm_s390_cpu_models_supported()) { 1062 return; 1063 } 1064 1065 cpu->model = g_malloc0(sizeof(*cpu->model)); 1066 kvm_s390_get_host_cpu_model(cpu->model, &err); 1067 if (err) { 1068 error_report_err(err); 1069 g_free(cpu->model); 1070 /* fallback to unsupported cpu models */ 1071 cpu->model = NULL; 1072 } 1073 } 1074 #endif 1075 1076 static void s390_qemu_cpu_model_initfn(Object *obj) 1077 { 1078 static S390CPUDef s390_qemu_cpu_defs; 1079 S390CPU *cpu = S390_CPU(obj); 1080 1081 cpu->model = g_malloc0(sizeof(*cpu->model)); 1082 /* TCG emulates a z900 (with some optional additional features) */ 1083 memcpy(&s390_qemu_cpu_defs, &s390_cpu_defs[0], sizeof(s390_qemu_cpu_defs)); 1084 add_qemu_cpu_model_features(s390_qemu_cpu_defs.full_feat); 1085 cpu->model->def = &s390_qemu_cpu_defs; 1086 bitmap_copy(cpu->model->features, cpu->model->def->default_feat, 1087 S390_FEAT_MAX); 1088 } 1089 1090 static void s390_cpu_model_finalize(Object *obj) 1091 { 1092 S390CPU *cpu = S390_CPU(obj); 1093 1094 g_free(cpu->model); 1095 cpu->model = NULL; 1096 } 1097 1098 static bool get_is_migration_safe(Object *obj, Error **errp) 1099 { 1100 return S390_CPU_GET_CLASS(obj)->is_migration_safe; 1101 } 1102 1103 static bool get_is_static(Object *obj, Error **errp) 1104 { 1105 return S390_CPU_GET_CLASS(obj)->is_static; 1106 } 1107 1108 static char *get_description(Object *obj, Error **errp) 1109 { 1110 return g_strdup(S390_CPU_GET_CLASS(obj)->desc); 1111 } 1112 1113 void s390_cpu_model_class_register_props(ObjectClass *oc) 1114 { 1115 object_class_property_add_bool(oc, "migration-safe", get_is_migration_safe, 1116 NULL, NULL); 1117 object_class_property_add_bool(oc, "static", get_is_static, 1118 NULL, NULL); 1119 object_class_property_add_str(oc, "description", get_description, NULL, 1120 NULL); 1121 } 1122 1123 #ifdef CONFIG_KVM 1124 static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) 1125 { 1126 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1127 1128 xcc->kvm_required = true; 1129 xcc->desc = "KVM only: All recognized features"; 1130 } 1131 #endif 1132 1133 static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data) 1134 { 1135 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1136 1137 /* all base models are migration safe */ 1138 xcc->cpu_def = (const S390CPUDef *) data; 1139 xcc->is_migration_safe = true; 1140 xcc->is_static = true; 1141 xcc->desc = xcc->cpu_def->desc; 1142 } 1143 1144 static void s390_cpu_model_class_init(ObjectClass *oc, void *data) 1145 { 1146 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1147 1148 /* model that can change between QEMU versions */ 1149 xcc->cpu_def = (const S390CPUDef *) data; 1150 xcc->is_migration_safe = true; 1151 xcc->desc = xcc->cpu_def->desc; 1152 } 1153 1154 static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data) 1155 { 1156 S390CPUClass *xcc = S390_CPU_CLASS(oc); 1157 1158 xcc->is_migration_safe = true; 1159 xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s", 1160 qemu_hw_version()); 1161 } 1162 1163 #define S390_CPU_TYPE_SUFFIX "-" TYPE_S390_CPU 1164 #define S390_CPU_TYPE_NAME(name) (name S390_CPU_TYPE_SUFFIX) 1165 1166 /* Generate type name for a cpu model. Caller has to free the string. */ 1167 static char *s390_cpu_type_name(const char *model_name) 1168 { 1169 return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name); 1170 } 1171 1172 /* Generate type name for a base cpu model. Caller has to free the string. */ 1173 static char *s390_base_cpu_type_name(const char *model_name) 1174 { 1175 return g_strdup_printf(S390_CPU_TYPE_NAME("%s-base"), model_name); 1176 } 1177 1178 ObjectClass *s390_cpu_class_by_name(const char *name) 1179 { 1180 char *typename = s390_cpu_type_name(name); 1181 ObjectClass *oc; 1182 1183 oc = object_class_by_name(typename); 1184 g_free(typename); 1185 return oc; 1186 } 1187 1188 static const TypeInfo qemu_s390_cpu_type_info = { 1189 .name = S390_CPU_TYPE_NAME("qemu"), 1190 .parent = TYPE_S390_CPU, 1191 .instance_init = s390_qemu_cpu_model_initfn, 1192 .instance_finalize = s390_cpu_model_finalize, 1193 .class_init = s390_qemu_cpu_model_class_init, 1194 }; 1195 1196 #ifdef CONFIG_KVM 1197 static const TypeInfo host_s390_cpu_type_info = { 1198 .name = S390_CPU_TYPE_NAME("host"), 1199 .parent = TYPE_S390_CPU, 1200 .instance_init = s390_host_cpu_model_initfn, 1201 .instance_finalize = s390_cpu_model_finalize, 1202 .class_init = s390_host_cpu_model_class_init, 1203 }; 1204 #endif 1205 1206 static void register_types(void) 1207 { 1208 int i; 1209 1210 /* init all bitmaps from gnerated data initially */ 1211 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 1212 s390_init_feat_bitmap(s390_cpu_defs[i].base_init, 1213 s390_cpu_defs[i].base_feat); 1214 s390_init_feat_bitmap(s390_cpu_defs[i].default_init, 1215 s390_cpu_defs[i].default_feat); 1216 s390_init_feat_bitmap(s390_cpu_defs[i].full_init, 1217 s390_cpu_defs[i].full_feat); 1218 } 1219 1220 for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { 1221 char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name); 1222 TypeInfo ti_base = { 1223 .name = base_name, 1224 .parent = TYPE_S390_CPU, 1225 .instance_init = s390_cpu_model_initfn, 1226 .instance_finalize = s390_cpu_model_finalize, 1227 .class_init = s390_base_cpu_model_class_init, 1228 .class_data = (void *) &s390_cpu_defs[i], 1229 }; 1230 char *name = s390_cpu_type_name(s390_cpu_defs[i].name); 1231 TypeInfo ti = { 1232 .name = name, 1233 .parent = TYPE_S390_CPU, 1234 .instance_init = s390_cpu_model_initfn, 1235 .instance_finalize = s390_cpu_model_finalize, 1236 .class_init = s390_cpu_model_class_init, 1237 .class_data = (void *) &s390_cpu_defs[i], 1238 }; 1239 1240 type_register_static(&ti_base); 1241 type_register_static(&ti); 1242 g_free(base_name); 1243 g_free(name); 1244 } 1245 1246 type_register_static(&qemu_s390_cpu_type_info); 1247 #ifdef CONFIG_KVM 1248 type_register_static(&host_s390_cpu_type_info); 1249 #endif 1250 } 1251 1252 type_init(register_types) 1253