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