1 /* 2 * sPAPR CPU core device, acts as container of CPU thread devices. 3 * 4 * Copyright (C) 2016 Bharata B Rao <bharata@linux.vnet.ibm.com> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 */ 9 #include "hw/cpu/core.h" 10 #include "hw/ppc/spapr_cpu_core.h" 11 #include "target-ppc/cpu.h" 12 #include "hw/ppc/spapr.h" 13 #include "hw/boards.h" 14 #include "qapi/error.h" 15 #include "sysemu/cpus.h" 16 #include "target-ppc/kvm_ppc.h" 17 #include "hw/ppc/ppc.h" 18 #include "target-ppc/mmu-hash64.h" 19 #include "sysemu/numa.h" 20 21 static void spapr_cpu_reset(void *opaque) 22 { 23 sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); 24 PowerPCCPU *cpu = opaque; 25 CPUState *cs = CPU(cpu); 26 CPUPPCState *env = &cpu->env; 27 28 cpu_reset(cs); 29 30 /* All CPUs start halted. CPU0 is unhalted from the machine level 31 * reset code and the rest are explicitly started up by the guest 32 * using an RTAS call */ 33 cs->halted = 1; 34 35 env->spr[SPR_HIOR] = 0; 36 37 ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift, 38 &error_fatal); 39 } 40 41 static void spapr_cpu_destroy(PowerPCCPU *cpu) 42 { 43 sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); 44 45 xics_cpu_destroy(spapr->xics, cpu); 46 qemu_unregister_reset(spapr_cpu_reset, cpu); 47 } 48 49 void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp) 50 { 51 CPUPPCState *env = &cpu->env; 52 CPUState *cs = CPU(cpu); 53 int i; 54 55 /* Set time-base frequency to 512 MHz */ 56 cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); 57 58 /* Enable PAPR mode in TCG or KVM */ 59 cpu_ppc_set_papr(cpu); 60 61 if (cpu->max_compat) { 62 Error *local_err = NULL; 63 64 ppc_set_compat(cpu, cpu->max_compat, &local_err); 65 if (local_err) { 66 error_propagate(errp, local_err); 67 return; 68 } 69 } 70 71 /* Set NUMA node for the added CPUs */ 72 for (i = 0; i < nb_numa_nodes; i++) { 73 if (test_bit(cs->cpu_index, numa_info[i].node_cpu)) { 74 cs->numa_node = i; 75 break; 76 } 77 } 78 79 xics_cpu_setup(spapr->xics, cpu); 80 81 qemu_register_reset(spapr_cpu_reset, cpu); 82 spapr_cpu_reset(cpu); 83 } 84 85 /* 86 * Return the sPAPR CPU core type for @model which essentially is the CPU 87 * model specified with -cpu cmdline option. 88 */ 89 char *spapr_get_cpu_core_type(const char *model) 90 { 91 char *core_type; 92 gchar **model_pieces = g_strsplit(model, ",", 2); 93 94 core_type = g_strdup_printf("%s-%s", model_pieces[0], TYPE_SPAPR_CPU_CORE); 95 g_strfreev(model_pieces); 96 return core_type; 97 } 98 99 static void spapr_core_release(DeviceState *dev, void *opaque) 100 { 101 sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); 102 const char *typename = object_class_get_name(sc->cpu_class); 103 size_t size = object_type_get_instance_size(typename); 104 sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); 105 CPUCore *cc = CPU_CORE(dev); 106 int smt = kvmppc_smt_threads(); 107 int i; 108 109 for (i = 0; i < cc->nr_threads; i++) { 110 void *obj = sc->threads + i * size; 111 DeviceState *dev = DEVICE(obj); 112 CPUState *cs = CPU(dev); 113 PowerPCCPU *cpu = POWERPC_CPU(cs); 114 115 spapr_cpu_destroy(cpu); 116 cpu_remove_sync(cs); 117 object_unparent(obj); 118 } 119 120 spapr->cores[cc->core_id / smt] = NULL; 121 122 g_free(sc->threads); 123 object_unparent(OBJECT(dev)); 124 } 125 126 void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, 127 Error **errp) 128 { 129 sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); 130 CPUCore *cc = CPU_CORE(dev); 131 sPAPRDRConnector *drc = 132 spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id); 133 sPAPRDRConnectorClass *drck; 134 Error *local_err = NULL; 135 int smt = kvmppc_smt_threads(); 136 int index = cc->core_id / smt; 137 int spapr_max_cores = max_cpus / smp_threads; 138 int i; 139 140 for (i = spapr_max_cores - 1; i > index; i--) { 141 if (spapr->cores[i]) { 142 error_setg(errp, "core-id %d should be removed first", i * smt); 143 return; 144 } 145 } 146 g_assert(drc); 147 148 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 149 drck->detach(drc, dev, spapr_core_release, NULL, &local_err); 150 if (local_err) { 151 error_propagate(errp, local_err); 152 return; 153 } 154 155 spapr_hotplug_req_remove_by_index(drc); 156 } 157 158 void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, 159 Error **errp) 160 { 161 sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(OBJECT(hotplug_dev)); 162 sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); 163 sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev)); 164 CPUCore *cc = CPU_CORE(dev); 165 CPUState *cs = CPU(core->threads); 166 sPAPRDRConnector *drc; 167 sPAPRDRConnectorClass *drck; 168 Error *local_err = NULL; 169 void *fdt = NULL; 170 int fdt_offset = 0; 171 int index; 172 int smt = kvmppc_smt_threads(); 173 174 drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cc->core_id); 175 index = cc->core_id / smt; 176 spapr->cores[index] = OBJECT(dev); 177 178 if (!smc->dr_cpu_enabled) { 179 /* 180 * This is a cold plugged CPU core but the machine doesn't support 181 * DR. So skip the hotplug path ensuring that the core is brought 182 * up online with out an associated DR connector. 183 */ 184 return; 185 } 186 187 g_assert(drc); 188 189 /* 190 * Setup CPU DT entries only for hotplugged CPUs. For boot time or 191 * coldplugged CPUs DT entries are setup in spapr_finalize_fdt(). 192 */ 193 if (dev->hotplugged) { 194 fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr); 195 } 196 197 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); 198 drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, &local_err); 199 if (local_err) { 200 g_free(fdt); 201 spapr->cores[index] = NULL; 202 error_propagate(errp, local_err); 203 return; 204 } 205 206 if (dev->hotplugged) { 207 /* 208 * Send hotplug notification interrupt to the guest only in case 209 * of hotplugged CPUs. 210 */ 211 spapr_hotplug_req_add_by_index(drc); 212 } else { 213 /* 214 * Set the right DRC states for cold plugged CPU. 215 */ 216 drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_USABLE); 217 drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_UNISOLATED); 218 } 219 } 220 221 void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, 222 Error **errp) 223 { 224 MachineState *machine = MACHINE(OBJECT(hotplug_dev)); 225 sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(OBJECT(hotplug_dev)); 226 sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); 227 int spapr_max_cores = max_cpus / smp_threads; 228 int index, i; 229 int smt = kvmppc_smt_threads(); 230 Error *local_err = NULL; 231 CPUCore *cc = CPU_CORE(dev); 232 char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model); 233 const char *type = object_get_typename(OBJECT(dev)); 234 235 if (strcmp(base_core_type, type)) { 236 error_setg(&local_err, "CPU core type should be %s", base_core_type); 237 goto out; 238 } 239 240 if (!smc->dr_cpu_enabled && dev->hotplugged) { 241 error_setg(&local_err, "CPU hotplug not supported for this machine"); 242 goto out; 243 } 244 245 if (cc->nr_threads != smp_threads) { 246 error_setg(&local_err, "threads must be %d", smp_threads); 247 goto out; 248 } 249 250 if (cc->core_id % smt) { 251 error_setg(&local_err, "invalid core id %d\n", cc->core_id); 252 goto out; 253 } 254 255 index = cc->core_id / smt; 256 if (index < 0 || index >= spapr_max_cores) { 257 error_setg(&local_err, "core id %d out of range", cc->core_id); 258 goto out; 259 } 260 261 if (spapr->cores[index]) { 262 error_setg(&local_err, "core %d already populated", cc->core_id); 263 goto out; 264 } 265 266 for (i = 0; i < index; i++) { 267 if (!spapr->cores[i]) { 268 error_setg(&local_err, "core-id %d should be added first", 269 i * smt); 270 goto out; 271 } 272 } 273 274 out: 275 g_free(base_core_type); 276 error_propagate(errp, local_err); 277 } 278 279 static void spapr_cpu_core_realize_child(Object *child, Error **errp) 280 { 281 Error *local_err = NULL; 282 sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); 283 CPUState *cs = CPU(child); 284 PowerPCCPU *cpu = POWERPC_CPU(cs); 285 286 object_property_set_bool(child, true, "realized", &local_err); 287 if (local_err) { 288 error_propagate(errp, local_err); 289 return; 290 } 291 292 spapr_cpu_init(spapr, cpu, &local_err); 293 if (local_err) { 294 error_propagate(errp, local_err); 295 return; 296 } 297 } 298 299 static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) 300 { 301 sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); 302 CPUCore *cc = CPU_CORE(OBJECT(dev)); 303 const char *typename = object_class_get_name(sc->cpu_class); 304 size_t size = object_type_get_instance_size(typename); 305 Error *local_err = NULL; 306 void *obj; 307 int i, j; 308 309 sc->threads = g_malloc0(size * cc->nr_threads); 310 for (i = 0; i < cc->nr_threads; i++) { 311 char id[32]; 312 obj = sc->threads + i * size; 313 314 object_initialize(obj, size, typename); 315 snprintf(id, sizeof(id), "thread[%d]", i); 316 object_property_add_child(OBJECT(sc), id, obj, &local_err); 317 if (local_err) { 318 goto err; 319 } 320 object_unref(obj); 321 } 322 323 for (j = 0; j < cc->nr_threads; j++) { 324 obj = sc->threads + j * size; 325 326 spapr_cpu_core_realize_child(obj, &local_err); 327 if (local_err) { 328 goto err; 329 } 330 } 331 return; 332 333 err: 334 while (--i >= 0) { 335 obj = sc->threads + i * size; 336 object_unparent(obj); 337 } 338 g_free(sc->threads); 339 error_propagate(errp, local_err); 340 } 341 342 static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) 343 { 344 DeviceClass *dc = DEVICE_CLASS(oc); 345 dc->realize = spapr_cpu_core_realize; 346 } 347 348 /* 349 * instance_init routines from different flavours of sPAPR CPU cores. 350 */ 351 #define SPAPR_CPU_CORE_INITFN(_type, _fname) \ 352 static void glue(glue(spapr_cpu_core_, _fname), _initfn(Object *obj)) \ 353 { \ 354 sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); \ 355 char *name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, stringify(_type)); \ 356 ObjectClass *oc = object_class_by_name(name); \ 357 g_assert(oc); \ 358 g_free((void *)name); \ 359 core->cpu_class = oc; \ 360 } 361 362 SPAPR_CPU_CORE_INITFN(970mp_v1.0, 970MP_v10); 363 SPAPR_CPU_CORE_INITFN(970mp_v1.1, 970MP_v11); 364 SPAPR_CPU_CORE_INITFN(970_v2.2, 970); 365 SPAPR_CPU_CORE_INITFN(POWER5+_v2.1, POWER5plus); 366 SPAPR_CPU_CORE_INITFN(POWER7_v2.3, POWER7); 367 SPAPR_CPU_CORE_INITFN(POWER7+_v2.1, POWER7plus); 368 SPAPR_CPU_CORE_INITFN(POWER8_v2.0, POWER8); 369 SPAPR_CPU_CORE_INITFN(POWER8E_v2.1, POWER8E); 370 SPAPR_CPU_CORE_INITFN(POWER8NVL_v1.0, POWER8NVL); 371 372 typedef struct SPAPRCoreInfo { 373 const char *name; 374 void (*initfn)(Object *obj); 375 } SPAPRCoreInfo; 376 377 static const SPAPRCoreInfo spapr_cores[] = { 378 /* 970 and aliaes */ 379 { .name = "970_v2.2", .initfn = spapr_cpu_core_970_initfn }, 380 { .name = "970", .initfn = spapr_cpu_core_970_initfn }, 381 382 /* 970MP variants and aliases */ 383 { .name = "970MP_v1.0", .initfn = spapr_cpu_core_970MP_v10_initfn }, 384 { .name = "970mp_v1.0", .initfn = spapr_cpu_core_970MP_v10_initfn }, 385 { .name = "970MP_v1.1", .initfn = spapr_cpu_core_970MP_v11_initfn }, 386 { .name = "970mp_v1.1", .initfn = spapr_cpu_core_970MP_v11_initfn }, 387 { .name = "970mp", .initfn = spapr_cpu_core_970MP_v11_initfn }, 388 389 /* POWER5 and aliases */ 390 { .name = "POWER5+_v2.1", .initfn = spapr_cpu_core_POWER5plus_initfn }, 391 { .name = "POWER5+", .initfn = spapr_cpu_core_POWER5plus_initfn }, 392 393 /* POWER7 and aliases */ 394 { .name = "POWER7_v2.3", .initfn = spapr_cpu_core_POWER7_initfn }, 395 { .name = "POWER7", .initfn = spapr_cpu_core_POWER7_initfn }, 396 397 /* POWER7+ and aliases */ 398 { .name = "POWER7+_v2.1", .initfn = spapr_cpu_core_POWER7plus_initfn }, 399 { .name = "POWER7+", .initfn = spapr_cpu_core_POWER7plus_initfn }, 400 401 /* POWER8 and aliases */ 402 { .name = "POWER8_v2.0", .initfn = spapr_cpu_core_POWER8_initfn }, 403 { .name = "POWER8", .initfn = spapr_cpu_core_POWER8_initfn }, 404 { .name = "power8", .initfn = spapr_cpu_core_POWER8_initfn }, 405 406 /* POWER8E and aliases */ 407 { .name = "POWER8E_v2.1", .initfn = spapr_cpu_core_POWER8E_initfn }, 408 { .name = "POWER8E", .initfn = spapr_cpu_core_POWER8E_initfn }, 409 410 /* POWER8NVL and aliases */ 411 { .name = "POWER8NVL_v1.0", .initfn = spapr_cpu_core_POWER8NVL_initfn }, 412 { .name = "POWER8NVL", .initfn = spapr_cpu_core_POWER8NVL_initfn }, 413 414 { .name = NULL } 415 }; 416 417 static void spapr_cpu_core_register(const SPAPRCoreInfo *info) 418 { 419 TypeInfo type_info = { 420 .parent = TYPE_SPAPR_CPU_CORE, 421 .instance_size = sizeof(sPAPRCPUCore), 422 .instance_init = info->initfn, 423 }; 424 425 type_info.name = g_strdup_printf("%s-" TYPE_SPAPR_CPU_CORE, info->name); 426 type_register(&type_info); 427 g_free((void *)type_info.name); 428 } 429 430 static const TypeInfo spapr_cpu_core_type_info = { 431 .name = TYPE_SPAPR_CPU_CORE, 432 .parent = TYPE_CPU_CORE, 433 .abstract = true, 434 .instance_size = sizeof(sPAPRCPUCore), 435 .class_init = spapr_cpu_core_class_init, 436 }; 437 438 static void spapr_cpu_core_register_types(void) 439 { 440 const SPAPRCoreInfo *info = spapr_cores; 441 442 type_register_static(&spapr_cpu_core_type_info); 443 while (info->name) { 444 spapr_cpu_core_register(info); 445 info++; 446 } 447 } 448 449 type_init(spapr_cpu_core_register_types) 450