qemu

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

machine.c (9106B)


      1 /*
      2  * S390x machine definitions and functions
      3  *
      4  * Copyright IBM Corp. 2014, 2018
      5  *
      6  * Authors:
      7  *   Thomas Huth <thuth@linux.vnet.ibm.com>
      8  *   Christian Borntraeger <borntraeger@de.ibm.com>
      9  *   Jason J. Herne <jjherne@us.ibm.com>
     10  *
     11  * This work is free software; you can redistribute it and/or modify
     12  * it under the terms of the GNU General Public License as published
     13  * by the Free Software Foundation; either version 2 of the License,
     14  * or (at your option) any later version.
     15  */
     16 
     17 #include "qemu/osdep.h"
     18 #include "cpu.h"
     19 #include "s390x-internal.h"
     20 #include "kvm/kvm_s390x.h"
     21 #include "migration/vmstate.h"
     22 #include "tcg/tcg_s390x.h"
     23 #include "sysemu/kvm.h"
     24 #include "sysemu/tcg.h"
     25 
     26 static int cpu_post_load(void *opaque, int version_id)
     27 {
     28     S390CPU *cpu = opaque;
     29 
     30     /*
     31      * As the cpu state is pushed to kvm via kvm_set_mp_state rather
     32      * than via cpu_synchronize_state, we need update kvm here.
     33      */
     34     if (kvm_enabled()) {
     35         kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
     36         return kvm_s390_vcpu_interrupt_post_load(cpu);
     37     }
     38 
     39     if (tcg_enabled()) {
     40         /* Rearm the CKC timer if necessary */
     41         tcg_s390_tod_updated(CPU(cpu), RUN_ON_CPU_NULL);
     42     }
     43 
     44     return 0;
     45 }
     46 
     47 static int cpu_pre_save(void *opaque)
     48 {
     49     S390CPU *cpu = opaque;
     50 
     51     if (kvm_enabled()) {
     52         kvm_s390_vcpu_interrupt_pre_save(cpu);
     53     }
     54 
     55     return 0;
     56 }
     57 
     58 static inline bool fpu_needed(void *opaque)
     59 {
     60     /* This looks odd, but we might want to NOT transfer fprs in the future */
     61     return true;
     62 }
     63 
     64 static const VMStateDescription vmstate_fpu = {
     65     .name = "cpu/fpu",
     66     .version_id = 1,
     67     .minimum_version_id = 1,
     68     .needed = fpu_needed,
     69     .fields = (VMStateField[]) {
     70         VMSTATE_UINT64(env.vregs[0][0], S390CPU),
     71         VMSTATE_UINT64(env.vregs[1][0], S390CPU),
     72         VMSTATE_UINT64(env.vregs[2][0], S390CPU),
     73         VMSTATE_UINT64(env.vregs[3][0], S390CPU),
     74         VMSTATE_UINT64(env.vregs[4][0], S390CPU),
     75         VMSTATE_UINT64(env.vregs[5][0], S390CPU),
     76         VMSTATE_UINT64(env.vregs[6][0], S390CPU),
     77         VMSTATE_UINT64(env.vregs[7][0], S390CPU),
     78         VMSTATE_UINT64(env.vregs[8][0], S390CPU),
     79         VMSTATE_UINT64(env.vregs[9][0], S390CPU),
     80         VMSTATE_UINT64(env.vregs[10][0], S390CPU),
     81         VMSTATE_UINT64(env.vregs[11][0], S390CPU),
     82         VMSTATE_UINT64(env.vregs[12][0], S390CPU),
     83         VMSTATE_UINT64(env.vregs[13][0], S390CPU),
     84         VMSTATE_UINT64(env.vregs[14][0], S390CPU),
     85         VMSTATE_UINT64(env.vregs[15][0], S390CPU),
     86         VMSTATE_UINT32(env.fpc, S390CPU),
     87         VMSTATE_END_OF_LIST()
     88     }
     89 };
     90 
     91 static bool vregs_needed(void *opaque)
     92 {
     93     return s390_has_feat(S390_FEAT_VECTOR);
     94 }
     95 
     96 static const VMStateDescription vmstate_vregs = {
     97     .name = "cpu/vregs",
     98     .version_id = 1,
     99     .minimum_version_id = 1,
    100     .needed = vregs_needed,
    101     .fields = (VMStateField[]) {
    102         /* vregs[0][0] -> vregs[15][0] and fregs are overlays */
    103         VMSTATE_UINT64(env.vregs[16][0], S390CPU),
    104         VMSTATE_UINT64(env.vregs[17][0], S390CPU),
    105         VMSTATE_UINT64(env.vregs[18][0], S390CPU),
    106         VMSTATE_UINT64(env.vregs[19][0], S390CPU),
    107         VMSTATE_UINT64(env.vregs[20][0], S390CPU),
    108         VMSTATE_UINT64(env.vregs[21][0], S390CPU),
    109         VMSTATE_UINT64(env.vregs[22][0], S390CPU),
    110         VMSTATE_UINT64(env.vregs[23][0], S390CPU),
    111         VMSTATE_UINT64(env.vregs[24][0], S390CPU),
    112         VMSTATE_UINT64(env.vregs[25][0], S390CPU),
    113         VMSTATE_UINT64(env.vregs[26][0], S390CPU),
    114         VMSTATE_UINT64(env.vregs[27][0], S390CPU),
    115         VMSTATE_UINT64(env.vregs[28][0], S390CPU),
    116         VMSTATE_UINT64(env.vregs[29][0], S390CPU),
    117         VMSTATE_UINT64(env.vregs[30][0], S390CPU),
    118         VMSTATE_UINT64(env.vregs[31][0], S390CPU),
    119         VMSTATE_UINT64(env.vregs[0][1], S390CPU),
    120         VMSTATE_UINT64(env.vregs[1][1], S390CPU),
    121         VMSTATE_UINT64(env.vregs[2][1], S390CPU),
    122         VMSTATE_UINT64(env.vregs[3][1], S390CPU),
    123         VMSTATE_UINT64(env.vregs[4][1], S390CPU),
    124         VMSTATE_UINT64(env.vregs[5][1], S390CPU),
    125         VMSTATE_UINT64(env.vregs[6][1], S390CPU),
    126         VMSTATE_UINT64(env.vregs[7][1], S390CPU),
    127         VMSTATE_UINT64(env.vregs[8][1], S390CPU),
    128         VMSTATE_UINT64(env.vregs[9][1], S390CPU),
    129         VMSTATE_UINT64(env.vregs[10][1], S390CPU),
    130         VMSTATE_UINT64(env.vregs[11][1], S390CPU),
    131         VMSTATE_UINT64(env.vregs[12][1], S390CPU),
    132         VMSTATE_UINT64(env.vregs[13][1], S390CPU),
    133         VMSTATE_UINT64(env.vregs[14][1], S390CPU),
    134         VMSTATE_UINT64(env.vregs[15][1], S390CPU),
    135         VMSTATE_UINT64(env.vregs[16][1], S390CPU),
    136         VMSTATE_UINT64(env.vregs[17][1], S390CPU),
    137         VMSTATE_UINT64(env.vregs[18][1], S390CPU),
    138         VMSTATE_UINT64(env.vregs[19][1], S390CPU),
    139         VMSTATE_UINT64(env.vregs[20][1], S390CPU),
    140         VMSTATE_UINT64(env.vregs[21][1], S390CPU),
    141         VMSTATE_UINT64(env.vregs[22][1], S390CPU),
    142         VMSTATE_UINT64(env.vregs[23][1], S390CPU),
    143         VMSTATE_UINT64(env.vregs[24][1], S390CPU),
    144         VMSTATE_UINT64(env.vregs[25][1], S390CPU),
    145         VMSTATE_UINT64(env.vregs[26][1], S390CPU),
    146         VMSTATE_UINT64(env.vregs[27][1], S390CPU),
    147         VMSTATE_UINT64(env.vregs[28][1], S390CPU),
    148         VMSTATE_UINT64(env.vregs[29][1], S390CPU),
    149         VMSTATE_UINT64(env.vregs[30][1], S390CPU),
    150         VMSTATE_UINT64(env.vregs[31][1], S390CPU),
    151         VMSTATE_END_OF_LIST()
    152     }
    153 };
    154 
    155 static bool riccb_needed(void *opaque)
    156 {
    157     return s390_has_feat(S390_FEAT_RUNTIME_INSTRUMENTATION);
    158 }
    159 
    160 const VMStateDescription vmstate_riccb = {
    161     .name = "cpu/riccb",
    162     .version_id = 1,
    163     .minimum_version_id = 1,
    164     .needed = riccb_needed,
    165     .fields = (VMStateField[]) {
    166         VMSTATE_UINT8_ARRAY(env.riccb, S390CPU, 64),
    167         VMSTATE_END_OF_LIST()
    168     }
    169 };
    170 
    171 static bool exval_needed(void *opaque)
    172 {
    173     S390CPU *cpu = opaque;
    174     return cpu->env.ex_value != 0;
    175 }
    176 
    177 const VMStateDescription vmstate_exval = {
    178     .name = "cpu/exval",
    179     .version_id = 1,
    180     .minimum_version_id = 1,
    181     .needed = exval_needed,
    182     .fields = (VMStateField[]) {
    183         VMSTATE_UINT64(env.ex_value, S390CPU),
    184         VMSTATE_END_OF_LIST()
    185     }
    186 };
    187 
    188 static bool gscb_needed(void *opaque)
    189 {
    190     return s390_has_feat(S390_FEAT_GUARDED_STORAGE);
    191 }
    192 
    193 const VMStateDescription vmstate_gscb = {
    194     .name = "cpu/gscb",
    195     .version_id = 1,
    196     .minimum_version_id = 1,
    197     .needed = gscb_needed,
    198     .fields = (VMStateField[]) {
    199         VMSTATE_UINT64_ARRAY(env.gscb, S390CPU, 4),
    200         VMSTATE_END_OF_LIST()
    201         }
    202 };
    203 
    204 static bool bpbc_needed(void *opaque)
    205 {
    206     return s390_has_feat(S390_FEAT_BPB);
    207 }
    208 
    209 const VMStateDescription vmstate_bpbc = {
    210     .name = "cpu/bpbc",
    211     .version_id = 1,
    212     .minimum_version_id = 1,
    213     .needed = bpbc_needed,
    214     .fields = (VMStateField[]) {
    215         VMSTATE_BOOL(env.bpbc, S390CPU),
    216         VMSTATE_END_OF_LIST()
    217     }
    218 };
    219 
    220 static bool etoken_needed(void *opaque)
    221 {
    222     return s390_has_feat(S390_FEAT_ETOKEN);
    223 }
    224 
    225 const VMStateDescription vmstate_etoken = {
    226     .name = "cpu/etoken",
    227     .version_id = 1,
    228     .minimum_version_id = 1,
    229     .needed = etoken_needed,
    230     .fields = (VMStateField[]) {
    231         VMSTATE_UINT64(env.etoken, S390CPU),
    232         VMSTATE_UINT64(env.etoken_extension, S390CPU),
    233         VMSTATE_END_OF_LIST()
    234     }
    235 };
    236 
    237 static bool diag318_needed(void *opaque)
    238 {
    239     return s390_has_feat(S390_FEAT_DIAG_318);
    240 }
    241 
    242 const VMStateDescription vmstate_diag318 = {
    243     .name = "cpu/diag318",
    244     .version_id = 1,
    245     .minimum_version_id = 1,
    246     .needed = diag318_needed,
    247     .fields = (VMStateField[]) {
    248         VMSTATE_UINT64(env.diag318_info, S390CPU),
    249         VMSTATE_END_OF_LIST()
    250     }
    251 };
    252 
    253 const VMStateDescription vmstate_s390_cpu = {
    254     .name = "cpu",
    255     .post_load = cpu_post_load,
    256     .pre_save = cpu_pre_save,
    257     .version_id = 4,
    258     .minimum_version_id = 3,
    259     .fields      = (VMStateField[]) {
    260         VMSTATE_UINT64_ARRAY(env.regs, S390CPU, 16),
    261         VMSTATE_UINT64(env.psw.mask, S390CPU),
    262         VMSTATE_UINT64(env.psw.addr, S390CPU),
    263         VMSTATE_UINT64(env.psa, S390CPU),
    264         VMSTATE_UINT32(env.todpr, S390CPU),
    265         VMSTATE_UINT64(env.pfault_token, S390CPU),
    266         VMSTATE_UINT64(env.pfault_compare, S390CPU),
    267         VMSTATE_UINT64(env.pfault_select, S390CPU),
    268         VMSTATE_UINT64(env.cputm, S390CPU),
    269         VMSTATE_UINT64(env.ckc, S390CPU),
    270         VMSTATE_UINT64(env.gbea, S390CPU),
    271         VMSTATE_UINT64(env.pp, S390CPU),
    272         VMSTATE_UINT32_ARRAY(env.aregs, S390CPU, 16),
    273         VMSTATE_UINT64_ARRAY(env.cregs, S390CPU, 16),
    274         VMSTATE_UINT8(env.cpu_state, S390CPU),
    275         VMSTATE_UINT8(env.sigp_order, S390CPU),
    276         VMSTATE_UINT32_V(irqstate_saved_size, S390CPU, 4),
    277         VMSTATE_VBUFFER_UINT32(irqstate, S390CPU, 4, NULL,
    278                                irqstate_saved_size),
    279         VMSTATE_END_OF_LIST()
    280     },
    281     .subsections = (const VMStateDescription*[]) {
    282         &vmstate_fpu,
    283         &vmstate_vregs,
    284         &vmstate_riccb,
    285         &vmstate_exval,
    286         &vmstate_gscb,
    287         &vmstate_bpbc,
    288         &vmstate_etoken,
    289         &vmstate_diag318,
    290         NULL
    291     },
    292 };