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 10 #include "qemu/osdep.h" 11 #include "hw/cpu/core.h" 12 #include "hw/ppc/spapr_cpu_core.h" 13 #include "target/ppc/cpu.h" 14 #include "hw/ppc/spapr.h" 15 #include "hw/boards.h" 16 #include "qapi/error.h" 17 #include "sysemu/cpus.h" 18 #include "sysemu/kvm.h" 19 #include "target/ppc/kvm_ppc.h" 20 #include "hw/ppc/ppc.h" 21 #include "target/ppc/mmu-hash64.h" 22 #include "sysemu/numa.h" 23 #include "sysemu/reset.h" 24 #include "sysemu/hw_accel.h" 25 #include "qemu/error-report.h" 26 27 static void spapr_cpu_reset(void *opaque) 28 { 29 PowerPCCPU *cpu = opaque; 30 CPUState *cs = CPU(cpu); 31 CPUPPCState *env = &cpu->env; 32 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 33 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); 34 target_ulong lpcr; 35 36 cpu_reset(cs); 37 38 /* All CPUs start halted. CPU0 is unhalted from the machine level 39 * reset code and the rest are explicitly started up by the guest 40 * using an RTAS call */ 41 cs->halted = 1; 42 43 /* Set compatibility mode to match the boot CPU, which was either set 44 * by the machine reset code or by CAS. This should never fail. 45 */ 46 ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); 47 48 env->spr[SPR_HIOR] = 0; 49 50 lpcr = env->spr[SPR_LPCR]; 51 52 /* Set emulated LPCR to not send interrupts to hypervisor. Note that 53 * under KVM, the actual HW LPCR will be set differently by KVM itself, 54 * the settings below ensure proper operations with TCG in absence of 55 * a real hypervisor. 56 * 57 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for 58 * real mode accesses, which thankfully defaults to 0 and isn't 59 * accessible in guest mode. 60 * 61 * Disable Power-saving mode Exit Cause exceptions for the CPU, so 62 * we don't get spurious wakups before an RTAS start-cpu call. 63 * For the same reason, set PSSCR_EC. 64 */ 65 lpcr &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | pcc->lpcr_pm); 66 lpcr |= LPCR_LPES0 | LPCR_LPES1; 67 env->spr[SPR_PSSCR] |= PSSCR_EC; 68 69 /* Set RMLS to the max (ie, 16G) */ 70 lpcr &= ~LPCR_RMLS; 71 lpcr |= 1ull << LPCR_RMLS_SHIFT; 72 73 ppc_store_lpcr(cpu, lpcr); 74 75 /* Set a full AMOR so guest can use the AMR as it sees fit */ 76 env->spr[SPR_AMOR] = 0xffffffffffffffffull; 77 78 spapr_cpu->vpa_addr = 0; 79 spapr_cpu->slb_shadow_addr = 0; 80 spapr_cpu->slb_shadow_size = 0; 81 spapr_cpu->dtl_addr = 0; 82 spapr_cpu->dtl_size = 0; 83 84 spapr_caps_cpu_apply(SPAPR_MACHINE(qdev_get_machine()), cpu); 85 86 kvm_check_mmu(cpu, &error_fatal); 87 } 88 89 void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3) 90 { 91 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 92 CPUPPCState *env = &cpu->env; 93 94 env->nip = nip; 95 env->gpr[3] = r3; 96 kvmppc_set_reg_ppc_online(cpu, 1); 97 CPU(cpu)->halted = 0; 98 /* Enable Power-saving mode Exit Cause exceptions */ 99 ppc_store_lpcr(cpu, env->spr[SPR_LPCR] | pcc->lpcr_pm); 100 } 101 102 /* 103 * Return the sPAPR CPU core type for @model which essentially is the CPU 104 * model specified with -cpu cmdline option. 105 */ 106 const char *spapr_get_cpu_core_type(const char *cpu_type) 107 { 108 int len = strlen(cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX); 109 char *core_type = g_strdup_printf(SPAPR_CPU_CORE_TYPE_NAME("%.*s"), 110 len, cpu_type); 111 ObjectClass *oc = object_class_by_name(core_type); 112 113 g_free(core_type); 114 if (!oc) { 115 return NULL; 116 } 117 118 return object_class_get_name(oc); 119 } 120 121 static bool slb_shadow_needed(void *opaque) 122 { 123 SpaprCpuState *spapr_cpu = opaque; 124 125 return spapr_cpu->slb_shadow_addr != 0; 126 } 127 128 static const VMStateDescription vmstate_spapr_cpu_slb_shadow = { 129 .name = "spapr_cpu/vpa/slb_shadow", 130 .version_id = 1, 131 .minimum_version_id = 1, 132 .needed = slb_shadow_needed, 133 .fields = (VMStateField[]) { 134 VMSTATE_UINT64(slb_shadow_addr, SpaprCpuState), 135 VMSTATE_UINT64(slb_shadow_size, SpaprCpuState), 136 VMSTATE_END_OF_LIST() 137 } 138 }; 139 140 static bool dtl_needed(void *opaque) 141 { 142 SpaprCpuState *spapr_cpu = opaque; 143 144 return spapr_cpu->dtl_addr != 0; 145 } 146 147 static const VMStateDescription vmstate_spapr_cpu_dtl = { 148 .name = "spapr_cpu/vpa/dtl", 149 .version_id = 1, 150 .minimum_version_id = 1, 151 .needed = dtl_needed, 152 .fields = (VMStateField[]) { 153 VMSTATE_UINT64(dtl_addr, SpaprCpuState), 154 VMSTATE_UINT64(dtl_size, SpaprCpuState), 155 VMSTATE_END_OF_LIST() 156 } 157 }; 158 159 static bool vpa_needed(void *opaque) 160 { 161 SpaprCpuState *spapr_cpu = opaque; 162 163 return spapr_cpu->vpa_addr != 0; 164 } 165 166 static const VMStateDescription vmstate_spapr_cpu_vpa = { 167 .name = "spapr_cpu/vpa", 168 .version_id = 1, 169 .minimum_version_id = 1, 170 .needed = vpa_needed, 171 .fields = (VMStateField[]) { 172 VMSTATE_UINT64(vpa_addr, SpaprCpuState), 173 VMSTATE_END_OF_LIST() 174 }, 175 .subsections = (const VMStateDescription * []) { 176 &vmstate_spapr_cpu_slb_shadow, 177 &vmstate_spapr_cpu_dtl, 178 NULL 179 } 180 }; 181 182 static const VMStateDescription vmstate_spapr_cpu_state = { 183 .name = "spapr_cpu", 184 .version_id = 1, 185 .minimum_version_id = 1, 186 .fields = (VMStateField[]) { 187 VMSTATE_END_OF_LIST() 188 }, 189 .subsections = (const VMStateDescription * []) { 190 &vmstate_spapr_cpu_vpa, 191 NULL 192 } 193 }; 194 195 static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc) 196 { 197 if (!sc->pre_3_0_migration) { 198 vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data); 199 } 200 qemu_unregister_reset(spapr_cpu_reset, cpu); 201 if (spapr_cpu_state(cpu)->icp) { 202 object_unparent(OBJECT(spapr_cpu_state(cpu)->icp)); 203 } 204 if (spapr_cpu_state(cpu)->tctx) { 205 object_unparent(OBJECT(spapr_cpu_state(cpu)->tctx)); 206 } 207 cpu_remove_sync(CPU(cpu)); 208 object_unparent(OBJECT(cpu)); 209 } 210 211 static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp) 212 { 213 SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); 214 CPUCore *cc = CPU_CORE(dev); 215 int i; 216 217 for (i = 0; i < cc->nr_threads; i++) { 218 spapr_unrealize_vcpu(sc->threads[i], sc); 219 } 220 g_free(sc->threads); 221 } 222 223 static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, 224 SpaprCpuCore *sc, Error **errp) 225 { 226 CPUPPCState *env = &cpu->env; 227 CPUState *cs = CPU(cpu); 228 Error *local_err = NULL; 229 230 object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); 231 if (local_err) { 232 goto error; 233 } 234 235 /* Set time-base frequency to 512 MHz */ 236 cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); 237 238 cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); 239 kvmppc_set_papr(cpu); 240 241 qemu_register_reset(spapr_cpu_reset, cpu); 242 spapr_cpu_reset(cpu); 243 244 spapr->irq->cpu_intc_create(spapr, cpu, &local_err); 245 if (local_err) { 246 goto error_unregister; 247 } 248 249 if (!sc->pre_3_0_migration) { 250 vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state, 251 cpu->machine_data); 252 } 253 254 return; 255 256 error_unregister: 257 qemu_unregister_reset(spapr_cpu_reset, cpu); 258 cpu_remove_sync(CPU(cpu)); 259 error: 260 error_propagate(errp, local_err); 261 } 262 263 static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp) 264 { 265 SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc); 266 CPUCore *cc = CPU_CORE(sc); 267 Object *obj; 268 char *id; 269 CPUState *cs; 270 PowerPCCPU *cpu; 271 Error *local_err = NULL; 272 273 obj = object_new(scc->cpu_type); 274 275 cs = CPU(obj); 276 cpu = POWERPC_CPU(obj); 277 cs->cpu_index = cc->core_id + i; 278 spapr_set_vcpu_id(cpu, cs->cpu_index, &local_err); 279 if (local_err) { 280 goto err; 281 } 282 283 cpu->node_id = sc->node_id; 284 285 id = g_strdup_printf("thread[%d]", i); 286 object_property_add_child(OBJECT(sc), id, obj, &local_err); 287 g_free(id); 288 if (local_err) { 289 goto err; 290 } 291 292 cpu->machine_data = g_new0(SpaprCpuState, 1); 293 294 object_unref(obj); 295 return cpu; 296 297 err: 298 object_unref(obj); 299 error_propagate(errp, local_err); 300 return NULL; 301 } 302 303 static void spapr_delete_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc) 304 { 305 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); 306 307 cpu->machine_data = NULL; 308 g_free(spapr_cpu); 309 object_unparent(OBJECT(cpu)); 310 } 311 312 static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) 313 { 314 /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user 315 * tries to add a sPAPR CPU core to a non-pseries machine. 316 */ 317 SpaprMachineState *spapr = 318 (SpaprMachineState *) object_dynamic_cast(qdev_get_machine(), 319 TYPE_SPAPR_MACHINE); 320 SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); 321 CPUCore *cc = CPU_CORE(OBJECT(dev)); 322 Error *local_err = NULL; 323 int i, j; 324 325 if (!spapr) { 326 error_setg(errp, TYPE_SPAPR_CPU_CORE " needs a pseries machine"); 327 return; 328 } 329 330 sc->threads = g_new(PowerPCCPU *, cc->nr_threads); 331 for (i = 0; i < cc->nr_threads; i++) { 332 sc->threads[i] = spapr_create_vcpu(sc, i, &local_err); 333 if (local_err) { 334 goto err; 335 } 336 } 337 338 for (j = 0; j < cc->nr_threads; j++) { 339 spapr_realize_vcpu(sc->threads[j], spapr, sc, &local_err); 340 if (local_err) { 341 goto err_unrealize; 342 } 343 } 344 return; 345 346 err_unrealize: 347 while (--j >= 0) { 348 spapr_unrealize_vcpu(sc->threads[j], sc); 349 } 350 err: 351 while (--i >= 0) { 352 spapr_delete_vcpu(sc->threads[i], sc); 353 } 354 g_free(sc->threads); 355 error_propagate(errp, local_err); 356 } 357 358 static Property spapr_cpu_core_properties[] = { 359 DEFINE_PROP_INT32("node-id", SpaprCpuCore, node_id, CPU_UNSET_NUMA_NODE_ID), 360 DEFINE_PROP_BOOL("pre-3.0-migration", SpaprCpuCore, pre_3_0_migration, 361 false), 362 DEFINE_PROP_END_OF_LIST() 363 }; 364 365 static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) 366 { 367 DeviceClass *dc = DEVICE_CLASS(oc); 368 SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc); 369 370 dc->realize = spapr_cpu_core_realize; 371 dc->unrealize = spapr_cpu_core_unrealize; 372 dc->props = spapr_cpu_core_properties; 373 scc->cpu_type = data; 374 } 375 376 #define DEFINE_SPAPR_CPU_CORE_TYPE(cpu_model) \ 377 { \ 378 .parent = TYPE_SPAPR_CPU_CORE, \ 379 .class_data = (void *) POWERPC_CPU_TYPE_NAME(cpu_model), \ 380 .class_init = spapr_cpu_core_class_init, \ 381 .name = SPAPR_CPU_CORE_TYPE_NAME(cpu_model), \ 382 } 383 384 static const TypeInfo spapr_cpu_core_type_infos[] = { 385 { 386 .name = TYPE_SPAPR_CPU_CORE, 387 .parent = TYPE_CPU_CORE, 388 .abstract = true, 389 .instance_size = sizeof(SpaprCpuCore), 390 .class_size = sizeof(SpaprCpuCoreClass), 391 }, 392 DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"), 393 DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"), 394 DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"), 395 DEFINE_SPAPR_CPU_CORE_TYPE("power5+_v2.1"), 396 DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"), 397 DEFINE_SPAPR_CPU_CORE_TYPE("power7+_v2.1"), 398 DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"), 399 DEFINE_SPAPR_CPU_CORE_TYPE("power8e_v2.1"), 400 DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"), 401 DEFINE_SPAPR_CPU_CORE_TYPE("power9_v1.0"), 402 DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"), 403 #ifdef CONFIG_KVM 404 DEFINE_SPAPR_CPU_CORE_TYPE("host"), 405 #endif 406 }; 407 408 DEFINE_TYPES(spapr_cpu_core_type_infos) 409