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/boards.h"
15 #include "system/hw_accel.h"
16 #include "system/runstate.h"
17 #include "exec/address-spaces.h"
18 #include "exec/cputlb.h"
19 #include "exec/exec-all.h"
20 #include "system/tcg.h"
21 #include "trace.h"
22 #include "qapi/qapi-types-machine.h"
23
24 QemuMutex qemu_sigp_mutex;
25
26 typedef struct SigpInfo {
27 uint64_t param;
28 int cc;
29 uint64_t *status_reg;
30 } SigpInfo;
31
set_sigp_status(SigpInfo * si,uint64_t status)32 static void set_sigp_status(SigpInfo *si, uint64_t status)
33 {
34 *si->status_reg &= 0xffffffff00000000ULL;
35 *si->status_reg |= status;
36 si->cc = SIGP_CC_STATUS_STORED;
37 }
38
sigp_sense(S390CPU * dst_cpu,SigpInfo * si)39 static void sigp_sense(S390CPU *dst_cpu, SigpInfo *si)
40 {
41 uint8_t state = s390_cpu_get_state(dst_cpu);
42 bool ext_call = dst_cpu->env.pending_int & INTERRUPT_EXTERNAL_CALL;
43 uint64_t status = 0;
44
45 if (!tcg_enabled()) {
46 /* handled in KVM */
47 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
48 return;
49 }
50
51 /* sensing without locks is racy, but it's the same for real hw */
52 if (state != S390_CPU_STATE_STOPPED && !ext_call) {
53 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
54 } else {
55 if (ext_call) {
56 status |= SIGP_STAT_EXT_CALL_PENDING;
57 }
58 if (state == S390_CPU_STATE_STOPPED) {
59 status |= SIGP_STAT_STOPPED;
60 }
61 set_sigp_status(si, status);
62 }
63 }
64
sigp_external_call(S390CPU * src_cpu,S390CPU * dst_cpu,SigpInfo * si)65 static void sigp_external_call(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si)
66 {
67 int ret;
68
69 if (!tcg_enabled()) {
70 /* handled in KVM */
71 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
72 return;
73 }
74
75 ret = cpu_inject_external_call(dst_cpu, src_cpu->env.core_id);
76 if (!ret) {
77 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
78 } else {
79 set_sigp_status(si, SIGP_STAT_EXT_CALL_PENDING);
80 }
81 }
82
sigp_emergency(S390CPU * src_cpu,S390CPU * dst_cpu,SigpInfo * si)83 static void sigp_emergency(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si)
84 {
85 if (!tcg_enabled()) {
86 /* handled in KVM */
87 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
88 return;
89 }
90
91 cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id);
92 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
93 }
94
sigp_start(CPUState * cs,run_on_cpu_data arg)95 static void sigp_start(CPUState *cs, run_on_cpu_data arg)
96 {
97 S390CPU *cpu = S390_CPU(cs);
98 SigpInfo *si = arg.host_ptr;
99
100 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
101 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
102 return;
103 }
104
105 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
106 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
107 }
108
sigp_stop(CPUState * cs,run_on_cpu_data arg)109 static void sigp_stop(CPUState *cs, run_on_cpu_data arg)
110 {
111 S390CPU *cpu = S390_CPU(cs);
112 SigpInfo *si = arg.host_ptr;
113
114 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) {
115 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
116 return;
117 }
118
119 /* disabled wait - sleeping in user space */
120 if (cs->halted) {
121 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
122 } else {
123 /* execute the stop function */
124 cpu->env.sigp_order = SIGP_STOP;
125 cpu_inject_stop(cpu);
126 }
127 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
128 }
129
sigp_stop_and_store_status(CPUState * cs,run_on_cpu_data arg)130 static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
131 {
132 S390CPU *cpu = S390_CPU(cs);
133 SigpInfo *si = arg.host_ptr;
134
135 /* disabled wait - sleeping in user space */
136 if (s390_cpu_get_state(cpu) == S390_CPU_STATE_OPERATING && cs->halted) {
137 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
138 }
139
140 switch (s390_cpu_get_state(cpu)) {
141 case S390_CPU_STATE_OPERATING:
142 cpu->env.sigp_order = SIGP_STOP_STORE_STATUS;
143 cpu_inject_stop(cpu);
144 /* store will be performed in do_stop_interrupt() */
145 break;
146 case S390_CPU_STATE_STOPPED:
147 /* already stopped, just store the status */
148 cpu_synchronize_state(cs);
149 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
150 break;
151 }
152 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
153 }
154
sigp_store_status_at_address(CPUState * cs,run_on_cpu_data arg)155 static void sigp_store_status_at_address(CPUState *cs, run_on_cpu_data arg)
156 {
157 S390CPU *cpu = S390_CPU(cs);
158 SigpInfo *si = arg.host_ptr;
159 uint32_t address = si->param & 0x7ffffe00u;
160
161 /* cpu has to be stopped */
162 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
163 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
164 return;
165 }
166
167 cpu_synchronize_state(cs);
168
169 if (s390_store_status(cpu, address, false)) {
170 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
171 return;
172 }
173 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
174 }
175
176 #define ADTL_SAVE_LC_MASK 0xfUL
sigp_store_adtl_status(CPUState * cs,run_on_cpu_data arg)177 static void sigp_store_adtl_status(CPUState *cs, run_on_cpu_data arg)
178 {
179 S390CPU *cpu = S390_CPU(cs);
180 SigpInfo *si = arg.host_ptr;
181 uint8_t lc = si->param & ADTL_SAVE_LC_MASK;
182 hwaddr addr = si->param & ~ADTL_SAVE_LC_MASK;
183 hwaddr len = 1UL << (lc ? lc : 10);
184
185 if (!s390_has_feat(S390_FEAT_VECTOR) &&
186 !s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
187 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
188 return;
189 }
190
191 /* cpu has to be stopped */
192 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
193 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
194 return;
195 }
196
197 /* address must be aligned to length */
198 if (addr & (len - 1)) {
199 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
200 return;
201 }
202
203 /* no GS: only lc == 0 is valid */
204 if (!s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
205 lc != 0) {
206 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
207 return;
208 }
209
210 /* GS: 0, 10, 11, 12 are valid */
211 if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
212 lc != 0 &&
213 lc != 10 &&
214 lc != 11 &&
215 lc != 12) {
216 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
217 return;
218 }
219
220 cpu_synchronize_state(cs);
221
222 if (s390_store_adtl_status(cpu, addr, len)) {
223 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
224 return;
225 }
226 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
227 }
228
sigp_restart(CPUState * cs,run_on_cpu_data arg)229 static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
230 {
231 S390CPU *cpu = S390_CPU(cs);
232 SigpInfo *si = arg.host_ptr;
233
234 switch (s390_cpu_get_state(cpu)) {
235 case S390_CPU_STATE_STOPPED:
236 /* the restart irq has to be delivered prior to any other pending irq */
237 cpu_synchronize_state(cs);
238 /*
239 * Set OPERATING (and unhalting) before loading the restart PSW.
240 * s390_cpu_set_psw() will then properly halt the CPU again if
241 * necessary (TCG).
242 */
243 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
244 do_restart_interrupt(&cpu->env);
245 break;
246 case S390_CPU_STATE_OPERATING:
247 cpu_inject_restart(cpu);
248 break;
249 }
250 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
251 }
252
sigp_initial_cpu_reset(CPUState * cs,run_on_cpu_data arg)253 static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
254 {
255 SigpInfo *si = arg.host_ptr;
256
257 cpu_synchronize_state(cs);
258 resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_INITIAL);
259 cpu_synchronize_post_reset(cs);
260 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
261 }
262
sigp_cpu_reset(CPUState * cs,run_on_cpu_data arg)263 static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
264 {
265 SigpInfo *si = arg.host_ptr;
266
267 cpu_synchronize_state(cs);
268 resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_NORMAL);
269 cpu_synchronize_post_reset(cs);
270 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
271 }
272
sigp_set_prefix(CPUState * cs,run_on_cpu_data arg)273 static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
274 {
275 S390CPU *cpu = S390_CPU(cs);
276 SigpInfo *si = arg.host_ptr;
277 uint32_t addr = si->param & 0x7fffe000u;
278
279 cpu_synchronize_state(cs);
280
281 if (!address_space_access_valid(&address_space_memory, addr,
282 sizeof(struct LowCore), false,
283 MEMTXATTRS_UNSPECIFIED)) {
284 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
285 return;
286 }
287
288 /* cpu has to be stopped */
289 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) {
290 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
291 return;
292 }
293
294 cpu->env.psa = addr;
295 tlb_flush(cs);
296 cpu_synchronize_post_init(cs);
297 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
298 }
299
sigp_cond_emergency(S390CPU * src_cpu,S390CPU * dst_cpu,SigpInfo * si)300 static void sigp_cond_emergency(S390CPU *src_cpu, S390CPU *dst_cpu,
301 SigpInfo *si)
302 {
303 const uint64_t psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
304 uint16_t p_asn, s_asn, asn;
305 uint64_t psw_addr, psw_mask;
306 bool idle;
307
308 if (!tcg_enabled()) {
309 /* handled in KVM */
310 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
311 return;
312 }
313
314 /* this looks racy, but these values are only used when STOPPED */
315 idle = CPU(dst_cpu)->halted;
316 psw_addr = dst_cpu->env.psw.addr;
317 psw_mask = dst_cpu->env.psw.mask;
318 asn = si->param;
319 p_asn = dst_cpu->env.cregs[4] & 0xffff; /* Primary ASN */
320 s_asn = dst_cpu->env.cregs[3] & 0xffff; /* Secondary ASN */
321
322 if (s390_cpu_get_state(dst_cpu) != S390_CPU_STATE_STOPPED ||
323 (psw_mask & psw_int_mask) != psw_int_mask ||
324 (idle && psw_addr != 0) ||
325 (!idle && (asn == p_asn || asn == s_asn))) {
326 cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id);
327 } else {
328 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE);
329 }
330
331 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
332 }
333
sigp_sense_running(S390CPU * dst_cpu,SigpInfo * si)334 static void sigp_sense_running(S390CPU *dst_cpu, SigpInfo *si)
335 {
336 if (!tcg_enabled()) {
337 /* handled in KVM */
338 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
339 return;
340 }
341
342 /* sensing without locks is racy, but it's the same for real hw */
343 if (!s390_has_feat(S390_FEAT_SENSE_RUNNING_STATUS)) {
344 set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
345 return;
346 }
347
348 /* If halted (which includes also STOPPED), it is not running */
349 if (CPU(dst_cpu)->halted) {
350 set_sigp_status(si, SIGP_STAT_NOT_RUNNING);
351 } else {
352 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
353 }
354 }
355
handle_sigp_single_dst(S390CPU * cpu,S390CPU * dst_cpu,uint8_t order,uint64_t param,uint64_t * status_reg)356 static int handle_sigp_single_dst(S390CPU *cpu, S390CPU *dst_cpu, uint8_t order,
357 uint64_t param, uint64_t *status_reg)
358 {
359 SigpInfo si = {
360 .param = param,
361 .status_reg = status_reg,
362 };
363
364 /* cpu available? */
365 if (dst_cpu == NULL) {
366 return SIGP_CC_NOT_OPERATIONAL;
367 }
368
369 /* only resets can break pending orders */
370 if (dst_cpu->env.sigp_order != 0 &&
371 order != SIGP_CPU_RESET &&
372 order != SIGP_INITIAL_CPU_RESET) {
373 return SIGP_CC_BUSY;
374 }
375
376 switch (order) {
377 case SIGP_SENSE:
378 sigp_sense(dst_cpu, &si);
379 break;
380 case SIGP_EXTERNAL_CALL:
381 sigp_external_call(cpu, dst_cpu, &si);
382 break;
383 case SIGP_EMERGENCY:
384 sigp_emergency(cpu, dst_cpu, &si);
385 break;
386 case SIGP_START:
387 run_on_cpu(CPU(dst_cpu), sigp_start, RUN_ON_CPU_HOST_PTR(&si));
388 break;
389 case SIGP_STOP:
390 run_on_cpu(CPU(dst_cpu), sigp_stop, RUN_ON_CPU_HOST_PTR(&si));
391 break;
392 case SIGP_RESTART:
393 run_on_cpu(CPU(dst_cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si));
394 break;
395 case SIGP_STOP_STORE_STATUS:
396 run_on_cpu(CPU(dst_cpu), sigp_stop_and_store_status, RUN_ON_CPU_HOST_PTR(&si));
397 break;
398 case SIGP_STORE_STATUS_ADDR:
399 run_on_cpu(CPU(dst_cpu), sigp_store_status_at_address, RUN_ON_CPU_HOST_PTR(&si));
400 break;
401 case SIGP_STORE_ADTL_STATUS:
402 run_on_cpu(CPU(dst_cpu), sigp_store_adtl_status, RUN_ON_CPU_HOST_PTR(&si));
403 break;
404 case SIGP_SET_PREFIX:
405 run_on_cpu(CPU(dst_cpu), sigp_set_prefix, RUN_ON_CPU_HOST_PTR(&si));
406 break;
407 case SIGP_INITIAL_CPU_RESET:
408 run_on_cpu(CPU(dst_cpu), sigp_initial_cpu_reset, RUN_ON_CPU_HOST_PTR(&si));
409 break;
410 case SIGP_CPU_RESET:
411 run_on_cpu(CPU(dst_cpu), sigp_cpu_reset, RUN_ON_CPU_HOST_PTR(&si));
412 break;
413 case SIGP_COND_EMERGENCY:
414 sigp_cond_emergency(cpu, dst_cpu, &si);
415 break;
416 case SIGP_SENSE_RUNNING:
417 sigp_sense_running(dst_cpu, &si);
418 break;
419 default:
420 set_sigp_status(&si, SIGP_STAT_INVALID_ORDER);
421 }
422
423 return si.cc;
424 }
425
sigp_set_architecture(S390CPU * cpu,uint32_t param,uint64_t * status_reg)426 static int sigp_set_architecture(S390CPU *cpu, uint32_t param,
427 uint64_t *status_reg)
428 {
429 *status_reg &= 0xffffffff00000000ULL;
430
431 /* Reject set arch order, with czam we're always in z/Arch mode. */
432 *status_reg |= SIGP_STAT_INVALID_PARAMETER;
433 return SIGP_CC_STATUS_STORED;
434 }
435
s390_cpu_addr2state(uint16_t cpu_addr)436 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
437 {
438 static MachineState *ms;
439
440 if (!ms) {
441 ms = MACHINE(qdev_get_machine());
442 g_assert(ms->possible_cpus);
443 }
444
445 /* CPU address corresponds to the core_id and the index */
446 if (cpu_addr >= ms->possible_cpus->len) {
447 return NULL;
448 }
449 return S390_CPU(ms->possible_cpus->cpus[cpu_addr].cpu);
450 }
451
handle_sigp(CPUS390XState * env,uint8_t order,uint64_t r1,uint64_t r3)452 int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3)
453 {
454 uint64_t *status_reg = &env->regs[r1];
455 uint64_t param = (r1 % 2) ? env->regs[r1] : env->regs[r1 + 1];
456 S390CPU *cpu = env_archcpu(env);
457 S390CPU *dst_cpu = NULL;
458 int ret;
459
460 if (qemu_mutex_trylock(&qemu_sigp_mutex)) {
461 ret = SIGP_CC_BUSY;
462 goto out;
463 }
464
465 switch (order) {
466 case SIGP_SET_ARCH:
467 ret = sigp_set_architecture(cpu, param, status_reg);
468 break;
469 default:
470 /* all other sigp orders target a single vcpu */
471 dst_cpu = s390_cpu_addr2state(env->regs[r3]);
472 ret = handle_sigp_single_dst(cpu, dst_cpu, order, param, status_reg);
473 }
474 qemu_mutex_unlock(&qemu_sigp_mutex);
475
476 out:
477 trace_sigp_finished(order, CPU(cpu)->cpu_index,
478 dst_cpu ? CPU(dst_cpu)->cpu_index : -1, ret);
479 g_assert(ret >= 0);
480
481 return ret;
482 }
483
s390_cpu_restart(S390CPU * cpu)484 int s390_cpu_restart(S390CPU *cpu)
485 {
486 SigpInfo si = {};
487
488 run_on_cpu(CPU(cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si));
489 return 0;
490 }
491
do_stop_interrupt(CPUS390XState * env)492 void do_stop_interrupt(CPUS390XState *env)
493 {
494 S390CPU *cpu = env_archcpu(env);
495
496 /*
497 * Complete the STOP operation before exposing the CPU as
498 * STOPPED to the system.
499 */
500 if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
501 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
502 }
503 env->sigp_order = 0;
504 if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
505 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
506 }
507 env->pending_int &= ~INTERRUPT_STOP;
508 }
509
s390_init_sigp(void)510 void s390_init_sigp(void)
511 {
512 qemu_mutex_init(&qemu_sigp_mutex);
513 }
514