master
c 629 lines 17.9 KB
Raw
1 /*
2 * s390x SIGP instruction handling
3 *
4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
5 * Copyright IBM Corp. 2012
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
9 */
10
11 #include "qemu/osdep.h"
12 #include "cpu.h"
13 #include "s390x-internal.h"
14 #include "hw/core/boards.h"
15 #include "system/hw_accel.h"
16 #include "system/memory.h"
17 #include "system/runstate.h"
18 #include "system/address-spaces.h"
19 #include "exec/cputlb.h"
20 #include "system/tcg.h"
21 #include "trace.h"
22 #include "qapi/qapi-types-machine.h"
23 #include "target/s390x/kvm/pv.h"
24
25 QemuMutex qemu_sigp_mutex;
26
27 typedef struct SigpInfo {
28 uint64_t param;
29 int cc;
30 uint64_t *status_reg;
31 } SigpInfo;
32
33 static void set_sigp_status(SigpInfo *si, uint64_t status)
34 {
35 *si->status_reg &= 0xffffffff00000000ULL;
36 *si->status_reg |= status;
37 si->cc = SIGP_CC_STATUS_STORED;
38 }
39
40 static void sigp_sense(S390CPU *dst_cpu, SigpInfo *si)
41 {
42 uint8_t state = s390_cpu_get_state(dst_cpu);
43 bool ext_call = dst_cpu->env.pending_int & INTERRUPT_EXTERNAL_CALL;
44 uint64_t status = 0;
45
46 if (!tcg_enabled()) {
47 /* handled in KVM */
48 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
49 return;
50 }
51
52 /* sensing without locks is racy, but it's the same for real hw */
53 if (state != S390_CPU_STATE_STOPPED && !ext_call) {
54 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
55 } else {
56 if (ext_call) {
57 status |= SIGP_STAT_EXT_CALL_PENDING;
58 }
59 if (state == S390_CPU_STATE_STOPPED) {
60 status |= SIGP_STAT_STOPPED;
61 }
62 set_sigp_status(si, status);
63 }
64 }
65
66 static void sigp_external_call(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si)
67 {
68 int ret;
69
70 if (!tcg_enabled()) {
71 /* handled in KVM */
72 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
73 return;
74 }
75
76 ret = cpu_inject_external_call(dst_cpu, src_cpu->env.core_id);
77 if (!ret) {
78 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
79 } else {
80 set_sigp_status(si, SIGP_STAT_EXT_CALL_PENDING);
81 }
82 }
83
84 static void sigp_emergency(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si)
85 {
86 if (!tcg_enabled()) {
87 /* handled in KVM */
88 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
89 return;
90 }
91
92 cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id);
93 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
94 }
95
96 static void sigp_start(CPUState *cs, run_on_cpu_data arg)
97 {
98 S390CPU *cpu = S390_CPU(cs);
99 SigpInfo *si = arg.host_ptr;
100
101 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
102 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
103 return;
104 }
105
106 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
107 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
108 }
109
110 static void sigp_stop(CPUState *cs, run_on_cpu_data arg)
111 {
112 S390CPU *cpu = S390_CPU(cs);
113 SigpInfo *si = arg.host_ptr;
114
115 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) {
116 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
117 return;
118 }
119
120 /* disabled wait - sleeping in user space */
121 if (cs->halted) {
122 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
123 } else {
124 /* execute the stop function */
125 cpu->env.sigp_order = SIGP_STOP;
126 cpu_inject_stop(cpu);
127 }
128 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
129 }
130
131 typedef struct SigpSaveArea {
132 uint64_t fprs[16]; /* 0x0000 */
133 uint64_t grs[16]; /* 0x0080 */
134 PSW psw; /* 0x0100 */
135 uint8_t pad_0x0110[0x0118 - 0x0110]; /* 0x0110 */
136 uint32_t prefix; /* 0x0118 */
137 uint32_t fpc; /* 0x011c */
138 uint8_t pad_0x0120[0x0124 - 0x0120]; /* 0x0120 */
139 uint32_t todpr; /* 0x0124 */
140 uint64_t cputm; /* 0x0128 */
141 uint64_t ckc; /* 0x0130 */
142 uint8_t pad_0x0138[0x0140 - 0x0138]; /* 0x0138 */
143 uint32_t ars[16]; /* 0x0140 */
144 uint64_t crs[16]; /* 0x0384 */
145 } SigpSaveArea;
146 QEMU_BUILD_BUG_ON(sizeof(SigpSaveArea) != 512);
147
148 #define S390_STORE_STATUS_DEF_ADDR offsetof(LowCore, floating_pt_save_area)
149 static int s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch)
150 {
151 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
152 AddressSpace *as = CPU(cpu)->as;
153 SigpSaveArea *sa;
154 hwaddr len = sizeof(*sa);
155 int i;
156
157 /* For PVMs storing will occur when this cpu enters SIE again */
158 if (s390_is_pv()) {
159 return 0;
160 }
161
162 sa = address_space_map(as, addr, &len, true, attrs);
163 if (!sa) {
164 return -EFAULT;
165 }
166 if (len != sizeof(*sa)) {
167 address_space_unmap(as, sa, len, true, 0);
168 return -EFAULT;
169 }
170
171 if (store_arch) {
172 static const uint8_t ar_id = 1;
173
174 address_space_stb(as, offsetof(LowCore, ar_access_id),
175 ar_id, attrs, NULL);
176
177 }
178 for (i = 0; i < 16; ++i) {
179 sa->fprs[i] = cpu_to_be64(*get_freg(&cpu->env, i));
180 }
181 for (i = 0; i < 16; ++i) {
182 sa->grs[i] = cpu_to_be64(cpu->env.regs[i]);
183 }
184 sa->psw.addr = cpu_to_be64(cpu->env.psw.addr);
185 sa->psw.mask = cpu_to_be64(s390_cpu_get_psw_mask(&cpu->env));
186 sa->prefix = cpu_to_be32(cpu->env.psa);
187 sa->fpc = cpu_to_be32(cpu->env.fpc);
188 sa->todpr = cpu_to_be32(cpu->env.todpr);
189 sa->cputm = cpu_to_be64(cpu->env.cputm);
190 sa->ckc = cpu_to_be64(cpu->env.ckc >> 8);
191 for (i = 0; i < 16; ++i) {
192 sa->ars[i] = cpu_to_be32(cpu->env.aregs[i]);
193 }
194 for (i = 0; i < 16; ++i) {
195 sa->crs[i] = cpu_to_be64(cpu->env.cregs[i]);
196 }
197
198 address_space_unmap(as, sa, len, true, len);
199
200 return 0;
201 }
202
203 static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
204 {
205 S390CPU *cpu = S390_CPU(cs);
206 SigpInfo *si = arg.host_ptr;
207
208 /* disabled wait - sleeping in user space */
209 if (s390_cpu_get_state(cpu) == S390_CPU_STATE_OPERATING && cs->halted) {
210 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
211 }
212
213 switch (s390_cpu_get_state(cpu)) {
214 case S390_CPU_STATE_OPERATING:
215 cpu->env.sigp_order = SIGP_STOP_STORE_STATUS;
216 cpu_inject_stop(cpu);
217 /* store will be performed in do_stop_interrupt() */
218 break;
219 case S390_CPU_STATE_STOPPED:
220 /* already stopped, just store the status */
221 cpu_synchronize_state(cs);
222 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
223 break;
224 }
225 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
226 }
227
228 static void sigp_store_status_at_address(CPUState *cs, run_on_cpu_data arg)
229 {
230 S390CPU *cpu = S390_CPU(cs);
231 SigpInfo *si = arg.host_ptr;
232 uint32_t address = si->param & 0x7ffffe00u;
233
234 /* cpu has to be stopped */
235 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
236 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
237 return;
238 }
239
240 cpu_synchronize_state(cs);
241
242 if (s390_store_status(cpu, address, false)) {
243 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
244 return;
245 }
246 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
247 }
248
249 typedef struct SigpAdtlSaveArea {
250 uint64_t vregs[32][2]; /* 0x0000 */
251 uint8_t pad_0x0200[0x0400 - 0x0200]; /* 0x0200 */
252 uint64_t gscb[4]; /* 0x0400 */
253 uint8_t pad_0x0420[0x1000 - 0x0420]; /* 0x0420 */
254 } SigpAdtlSaveArea;
255 QEMU_BUILD_BUG_ON(sizeof(SigpAdtlSaveArea) != 4096);
256
257 #define ADTL_GS_MIN_SIZE 2048 /* minimal size of adtl save area for GS */
258 static int s390_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len)
259 {
260 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
261 AddressSpace *as = CPU(cpu)->as;
262 SigpAdtlSaveArea *sa;
263 hwaddr save = len;
264 int i;
265
266 sa = address_space_map(as, addr, &save, true, attrs);
267 if (!sa) {
268 return -EFAULT;
269 }
270 if (save != len) {
271 address_space_unmap(as, sa, len, true, 0);
272 return -EFAULT;
273 }
274
275 if (s390_has_feat(S390_FEAT_VECTOR)) {
276 for (i = 0; i < 32; i++) {
277 sa->vregs[i][0] = cpu_to_be64(cpu->env.vregs[i][0]);
278 sa->vregs[i][1] = cpu_to_be64(cpu->env.vregs[i][1]);
279 }
280 }
281 if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) && len >= ADTL_GS_MIN_SIZE) {
282 for (i = 0; i < 4; i++) {
283 sa->gscb[i] = cpu_to_be64(cpu->env.gscb[i]);
284 }
285 }
286
287 address_space_unmap(as, sa, len, true, len);
288
289 return 0;
290 }
291
292 #define ADTL_SAVE_LC_MASK 0xfUL
293 static void sigp_store_adtl_status(CPUState *cs, run_on_cpu_data arg)
294 {
295 S390CPU *cpu = S390_CPU(cs);
296 SigpInfo *si = arg.host_ptr;
297 uint8_t lc = si->param & ADTL_SAVE_LC_MASK;
298 hwaddr addr = si->param & ~ADTL_SAVE_LC_MASK;
299 hwaddr len = 1UL << (lc ? lc : 10);
300
301 if (!s390_has_feat(S390_FEAT_VECTOR) &&
302 !s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
303 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
304 return;
305 }
306
307 /* cpu has to be stopped */
308 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
309 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
310 return;
311 }
312
313 /* address must be aligned to length */
314 if (addr & (len - 1)) {
315 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
316 return;
317 }
318
319 /* no GS: only lc == 0 is valid */
320 if (!s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
321 lc != 0) {
322 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
323 return;
324 }
325
326 /* GS: 0, 10, 11, 12 are valid */
327 if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
328 lc != 0 &&
329 lc != 10 &&
330 lc != 11 &&
331 lc != 12) {
332 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
333 return;
334 }
335
336 cpu_synchronize_state(cs);
337
338 if (s390_store_adtl_status(cpu, addr, len)) {
339 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
340 return;
341 }
342 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
343 }
344
345 static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
346 {
347 S390CPU *cpu = S390_CPU(cs);
348 SigpInfo *si = arg.host_ptr;
349
350 switch (s390_cpu_get_state(cpu)) {
351 case S390_CPU_STATE_STOPPED:
352 /* the restart irq has to be delivered prior to any other pending irq */
353 cpu_synchronize_state(cs);
354 /*
355 * Set OPERATING (and unhalting) before loading the restart PSW.
356 * s390_cpu_set_psw() will then properly halt the CPU again if
357 * necessary (TCG).
358 */
359 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
360 do_restart_interrupt(&cpu->env);
361 break;
362 case S390_CPU_STATE_OPERATING:
363 cpu_inject_restart(cpu);
364 break;
365 }
366 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
367 }
368
369 static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
370 {
371 SigpInfo *si = arg.host_ptr;
372
373 cpu_synchronize_state(cs);
374 resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_INITIAL);
375 cpu_synchronize_post_reset(cs);
376 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
377 }
378
379 static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
380 {
381 SigpInfo *si = arg.host_ptr;
382
383 cpu_synchronize_state(cs);
384 resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_NORMAL);
385 cpu_synchronize_post_reset(cs);
386 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
387 }
388
389 static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
390 {
391 S390CPU *cpu = S390_CPU(cs);
392 SigpInfo *si = arg.host_ptr;
393 uint32_t addr = si->param & 0x7fffe000u;
394
395 cpu_synchronize_state(cs);
396
397 if (!address_space_access_valid(&address_space_memory, addr,
398 sizeof(struct LowCore), false,
399 MEMTXATTRS_UNSPECIFIED)) {
400 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
401 return;
402 }
403
404 /* cpu has to be stopped */
405 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
406 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
407 return;
408 }
409
410 cpu->env.psa = addr;
411 tlb_flush(cs);
412 cpu_synchronize_post_init(cs);
413 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
414 }
415
416 static void sigp_cond_emergency(S390CPU *src_cpu, S390CPU *dst_cpu,
417 SigpInfo *si)
418 {
419 const uint64_t psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
420 uint16_t p_asn, s_asn, asn;
421 uint64_t psw_addr, psw_mask;
422 bool idle;
423
424 if (!tcg_enabled()) {
425 /* handled in KVM */
426 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
427 return;
428 }
429
430 /* this looks racy, but these values are only used when STOPPED */
431 idle = CPU(dst_cpu)->halted;
432 psw_addr = dst_cpu->env.psw.addr;
433 psw_mask = dst_cpu->env.psw.mask;
434 asn = si->param;
435 p_asn = dst_cpu->env.cregs[4] & 0xffff; /* Primary ASN */
436 s_asn = dst_cpu->env.cregs[3] & 0xffff; /* Secondary ASN */
437
438 if (s390_cpu_get_state(dst_cpu) != S390_CPU_STATE_STOPPED ||
439 (psw_mask & psw_int_mask) != psw_int_mask ||
440 (idle && psw_addr != 0) ||
441 (!idle && (asn == p_asn || asn == s_asn))) {
442 cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id);
443 } else {
444 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
445 }
446
447 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
448 }
449
450 static void sigp_sense_running(S390CPU *dst_cpu, SigpInfo *si)
451 {
452 if (!tcg_enabled()) {
453 /* handled in KVM */
454 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
455 return;
456 }
457
458 /* sensing without locks is racy, but it's the same for real hw */
459 if (!s390_has_feat(S390_FEAT_SENSE_RUNNING_STATUS)) {
460 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
461 return;
462 }
463
464 /* If halted (which includes also STOPPED), it is not running */
465 if (CPU(dst_cpu)->halted) {
466 set_sigp_status(si, SIGP_STAT_NOT_RUNNING);
467 } else {
468 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
469 }
470 }
471
472 static int handle_sigp_single_dst(S390CPU *cpu, S390CPU *dst_cpu, uint8_t order,
473 uint64_t param, uint64_t *status_reg)
474 {
475 SigpInfo si = {
476 .param = param,
477 .status_reg = status_reg,
478 };
479
480 /* cpu available? */
481 if (dst_cpu == NULL) {
482 return SIGP_CC_NOT_OPERATIONAL;
483 }
484
485 /* only resets can break pending orders */
486 if (dst_cpu->env.sigp_order != 0 &&
487 order != SIGP_CPU_RESET &&
488 order != SIGP_INITIAL_CPU_RESET) {
489 return SIGP_CC_BUSY;
490 }
491
492 switch (order) {
493 case SIGP_SENSE:
494 sigp_sense(dst_cpu, &si);
495 break;
496 case SIGP_EXTERNAL_CALL:
497 sigp_external_call(cpu, dst_cpu, &si);
498 break;
499 case SIGP_EMERGENCY:
500 sigp_emergency(cpu, dst_cpu, &si);
501 break;
502 case SIGP_START:
503 run_on_cpu(CPU(dst_cpu), sigp_start, RUN_ON_CPU_HOST_PTR(&si));
504 break;
505 case SIGP_STOP:
506 run_on_cpu(CPU(dst_cpu), sigp_stop, RUN_ON_CPU_HOST_PTR(&si));
507 break;
508 case SIGP_RESTART:
509 run_on_cpu(CPU(dst_cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si));
510 break;
511 case SIGP_STOP_STORE_STATUS:
512 run_on_cpu(CPU(dst_cpu), sigp_stop_and_store_status, RUN_ON_CPU_HOST_PTR(&si));
513 break;
514 case SIGP_STORE_STATUS_ADDR:
515 run_on_cpu(CPU(dst_cpu), sigp_store_status_at_address, RUN_ON_CPU_HOST_PTR(&si));
516 break;
517 case SIGP_STORE_ADTL_STATUS:
518 run_on_cpu(CPU(dst_cpu), sigp_store_adtl_status, RUN_ON_CPU_HOST_PTR(&si));
519 break;
520 case SIGP_SET_PREFIX:
521 run_on_cpu(CPU(dst_cpu), sigp_set_prefix, RUN_ON_CPU_HOST_PTR(&si));
522 break;
523 case SIGP_INITIAL_CPU_RESET:
524 run_on_cpu(CPU(dst_cpu), sigp_initial_cpu_reset, RUN_ON_CPU_HOST_PTR(&si));
525 break;
526 case SIGP_CPU_RESET:
527 run_on_cpu(CPU(dst_cpu), sigp_cpu_reset, RUN_ON_CPU_HOST_PTR(&si));
528 break;
529 case SIGP_COND_EMERGENCY:
530 sigp_cond_emergency(cpu, dst_cpu, &si);
531 break;
532 case SIGP_SENSE_RUNNING:
533 sigp_sense_running(dst_cpu, &si);
534 break;
535 default:
536 set_sigp_status(&si, SIGP_STAT_INVALID_ORDER);
537 }
538
539 return si.cc;
540 }
541
542 static int sigp_set_architecture(S390CPU *cpu, uint32_t param,
543 uint64_t *status_reg)
544 {
545 *status_reg &= 0xffffffff00000000ULL;
546
547 /* Reject set arch order, with czam we're always in z/Arch mode. */
548 *status_reg |= SIGP_STAT_INVALID_PARAMETER;
549 return SIGP_CC_STATUS_STORED;
550 }
551
552 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
553 {
554 static MachineState *ms;
555
556 if (!ms) {
557 ms = MACHINE(qdev_get_machine());
558 g_assert(ms->possible_cpus);
559 }
560
561 /* CPU address corresponds to the core_id and the index */
562 if (cpu_addr >= ms->possible_cpus->len) {
563 return NULL;
564 }
565 return S390_CPU(ms->possible_cpus->cpus[cpu_addr].cpu);
566 }
567
568 int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3)
569 {
570 uint64_t *status_reg = &env->regs[r1];
571 uint64_t param = (r1 % 2) ? env->regs[r1] : env->regs[r1 + 1];
572 S390CPU *cpu = env_archcpu(env);
573 S390CPU *dst_cpu = NULL;
574 int ret;
575
576 if (qemu_mutex_trylock(&qemu_sigp_mutex)) {
577 ret = SIGP_CC_BUSY;
578 goto out;
579 }
580
581 switch (order) {
582 case SIGP_SET_ARCH:
583 ret = sigp_set_architecture(cpu, param, status_reg);
584 break;
585 default:
586 /* all other sigp orders target a single vcpu */
587 dst_cpu = s390_cpu_addr2state(env->regs[r3]);
588 ret = handle_sigp_single_dst(cpu, dst_cpu, order, param, status_reg);
589 }
590 qemu_mutex_unlock(&qemu_sigp_mutex);
591
592 out:
593 trace_sigp_finished(order, CPU(cpu)->cpu_index,
594 dst_cpu ? CPU(dst_cpu)->cpu_index : -1, ret);
595 g_assert(ret >= 0);
596
597 return ret;
598 }
599
600 int s390_cpu_restart(S390CPU *cpu)
601 {
602 SigpInfo si = {};
603
604 run_on_cpu(CPU(cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si));
605 return 0;
606 }
607
608 void do_stop_interrupt(CPUS390XState *env)
609 {
610 S390CPU *cpu = env_archcpu(env);
611
612 /*
613 * Complete the STOP operation before exposing the CPU as
614 * STOPPED to the system.
615 */
616 if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
617 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
618 }
619 env->sigp_order = 0;
620 if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
621 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
622 }
623 env->pending_int &= ~INTERRUPT_STOP;
624 }
625
626 void s390_init_sigp(void)
627 {
628 qemu_mutex_init(&qemu_sigp_mutex);
629 }