qemu/target/s390x/machine.c
<<
>>
Prefs
   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
  26static 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
  47static 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
  58static 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
  64static 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
  91static bool vregs_needed(void *opaque)
  92{
  93    return s390_has_feat(S390_FEAT_VECTOR);
  94}
  95
  96static 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
 155static bool riccb_needed(void *opaque)
 156{
 157    return s390_has_feat(S390_FEAT_RUNTIME_INSTRUMENTATION);
 158}
 159
 160const 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
 171static bool exval_needed(void *opaque)
 172{
 173    S390CPU *cpu = opaque;
 174    return cpu->env.ex_value != 0;
 175}
 176
 177const 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
 188static bool gscb_needed(void *opaque)
 189{
 190    return s390_has_feat(S390_FEAT_GUARDED_STORAGE);
 191}
 192
 193const 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
 204static bool bpbc_needed(void *opaque)
 205{
 206    return s390_has_feat(S390_FEAT_BPB);
 207}
 208
 209const 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
 220static bool etoken_needed(void *opaque)
 221{
 222    return s390_has_feat(S390_FEAT_ETOKEN);
 223}
 224
 225const 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
 237static bool diag318_needed(void *opaque)
 238{
 239    return s390_has_feat(S390_FEAT_DIAG_318);
 240}
 241
 242const 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
 253const 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};
 293