xref: /qemu/target/s390x/machine.c (revision 65cb7129f4160c7e07a0da107f888ec73ae96776)
1ef1df130SThomas Huth /*
2ef1df130SThomas Huth  * S390x machine definitions and functions
3ef1df130SThomas Huth  *
427e84d4eSChristian Borntraeger  * Copyright IBM Corp. 2014, 2018
5ef1df130SThomas Huth  *
6ef1df130SThomas Huth  * Authors:
7ef1df130SThomas Huth  *   Thomas Huth <thuth@linux.vnet.ibm.com>
8ef1df130SThomas Huth  *   Christian Borntraeger <borntraeger@de.ibm.com>
9ef1df130SThomas Huth  *   Jason J. Herne <jjherne@us.ibm.com>
10ef1df130SThomas Huth  *
11ef1df130SThomas Huth  * This work is free software; you can redistribute it and/or modify
12ef1df130SThomas Huth  * it under the terms of the GNU General Public License as published
13ef1df130SThomas Huth  * by the Free Software Foundation; either version 2 of the License,
14ef1df130SThomas Huth  * or (at your option) any later version.
15ef1df130SThomas Huth  */
16ef1df130SThomas Huth 
179615495aSPeter Maydell #include "qemu/osdep.h"
18ef1df130SThomas Huth #include "cpu.h"
19b6b47223SCho, Yu-Chen #include "s390x-internal.h"
2067043607SCho, Yu-Chen #include "kvm/kvm_s390x.h"
21d6454270SMarkus Armbruster #include "migration/vmstate.h"
22c9274b6bSCho, Yu-Chen #include "tcg/tcg_s390x.h"
23*32cad1ffSPhilippe Mathieu-Daudé #include "system/kvm.h"
24*32cad1ffSPhilippe Mathieu-Daudé #include "system/tcg.h"
25ef1df130SThomas Huth 
cpu_post_load(void * opaque,int version_id)26ef1df130SThomas Huth static int cpu_post_load(void *opaque, int version_id)
27ef1df130SThomas Huth {
28ef1df130SThomas Huth     S390CPU *cpu = opaque;
29ef1df130SThomas Huth 
30ef1df130SThomas Huth     /*
31ef1df130SThomas Huth      * As the cpu state is pushed to kvm via kvm_set_mp_state rather
32ef1df130SThomas Huth      * than via cpu_synchronize_state, we need update kvm here.
33ef1df130SThomas Huth      */
34ef1df130SThomas Huth     if (kvm_enabled()) {
35ef1df130SThomas Huth         kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
363cda44f7SJens Freimann         return kvm_s390_vcpu_interrupt_post_load(cpu);
37ef1df130SThomas Huth     }
38ef1df130SThomas Huth 
397c12f710SDavid Hildenbrand     if (tcg_enabled()) {
407c12f710SDavid Hildenbrand         /* Rearm the CKC timer if necessary */
417c12f710SDavid Hildenbrand         tcg_s390_tod_updated(CPU(cpu), RUN_ON_CPU_NULL);
427c12f710SDavid Hildenbrand     }
437c12f710SDavid Hildenbrand 
44ef1df130SThomas Huth     return 0;
45ef1df130SThomas Huth }
46303c681aSRichard Henderson 
cpu_pre_save(void * opaque)4744b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque)
483cda44f7SJens Freimann {
493cda44f7SJens Freimann     S390CPU *cpu = opaque;
503cda44f7SJens Freimann 
513cda44f7SJens Freimann     if (kvm_enabled()) {
523cda44f7SJens Freimann         kvm_s390_vcpu_interrupt_pre_save(cpu);
533cda44f7SJens Freimann     }
5444b1ff31SDr. David Alan Gilbert 
5544b1ff31SDr. David Alan Gilbert     return 0;
563cda44f7SJens Freimann }
57ef1df130SThomas Huth 
fpu_needed(void * opaque)585cd8cadaSJuan Quintela static inline bool fpu_needed(void *opaque)
595cd8cadaSJuan Quintela {
605cd8cadaSJuan Quintela     /* This looks odd, but we might want to NOT transfer fprs in the future */
615cd8cadaSJuan Quintela     return true;
625cd8cadaSJuan Quintela }
635cd8cadaSJuan Quintela 
6452c6cfb7SChristian Borntraeger static const VMStateDescription vmstate_fpu = {
6546c804deSDavid Hildenbrand     .name = "cpu/fpu",
6646c804deSDavid Hildenbrand     .version_id = 1,
6746c804deSDavid Hildenbrand     .minimum_version_id = 1,
685cd8cadaSJuan Quintela     .needed = fpu_needed,
695c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
704f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[0][0], S390CPU),
714f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[1][0], S390CPU),
724f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[2][0], S390CPU),
734f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[3][0], S390CPU),
744f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[4][0], S390CPU),
754f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[5][0], S390CPU),
764f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[6][0], S390CPU),
774f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[7][0], S390CPU),
784f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[8][0], S390CPU),
794f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[9][0], S390CPU),
804f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[10][0], S390CPU),
814f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[11][0], S390CPU),
824f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[12][0], S390CPU),
834f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[13][0], S390CPU),
844f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[14][0], S390CPU),
854f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[15][0], S390CPU),
8646c804deSDavid Hildenbrand         VMSTATE_UINT32(env.fpc, S390CPU),
8746c804deSDavid Hildenbrand         VMSTATE_END_OF_LIST()
8846c804deSDavid Hildenbrand     }
8946c804deSDavid Hildenbrand };
9046c804deSDavid Hildenbrand 
vregs_needed(void * opaque)91b01501dbSPaolo Bonzini static bool vregs_needed(void *opaque)
92b01501dbSPaolo Bonzini {
937c72ac49SDavid Hildenbrand     return s390_has_feat(S390_FEAT_VECTOR);
94b01501dbSPaolo Bonzini }
95b01501dbSPaolo Bonzini 
9652c6cfb7SChristian Borntraeger static const VMStateDescription vmstate_vregs = {
97b2ac0ff5SEric Farman     .name = "cpu/vregs",
98b2ac0ff5SEric Farman     .version_id = 1,
99b2ac0ff5SEric Farman     .minimum_version_id = 1,
1005cd8cadaSJuan Quintela     .needed = vregs_needed,
1015c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
102b2ac0ff5SEric Farman         /* vregs[0][0] -> vregs[15][0] and fregs are overlays */
1034f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[16][0], S390CPU),
1044f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[17][0], S390CPU),
1054f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[18][0], S390CPU),
1064f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[19][0], S390CPU),
1074f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[20][0], S390CPU),
1084f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[21][0], S390CPU),
1094f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[22][0], S390CPU),
1104f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[23][0], S390CPU),
1114f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[24][0], S390CPU),
1124f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[25][0], S390CPU),
1134f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[26][0], S390CPU),
1144f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[27][0], S390CPU),
1154f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[28][0], S390CPU),
1164f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[29][0], S390CPU),
1174f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[30][0], S390CPU),
1184f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[31][0], S390CPU),
1194f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[0][1], S390CPU),
1204f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[1][1], S390CPU),
1214f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[2][1], S390CPU),
1224f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[3][1], S390CPU),
1234f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[4][1], S390CPU),
1244f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[5][1], S390CPU),
1254f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[6][1], S390CPU),
1264f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[7][1], S390CPU),
1274f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[8][1], S390CPU),
1284f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[9][1], S390CPU),
1294f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[10][1], S390CPU),
1304f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[11][1], S390CPU),
1314f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[12][1], S390CPU),
1324f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[13][1], S390CPU),
1334f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[14][1], S390CPU),
1344f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[15][1], S390CPU),
1354f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[16][1], S390CPU),
1364f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[17][1], S390CPU),
1374f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[18][1], S390CPU),
1384f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[19][1], S390CPU),
1394f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[20][1], S390CPU),
1404f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[21][1], S390CPU),
1414f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[22][1], S390CPU),
1424f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[23][1], S390CPU),
1434f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[24][1], S390CPU),
1444f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[25][1], S390CPU),
1454f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[26][1], S390CPU),
1464f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[27][1], S390CPU),
1474f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[28][1], S390CPU),
1484f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[29][1], S390CPU),
1494f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[30][1], S390CPU),
1504f83d7d2SDavid Hildenbrand         VMSTATE_UINT64(env.vregs[31][1], S390CPU),
151b2ac0ff5SEric Farman         VMSTATE_END_OF_LIST()
152b2ac0ff5SEric Farman     }
153b2ac0ff5SEric Farman };
154b2ac0ff5SEric Farman 
riccb_needed(void * opaque)155b01501dbSPaolo Bonzini static bool riccb_needed(void *opaque)
156b01501dbSPaolo Bonzini {
1577c72ac49SDavid Hildenbrand     return s390_has_feat(S390_FEAT_RUNTIME_INSTRUMENTATION);
158b01501dbSPaolo Bonzini }
159b01501dbSPaolo Bonzini 
1605c04ea96SRichard Henderson static const VMStateDescription vmstate_riccb = {
1619700230bSFan Zhang     .name = "cpu/riccb",
1629700230bSFan Zhang     .version_id = 1,
1639700230bSFan Zhang     .minimum_version_id = 1,
1649700230bSFan Zhang     .needed = riccb_needed,
1655c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
1669700230bSFan Zhang         VMSTATE_UINT8_ARRAY(env.riccb, S390CPU, 64),
1679700230bSFan Zhang         VMSTATE_END_OF_LIST()
1689700230bSFan Zhang     }
1699700230bSFan Zhang };
1709700230bSFan Zhang 
exval_needed(void * opaque)171303c681aSRichard Henderson static bool exval_needed(void *opaque)
172303c681aSRichard Henderson {
173303c681aSRichard Henderson     S390CPU *cpu = opaque;
174303c681aSRichard Henderson     return cpu->env.ex_value != 0;
175303c681aSRichard Henderson }
176303c681aSRichard Henderson 
1775c04ea96SRichard Henderson static const VMStateDescription vmstate_exval = {
178303c681aSRichard Henderson     .name = "cpu/exval",
179303c681aSRichard Henderson     .version_id = 1,
180303c681aSRichard Henderson     .minimum_version_id = 1,
181303c681aSRichard Henderson     .needed = exval_needed,
1825c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
183303c681aSRichard Henderson         VMSTATE_UINT64(env.ex_value, S390CPU),
184303c681aSRichard Henderson         VMSTATE_END_OF_LIST()
185303c681aSRichard Henderson     }
186303c681aSRichard Henderson };
187303c681aSRichard Henderson 
gscb_needed(void * opaque)18862deb62dSFan Zhang static bool gscb_needed(void *opaque)
18962deb62dSFan Zhang {
1900280b3ebSChristian Borntraeger     return s390_has_feat(S390_FEAT_GUARDED_STORAGE);
19162deb62dSFan Zhang }
19262deb62dSFan Zhang 
1935c04ea96SRichard Henderson static const VMStateDescription vmstate_gscb = {
19462deb62dSFan Zhang     .name = "cpu/gscb",
19562deb62dSFan Zhang     .version_id = 1,
19662deb62dSFan Zhang     .minimum_version_id = 1,
19762deb62dSFan Zhang     .needed = gscb_needed,
1985c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
19962deb62dSFan Zhang         VMSTATE_UINT64_ARRAY(env.gscb, S390CPU, 4),
20062deb62dSFan Zhang         VMSTATE_END_OF_LIST()
20162deb62dSFan Zhang         }
20262deb62dSFan Zhang };
20362deb62dSFan Zhang 
bpbc_needed(void * opaque)204b073c875SChristian Borntraeger static bool bpbc_needed(void *opaque)
205b073c875SChristian Borntraeger {
206b073c875SChristian Borntraeger     return s390_has_feat(S390_FEAT_BPB);
207b073c875SChristian Borntraeger }
208b073c875SChristian Borntraeger 
2095c04ea96SRichard Henderson static const VMStateDescription vmstate_bpbc = {
210b073c875SChristian Borntraeger     .name = "cpu/bpbc",
211b073c875SChristian Borntraeger     .version_id = 1,
212b073c875SChristian Borntraeger     .minimum_version_id = 1,
213b073c875SChristian Borntraeger     .needed = bpbc_needed,
2145c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
215b073c875SChristian Borntraeger         VMSTATE_BOOL(env.bpbc, S390CPU),
216b073c875SChristian Borntraeger         VMSTATE_END_OF_LIST()
217b073c875SChristian Borntraeger     }
218b073c875SChristian Borntraeger };
219b073c875SChristian Borntraeger 
etoken_needed(void * opaque)22027e84d4eSChristian Borntraeger static bool etoken_needed(void *opaque)
22127e84d4eSChristian Borntraeger {
22227e84d4eSChristian Borntraeger     return s390_has_feat(S390_FEAT_ETOKEN);
22327e84d4eSChristian Borntraeger }
22427e84d4eSChristian Borntraeger 
2255c04ea96SRichard Henderson static const VMStateDescription vmstate_etoken = {
22627e84d4eSChristian Borntraeger     .name = "cpu/etoken",
22727e84d4eSChristian Borntraeger     .version_id = 1,
22827e84d4eSChristian Borntraeger     .minimum_version_id = 1,
22927e84d4eSChristian Borntraeger     .needed = etoken_needed,
2305c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
23127e84d4eSChristian Borntraeger         VMSTATE_UINT64(env.etoken, S390CPU),
23227e84d4eSChristian Borntraeger         VMSTATE_UINT64(env.etoken_extension, S390CPU),
23327e84d4eSChristian Borntraeger         VMSTATE_END_OF_LIST()
23427e84d4eSChristian Borntraeger     }
23527e84d4eSChristian Borntraeger };
23627e84d4eSChristian Borntraeger 
diag318_needed(void * opaque)237fabdada9SCollin Walling static bool diag318_needed(void *opaque)
238fabdada9SCollin Walling {
239fabdada9SCollin Walling     return s390_has_feat(S390_FEAT_DIAG_318);
240fabdada9SCollin Walling }
241fabdada9SCollin Walling 
2425c04ea96SRichard Henderson static const VMStateDescription vmstate_diag318 = {
243fabdada9SCollin Walling     .name = "cpu/diag318",
244fabdada9SCollin Walling     .version_id = 1,
245fabdada9SCollin Walling     .minimum_version_id = 1,
246fabdada9SCollin Walling     .needed = diag318_needed,
2475c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
248fabdada9SCollin Walling         VMSTATE_UINT64(env.diag318_info, S390CPU),
249fabdada9SCollin Walling         VMSTATE_END_OF_LIST()
250fabdada9SCollin Walling     }
251fabdada9SCollin Walling };
252fabdada9SCollin Walling 
25346c804deSDavid Hildenbrand const VMStateDescription vmstate_s390_cpu = {
25446c804deSDavid Hildenbrand     .name = "cpu",
25546c804deSDavid Hildenbrand     .post_load = cpu_post_load,
2563cda44f7SJens Freimann     .pre_save = cpu_pre_save,
2573cda44f7SJens Freimann     .version_id = 4,
25846c804deSDavid Hildenbrand     .minimum_version_id = 3,
2595c04ea96SRichard Henderson     .fields = (const VMStateField[]) {
260ef1df130SThomas Huth         VMSTATE_UINT64_ARRAY(env.regs, S390CPU, 16),
261ef1df130SThomas Huth         VMSTATE_UINT64(env.psw.mask, S390CPU),
262ef1df130SThomas Huth         VMSTATE_UINT64(env.psw.addr, S390CPU),
263ef1df130SThomas Huth         VMSTATE_UINT64(env.psa, S390CPU),
264ef1df130SThomas Huth         VMSTATE_UINT32(env.todpr, S390CPU),
265ef1df130SThomas Huth         VMSTATE_UINT64(env.pfault_token, S390CPU),
266ef1df130SThomas Huth         VMSTATE_UINT64(env.pfault_compare, S390CPU),
267ef1df130SThomas Huth         VMSTATE_UINT64(env.pfault_select, S390CPU),
268ef1df130SThomas Huth         VMSTATE_UINT64(env.cputm, S390CPU),
269ef1df130SThomas Huth         VMSTATE_UINT64(env.ckc, S390CPU),
270ef1df130SThomas Huth         VMSTATE_UINT64(env.gbea, S390CPU),
271ef1df130SThomas Huth         VMSTATE_UINT64(env.pp, S390CPU),
272ef1df130SThomas Huth         VMSTATE_UINT32_ARRAY(env.aregs, S390CPU, 16),
273ef1df130SThomas Huth         VMSTATE_UINT64_ARRAY(env.cregs, S390CPU, 16),
274ef1df130SThomas Huth         VMSTATE_UINT8(env.cpu_state, S390CPU),
27518ff9494SDavid Hildenbrand         VMSTATE_UINT8(env.sigp_order, S390CPU),
2763cda44f7SJens Freimann         VMSTATE_UINT32_V(irqstate_saved_size, S390CPU, 4),
27759046ec2SHalil Pasic         VMSTATE_VBUFFER_UINT32(irqstate, S390CPU, 4, NULL,
2783cda44f7SJens Freimann                                irqstate_saved_size),
279ef1df130SThomas Huth         VMSTATE_END_OF_LIST()
280ef1df130SThomas Huth     },
2815c04ea96SRichard Henderson     .subsections = (const VMStateDescription * const []) {
2825cd8cadaSJuan Quintela         &vmstate_fpu,
2835cd8cadaSJuan Quintela         &vmstate_vregs,
2849700230bSFan Zhang         &vmstate_riccb,
285303c681aSRichard Henderson         &vmstate_exval,
28662deb62dSFan Zhang         &vmstate_gscb,
287b073c875SChristian Borntraeger         &vmstate_bpbc,
28827e84d4eSChristian Borntraeger         &vmstate_etoken,
289fabdada9SCollin Walling         &vmstate_diag318,
2905cd8cadaSJuan Quintela         NULL
29146c804deSDavid Hildenbrand     },
292ef1df130SThomas Huth };
293