xref: /qemu/target/s390x/sigp.c (revision 6ff5da16000f908140723e164d33a0b51a6c4162)
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 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
510 void s390_init_sigp(void)
511 {
512     qemu_mutex_init(&qemu_sigp_mutex);
513 }
514