qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

spapr_cpu_core.c (11719B)


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