1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth * S390x machine definitions and functions
3fcf5ef2aSThomas Huth *
427e84d4eSChristian Borntraeger * Copyright IBM Corp. 2014, 2018
5fcf5ef2aSThomas Huth *
6fcf5ef2aSThomas Huth * Authors:
7fcf5ef2aSThomas Huth * Thomas Huth <thuth@linux.vnet.ibm.com>
8fcf5ef2aSThomas Huth * Christian Borntraeger <borntraeger@de.ibm.com>
9fcf5ef2aSThomas Huth * Jason J. Herne <jjherne@us.ibm.com>
10fcf5ef2aSThomas Huth *
11fcf5ef2aSThomas Huth * This work is free software; you can redistribute it and/or modify
12fcf5ef2aSThomas Huth * it under the terms of the GNU General Public License as published
13fcf5ef2aSThomas Huth * by the Free Software Foundation; either version 2 of the License,
14fcf5ef2aSThomas Huth * or (at your option) any later version.
15fcf5ef2aSThomas Huth */
16fcf5ef2aSThomas Huth
17fcf5ef2aSThomas Huth #include "qemu/osdep.h"
18fcf5ef2aSThomas 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"
23fcf5ef2aSThomas Huth #include "sysemu/kvm.h"
2414a48c1dSMarkus Armbruster #include "sysemu/tcg.h"
25fcf5ef2aSThomas Huth
cpu_post_load(void * opaque,int version_id)26fcf5ef2aSThomas Huth static int cpu_post_load(void *opaque, int version_id)
27fcf5ef2aSThomas Huth {
28fcf5ef2aSThomas Huth S390CPU *cpu = opaque;
29fcf5ef2aSThomas Huth
30fcf5ef2aSThomas Huth /*
31fcf5ef2aSThomas Huth * As the cpu state is pushed to kvm via kvm_set_mp_state rather
32fcf5ef2aSThomas Huth * than via cpu_synchronize_state, we need update kvm here.
33fcf5ef2aSThomas Huth */
34fcf5ef2aSThomas Huth if (kvm_enabled()) {
35fcf5ef2aSThomas Huth kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
36fcf5ef2aSThomas Huth return kvm_s390_vcpu_interrupt_post_load(cpu);
37fcf5ef2aSThomas Huth }
38fcf5ef2aSThomas 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
44fcf5ef2aSThomas Huth return 0;
45fcf5ef2aSThomas Huth }
46303c681aSRichard Henderson
cpu_pre_save(void * opaque)4744b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque)
48fcf5ef2aSThomas Huth {
49fcf5ef2aSThomas Huth S390CPU *cpu = opaque;
50fcf5ef2aSThomas Huth
51fcf5ef2aSThomas Huth if (kvm_enabled()) {
52fcf5ef2aSThomas Huth kvm_s390_vcpu_interrupt_pre_save(cpu);
53fcf5ef2aSThomas Huth }
5444b1ff31SDr. David Alan Gilbert
5544b1ff31SDr. David Alan Gilbert return 0;
56fcf5ef2aSThomas Huth }
57fcf5ef2aSThomas Huth
fpu_needed(void * opaque)58fcf5ef2aSThomas Huth static inline bool fpu_needed(void *opaque)
59fcf5ef2aSThomas Huth {
60fcf5ef2aSThomas Huth /* This looks odd, but we might want to NOT transfer fprs in the future */
61fcf5ef2aSThomas Huth return true;
62fcf5ef2aSThomas Huth }
63fcf5ef2aSThomas Huth
64fcf5ef2aSThomas Huth static const VMStateDescription vmstate_fpu = {
65fcf5ef2aSThomas Huth .name = "cpu/fpu",
66fcf5ef2aSThomas Huth .version_id = 1,
67fcf5ef2aSThomas Huth .minimum_version_id = 1,
68fcf5ef2aSThomas Huth .needed = fpu_needed,
69*5c04ea96SRichard 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),
86fcf5ef2aSThomas Huth VMSTATE_UINT32(env.fpc, S390CPU),
87fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
88fcf5ef2aSThomas Huth }
89fcf5ef2aSThomas Huth };
90fcf5ef2aSThomas Huth
vregs_needed(void * opaque)91fcf5ef2aSThomas Huth static bool vregs_needed(void *opaque)
92fcf5ef2aSThomas Huth {
93fcf5ef2aSThomas Huth return s390_has_feat(S390_FEAT_VECTOR);
94fcf5ef2aSThomas Huth }
95fcf5ef2aSThomas Huth
96fcf5ef2aSThomas Huth static const VMStateDescription vmstate_vregs = {
97fcf5ef2aSThomas Huth .name = "cpu/vregs",
98fcf5ef2aSThomas Huth .version_id = 1,
99fcf5ef2aSThomas Huth .minimum_version_id = 1,
100fcf5ef2aSThomas Huth .needed = vregs_needed,
101*5c04ea96SRichard Henderson .fields = (const VMStateField[]) {
102fcf5ef2aSThomas Huth /* 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),
151fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
152fcf5ef2aSThomas Huth }
153fcf5ef2aSThomas Huth };
154fcf5ef2aSThomas Huth
riccb_needed(void * opaque)155fcf5ef2aSThomas Huth static bool riccb_needed(void *opaque)
156fcf5ef2aSThomas Huth {
157fcf5ef2aSThomas Huth return s390_has_feat(S390_FEAT_RUNTIME_INSTRUMENTATION);
158fcf5ef2aSThomas Huth }
159fcf5ef2aSThomas Huth
160*5c04ea96SRichard Henderson static const VMStateDescription vmstate_riccb = {
161fcf5ef2aSThomas Huth .name = "cpu/riccb",
162fcf5ef2aSThomas Huth .version_id = 1,
163fcf5ef2aSThomas Huth .minimum_version_id = 1,
164fcf5ef2aSThomas Huth .needed = riccb_needed,
165*5c04ea96SRichard Henderson .fields = (const VMStateField[]) {
166fcf5ef2aSThomas Huth VMSTATE_UINT8_ARRAY(env.riccb, S390CPU, 64),
167fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
168fcf5ef2aSThomas Huth }
169fcf5ef2aSThomas Huth };
170fcf5ef2aSThomas Huth
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
177*5c04ea96SRichard 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,
182*5c04ea96SRichard 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
193*5c04ea96SRichard 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,
198*5c04ea96SRichard 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
209*5c04ea96SRichard 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,
214*5c04ea96SRichard 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
225*5c04ea96SRichard 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,
230*5c04ea96SRichard 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
242*5c04ea96SRichard 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,
247*5c04ea96SRichard Henderson .fields = (const VMStateField[]) {
248fabdada9SCollin Walling VMSTATE_UINT64(env.diag318_info, S390CPU),
249fabdada9SCollin Walling VMSTATE_END_OF_LIST()
250fabdada9SCollin Walling }
251fabdada9SCollin Walling };
252fabdada9SCollin Walling
253fcf5ef2aSThomas Huth const VMStateDescription vmstate_s390_cpu = {
254fcf5ef2aSThomas Huth .name = "cpu",
255fcf5ef2aSThomas Huth .post_load = cpu_post_load,
256fcf5ef2aSThomas Huth .pre_save = cpu_pre_save,
257fcf5ef2aSThomas Huth .version_id = 4,
258fcf5ef2aSThomas Huth .minimum_version_id = 3,
259*5c04ea96SRichard Henderson .fields = (const VMStateField[]) {
260fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.regs, S390CPU, 16),
261fcf5ef2aSThomas Huth VMSTATE_UINT64(env.psw.mask, S390CPU),
262fcf5ef2aSThomas Huth VMSTATE_UINT64(env.psw.addr, S390CPU),
263fcf5ef2aSThomas Huth VMSTATE_UINT64(env.psa, S390CPU),
264fcf5ef2aSThomas Huth VMSTATE_UINT32(env.todpr, S390CPU),
265fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pfault_token, S390CPU),
266fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pfault_compare, S390CPU),
267fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pfault_select, S390CPU),
268fcf5ef2aSThomas Huth VMSTATE_UINT64(env.cputm, S390CPU),
269fcf5ef2aSThomas Huth VMSTATE_UINT64(env.ckc, S390CPU),
270fcf5ef2aSThomas Huth VMSTATE_UINT64(env.gbea, S390CPU),
271fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pp, S390CPU),
272fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.aregs, S390CPU, 16),
273fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.cregs, S390CPU, 16),
274fcf5ef2aSThomas Huth VMSTATE_UINT8(env.cpu_state, S390CPU),
275fcf5ef2aSThomas Huth VMSTATE_UINT8(env.sigp_order, S390CPU),
276fcf5ef2aSThomas Huth VMSTATE_UINT32_V(irqstate_saved_size, S390CPU, 4),
27759046ec2SHalil Pasic VMSTATE_VBUFFER_UINT32(irqstate, S390CPU, 4, NULL,
278fcf5ef2aSThomas Huth irqstate_saved_size),
279fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
280fcf5ef2aSThomas Huth },
281*5c04ea96SRichard Henderson .subsections = (const VMStateDescription * const []) {
282fcf5ef2aSThomas Huth &vmstate_fpu,
283fcf5ef2aSThomas Huth &vmstate_vregs,
284fcf5ef2aSThomas Huth &vmstate_riccb,
285303c681aSRichard Henderson &vmstate_exval,
28662deb62dSFan Zhang &vmstate_gscb,
287b073c875SChristian Borntraeger &vmstate_bpbc,
28827e84d4eSChristian Borntraeger &vmstate_etoken,
289fabdada9SCollin Walling &vmstate_diag318,
290fcf5ef2aSThomas Huth NULL
291fcf5ef2aSThomas Huth },
292fcf5ef2aSThomas Huth };
293