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