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