2 * s390x SIGP instruction handling
4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
5 * Copyright IBM Corp. 2012
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.
11 #include "qemu/osdep.h"
14 #include "sysemu/hw_accel.h"
15 #include "sysemu/runstate.h"
16 #include "exec/address-spaces.h"
17 #include "exec/exec-all.h"
18 #include "sysemu/tcg.h"
20 #include "qapi/qapi-types-machine.h"
22 QemuMutex qemu_sigp_mutex
;
24 typedef struct SigpInfo
{
30 static void set_sigp_status(SigpInfo
*si
, uint64_t status
)
32 *si
->status_reg
&= 0xffffffff00000000ULL
;
33 *si
->status_reg
|= status
;
34 si
->cc
= SIGP_CC_STATUS_STORED
;
37 static void sigp_sense(S390CPU
*dst_cpu
, SigpInfo
*si
)
39 uint8_t state
= s390_cpu_get_state(dst_cpu
);
40 bool ext_call
= dst_cpu
->env
.pending_int
& INTERRUPT_EXTERNAL_CALL
;
45 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
49 /* sensing without locks is racy, but it's the same for real hw */
50 if (state
!= S390_CPU_STATE_STOPPED
&& !ext_call
) {
51 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
54 status
|= SIGP_STAT_EXT_CALL_PENDING
;
56 if (state
== S390_CPU_STATE_STOPPED
) {
57 status
|= SIGP_STAT_STOPPED
;
59 set_sigp_status(si
, status
);
63 static void sigp_external_call(S390CPU
*src_cpu
, S390CPU
*dst_cpu
, SigpInfo
*si
)
69 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
73 ret
= cpu_inject_external_call(dst_cpu
, src_cpu
->env
.core_id
);
75 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
77 set_sigp_status(si
, SIGP_STAT_EXT_CALL_PENDING
);
81 static void sigp_emergency(S390CPU
*src_cpu
, S390CPU
*dst_cpu
, SigpInfo
*si
)
85 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
89 cpu_inject_emergency_signal(dst_cpu
, src_cpu
->env
.core_id
);
90 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
93 static void sigp_start(CPUState
*cs
, run_on_cpu_data arg
)
95 S390CPU
*cpu
= S390_CPU(cs
);
96 SigpInfo
*si
= arg
.host_ptr
;
98 if (s390_cpu_get_state(cpu
) != S390_CPU_STATE_STOPPED
) {
99 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
103 s390_cpu_set_state(S390_CPU_STATE_OPERATING
, cpu
);
104 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
107 static void sigp_stop(CPUState
*cs
, run_on_cpu_data arg
)
109 S390CPU
*cpu
= S390_CPU(cs
);
110 SigpInfo
*si
= arg
.host_ptr
;
112 if (s390_cpu_get_state(cpu
) != S390_CPU_STATE_OPERATING
) {
113 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
117 /* disabled wait - sleeping in user space */
119 s390_cpu_set_state(S390_CPU_STATE_STOPPED
, cpu
);
121 /* execute the stop function */
122 cpu
->env
.sigp_order
= SIGP_STOP
;
123 cpu_inject_stop(cpu
);
125 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
128 static void sigp_stop_and_store_status(CPUState
*cs
, run_on_cpu_data arg
)
130 S390CPU
*cpu
= S390_CPU(cs
);
131 SigpInfo
*si
= arg
.host_ptr
;
133 /* disabled wait - sleeping in user space */
134 if (s390_cpu_get_state(cpu
) == S390_CPU_STATE_OPERATING
&& cs
->halted
) {
135 s390_cpu_set_state(S390_CPU_STATE_STOPPED
, cpu
);
138 switch (s390_cpu_get_state(cpu
)) {
139 case S390_CPU_STATE_OPERATING
:
140 cpu
->env
.sigp_order
= SIGP_STOP_STORE_STATUS
;
141 cpu_inject_stop(cpu
);
142 /* store will be performed in do_stop_interrup() */
144 case S390_CPU_STATE_STOPPED
:
145 /* already stopped, just store the status */
146 cpu_synchronize_state(cs
);
147 s390_store_status(cpu
, S390_STORE_STATUS_DEF_ADDR
, true);
150 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
153 static void sigp_store_status_at_address(CPUState
*cs
, run_on_cpu_data arg
)
155 S390CPU
*cpu
= S390_CPU(cs
);
156 SigpInfo
*si
= arg
.host_ptr
;
157 uint32_t address
= si
->param
& 0x7ffffe00u
;
159 /* cpu has to be stopped */
160 if (s390_cpu_get_state(cpu
) != S390_CPU_STATE_STOPPED
) {
161 set_sigp_status(si
, SIGP_STAT_INCORRECT_STATE
);
165 cpu_synchronize_state(cs
);
167 if (s390_store_status(cpu
, address
, false)) {
168 set_sigp_status(si
, SIGP_STAT_INVALID_PARAMETER
);
171 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
174 #define ADTL_SAVE_LC_MASK 0xfUL
175 static void sigp_store_adtl_status(CPUState
*cs
, run_on_cpu_data arg
)
177 S390CPU
*cpu
= S390_CPU(cs
);
178 SigpInfo
*si
= arg
.host_ptr
;
179 uint8_t lc
= si
->param
& ADTL_SAVE_LC_MASK
;
180 hwaddr addr
= si
->param
& ~ADTL_SAVE_LC_MASK
;
181 hwaddr len
= 1UL << (lc
? lc
: 10);
183 if (!s390_has_feat(S390_FEAT_VECTOR
) &&
184 !s390_has_feat(S390_FEAT_GUARDED_STORAGE
)) {
185 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
189 /* cpu has to be stopped */
190 if (s390_cpu_get_state(cpu
) != S390_CPU_STATE_STOPPED
) {
191 set_sigp_status(si
, SIGP_STAT_INCORRECT_STATE
);
195 /* address must be aligned to length */
196 if (addr
& (len
- 1)) {
197 set_sigp_status(si
, SIGP_STAT_INVALID_PARAMETER
);
201 /* no GS: only lc == 0 is valid */
202 if (!s390_has_feat(S390_FEAT_GUARDED_STORAGE
) &&
204 set_sigp_status(si
, SIGP_STAT_INVALID_PARAMETER
);
208 /* GS: 0, 10, 11, 12 are valid */
209 if (s390_has_feat(S390_FEAT_GUARDED_STORAGE
) &&
214 set_sigp_status(si
, SIGP_STAT_INVALID_PARAMETER
);
218 cpu_synchronize_state(cs
);
220 if (s390_store_adtl_status(cpu
, addr
, len
)) {
221 set_sigp_status(si
, SIGP_STAT_INVALID_PARAMETER
);
224 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
227 static void sigp_restart(CPUState
*cs
, run_on_cpu_data arg
)
229 S390CPU
*cpu
= S390_CPU(cs
);
230 SigpInfo
*si
= arg
.host_ptr
;
232 switch (s390_cpu_get_state(cpu
)) {
233 case S390_CPU_STATE_STOPPED
:
234 /* the restart irq has to be delivered prior to any other pending irq */
235 cpu_synchronize_state(cs
);
237 * Set OPERATING (and unhalting) before loading the restart PSW.
238 * load_psw() will then properly halt the CPU again if necessary (TCG).
240 s390_cpu_set_state(S390_CPU_STATE_OPERATING
, cpu
);
241 do_restart_interrupt(&cpu
->env
);
243 case S390_CPU_STATE_OPERATING
:
244 cpu_inject_restart(cpu
);
247 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
250 static void sigp_initial_cpu_reset(CPUState
*cs
, run_on_cpu_data arg
)
252 S390CPU
*cpu
= S390_CPU(cs
);
253 S390CPUClass
*scc
= S390_CPU_GET_CLASS(cpu
);
254 SigpInfo
*si
= arg
.host_ptr
;
256 cpu_synchronize_state(cs
);
257 scc
->initial_cpu_reset(cs
);
258 cpu_synchronize_post_reset(cs
);
259 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
262 static void sigp_cpu_reset(CPUState
*cs
, run_on_cpu_data arg
)
264 S390CPU
*cpu
= S390_CPU(cs
);
265 S390CPUClass
*scc
= S390_CPU_GET_CLASS(cpu
);
266 SigpInfo
*si
= arg
.host_ptr
;
268 cpu_synchronize_state(cs
);
270 cpu_synchronize_post_reset(cs
);
271 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
274 static void sigp_set_prefix(CPUState
*cs
, run_on_cpu_data arg
)
276 S390CPU
*cpu
= S390_CPU(cs
);
277 SigpInfo
*si
= arg
.host_ptr
;
278 uint32_t addr
= si
->param
& 0x7fffe000u
;
280 cpu_synchronize_state(cs
);
282 if (!address_space_access_valid(&address_space_memory
, addr
,
283 sizeof(struct LowCore
), false,
284 MEMTXATTRS_UNSPECIFIED
)) {
285 set_sigp_status(si
, SIGP_STAT_INVALID_PARAMETER
);
289 /* cpu has to be stopped */
290 if (s390_cpu_get_state(cpu
) != S390_CPU_STATE_STOPPED
) {
291 set_sigp_status(si
, SIGP_STAT_INCORRECT_STATE
);
297 cpu_synchronize_post_init(cs
);
298 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
301 static void sigp_cond_emergency(S390CPU
*src_cpu
, S390CPU
*dst_cpu
,
304 const uint64_t psw_int_mask
= PSW_MASK_IO
| PSW_MASK_EXT
;
305 uint16_t p_asn
, s_asn
, asn
;
306 uint64_t psw_addr
, psw_mask
;
309 if (!tcg_enabled()) {
311 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
315 /* this looks racy, but these values are only used when STOPPED */
316 idle
= CPU(dst_cpu
)->halted
;
317 psw_addr
= dst_cpu
->env
.psw
.addr
;
318 psw_mask
= dst_cpu
->env
.psw
.mask
;
320 p_asn
= dst_cpu
->env
.cregs
[4] & 0xffff; /* Primary ASN */
321 s_asn
= dst_cpu
->env
.cregs
[3] & 0xffff; /* Secondary ASN */
323 if (s390_cpu_get_state(dst_cpu
) != S390_CPU_STATE_STOPPED
||
324 (psw_mask
& psw_int_mask
) != psw_int_mask
||
325 (idle
&& psw_addr
!= 0) ||
326 (!idle
&& (asn
== p_asn
|| asn
== s_asn
))) {
327 cpu_inject_emergency_signal(dst_cpu
, src_cpu
->env
.core_id
);
329 set_sigp_status(si
, SIGP_STAT_INCORRECT_STATE
);
332 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
335 static void sigp_sense_running(S390CPU
*dst_cpu
, SigpInfo
*si
)
337 if (!tcg_enabled()) {
339 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
343 /* sensing without locks is racy, but it's the same for real hw */
344 if (!s390_has_feat(S390_FEAT_SENSE_RUNNING_STATUS
)) {
345 set_sigp_status(si
, SIGP_STAT_INVALID_ORDER
);
349 /* If halted (which includes also STOPPED), it is not running */
350 if (CPU(dst_cpu
)->halted
) {
351 si
->cc
= SIGP_CC_ORDER_CODE_ACCEPTED
;
353 set_sigp_status(si
, SIGP_STAT_NOT_RUNNING
);
357 static int handle_sigp_single_dst(S390CPU
*cpu
, S390CPU
*dst_cpu
, uint8_t order
,
358 uint64_t param
, uint64_t *status_reg
)
362 .status_reg
= status_reg
,
366 if (dst_cpu
== NULL
) {
367 return SIGP_CC_NOT_OPERATIONAL
;
370 /* only resets can break pending orders */
371 if (dst_cpu
->env
.sigp_order
!= 0 &&
372 order
!= SIGP_CPU_RESET
&&
373 order
!= SIGP_INITIAL_CPU_RESET
) {
379 sigp_sense(dst_cpu
, &si
);
381 case SIGP_EXTERNAL_CALL
:
382 sigp_external_call(cpu
, dst_cpu
, &si
);
385 sigp_emergency(cpu
, dst_cpu
, &si
);
388 run_on_cpu(CPU(dst_cpu
), sigp_start
, RUN_ON_CPU_HOST_PTR(&si
));
391 run_on_cpu(CPU(dst_cpu
), sigp_stop
, RUN_ON_CPU_HOST_PTR(&si
));
394 run_on_cpu(CPU(dst_cpu
), sigp_restart
, RUN_ON_CPU_HOST_PTR(&si
));
396 case SIGP_STOP_STORE_STATUS
:
397 run_on_cpu(CPU(dst_cpu
), sigp_stop_and_store_status
, RUN_ON_CPU_HOST_PTR(&si
));
399 case SIGP_STORE_STATUS_ADDR
:
400 run_on_cpu(CPU(dst_cpu
), sigp_store_status_at_address
, RUN_ON_CPU_HOST_PTR(&si
));
402 case SIGP_STORE_ADTL_STATUS
:
403 run_on_cpu(CPU(dst_cpu
), sigp_store_adtl_status
, RUN_ON_CPU_HOST_PTR(&si
));
405 case SIGP_SET_PREFIX
:
406 run_on_cpu(CPU(dst_cpu
), sigp_set_prefix
, RUN_ON_CPU_HOST_PTR(&si
));
408 case SIGP_INITIAL_CPU_RESET
:
409 run_on_cpu(CPU(dst_cpu
), sigp_initial_cpu_reset
, RUN_ON_CPU_HOST_PTR(&si
));
412 run_on_cpu(CPU(dst_cpu
), sigp_cpu_reset
, RUN_ON_CPU_HOST_PTR(&si
));
414 case SIGP_COND_EMERGENCY
:
415 sigp_cond_emergency(cpu
, dst_cpu
, &si
);
417 case SIGP_SENSE_RUNNING
:
418 sigp_sense_running(dst_cpu
, &si
);
421 set_sigp_status(&si
, SIGP_STAT_INVALID_ORDER
);
427 static int sigp_set_architecture(S390CPU
*cpu
, uint32_t param
,
428 uint64_t *status_reg
)
432 bool all_stopped
= true;
434 CPU_FOREACH(cur_cs
) {
435 cur_cpu
= S390_CPU(cur_cs
);
437 if (cur_cpu
== cpu
) {
440 if (s390_cpu_get_state(cur_cpu
) != S390_CPU_STATE_STOPPED
) {
445 *status_reg
&= 0xffffffff00000000ULL
;
447 /* Reject set arch order, with czam we're always in z/Arch mode. */
448 *status_reg
|= (all_stopped
? SIGP_STAT_INVALID_PARAMETER
:
449 SIGP_STAT_INCORRECT_STATE
);
450 return SIGP_CC_STATUS_STORED
;
453 int handle_sigp(CPUS390XState
*env
, uint8_t order
, uint64_t r1
, uint64_t r3
)
455 uint64_t *status_reg
= &env
->regs
[r1
];
456 uint64_t param
= (r1
% 2) ? env
->regs
[r1
] : env
->regs
[r1
+ 1];
457 S390CPU
*cpu
= env_archcpu(env
);
458 S390CPU
*dst_cpu
= NULL
;
461 if (qemu_mutex_trylock(&qemu_sigp_mutex
)) {
468 ret
= sigp_set_architecture(cpu
, param
, status_reg
);
471 /* all other sigp orders target a single vcpu */
472 dst_cpu
= s390_cpu_addr2state(env
->regs
[r3
]);
473 ret
= handle_sigp_single_dst(cpu
, dst_cpu
, order
, param
, status_reg
);
475 qemu_mutex_unlock(&qemu_sigp_mutex
);
478 trace_sigp_finished(order
, CPU(cpu
)->cpu_index
,
479 dst_cpu
? CPU(dst_cpu
)->cpu_index
: -1, ret
);
485 int s390_cpu_restart(S390CPU
*cpu
)
489 run_on_cpu(CPU(cpu
), sigp_restart
, RUN_ON_CPU_HOST_PTR(&si
));
493 void do_stop_interrupt(CPUS390XState
*env
)
495 S390CPU
*cpu
= env_archcpu(env
);
497 if (s390_cpu_set_state(S390_CPU_STATE_STOPPED
, cpu
) == 0) {
498 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN
);
500 if (cpu
->env
.sigp_order
== SIGP_STOP_STORE_STATUS
) {
501 s390_store_status(cpu
, S390_STORE_STATUS_DEF_ADDR
, true);
504 env
->pending_int
&= ~INTERRUPT_STOP
;
507 void s390_init_sigp(void)
509 qemu_mutex_init(&qemu_sigp_mutex
);