xref: /openbmc/qemu/linux-user/sparc/signal.c (revision f8ea624e7456b10bee8e82b788885a438af8084d)
1 /*
2  *  Emulation of Linux signals
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include "qemu/osdep.h"
20 #include "qemu.h"
21 #include "signal-common.h"
22 #include "linux-user/trace.h"
23 
24 /* A Sparc register window */
25 struct target_reg_window {
26     abi_ulong locals[8];
27     abi_ulong ins[8];
28 };
29 
30 /* A Sparc stack frame. */
31 struct target_stackf {
32     /*
33      * Since qemu does not reference fp or callers_pc directly,
34      * it's simpler to treat fp and callers_pc as elements of ins[],
35      * and then bundle locals[] and ins[] into reg_window.
36      */
37     struct target_reg_window win;
38     /*
39      * Similarly, bundle structptr and xxargs into xargs[].
40      * This portion of the struct is part of the function call abi,
41      * and belongs to the callee for spilling argument registers.
42      */
43     abi_ulong xargs[8];
44 };
45 
46 typedef struct {
47     struct {
48         abi_ulong psr;
49         abi_ulong pc;
50         abi_ulong npc;
51         abi_ulong y;
52         abi_ulong u_regs[16]; /* globals and ins */
53     }               si_regs;
54     int             si_mask;
55 } __siginfo_t;
56 
57 typedef struct {
58     abi_ulong  si_float_regs[32];
59     unsigned   long si_fsr;
60     unsigned   long si_fpqdepth;
61     struct {
62         unsigned long *insn_addr;
63         unsigned long insn;
64     } si_fpqueue [16];
65 } qemu_siginfo_fpu_t;
66 
67 
68 struct target_signal_frame {
69     struct target_stackf ss;
70     __siginfo_t         info;
71     abi_ulong           fpu_save;
72     uint32_t            insns[2] QEMU_ALIGNED(8);
73     abi_ulong           extramask[TARGET_NSIG_WORDS - 1];
74     abi_ulong           extra_size; /* Should be 0 */
75     qemu_siginfo_fpu_t fpu_state;
76 };
77 
78 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
79                                      CPUSPARCState *env,
80                                      unsigned long framesize)
81 {
82     abi_ulong sp = get_sp_from_cpustate(env);
83 
84     /*
85      * If we are on the alternate signal stack and would overflow it, don't.
86      * Return an always-bogus address instead so we will die with SIGSEGV.
87          */
88     if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) {
89             return -1;
90     }
91 
92     /* This is the X/Open sanctioned signal stack switching.  */
93     sp = target_sigsp(sp, sa) - framesize;
94 
95     /* Always align the stack frame.  This handles two cases.  First,
96      * sigaltstack need not be mindful of platform specific stack
97      * alignment.  Second, if we took this signal because the stack
98      * is not aligned properly, we'd like to take the signal cleanly
99      * and report that.
100      */
101     sp &= ~15UL;
102 
103     return sp;
104 }
105 
106 static int
107 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
108 {
109     int err = 0, i;
110 
111     __put_user(env->psr, &si->si_regs.psr);
112     __put_user(env->pc, &si->si_regs.pc);
113     __put_user(env->npc, &si->si_regs.npc);
114     __put_user(env->y, &si->si_regs.y);
115     for (i=0; i < 8; i++) {
116         __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
117     }
118     for (i=0; i < 8; i++) {
119         __put_user(env->regwptr[WREG_O0 + i], &si->si_regs.u_regs[i + 8]);
120     }
121     __put_user(mask, &si->si_mask);
122     return err;
123 }
124 
125 #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
126 
127 void setup_frame(int sig, struct target_sigaction *ka,
128                  target_sigset_t *set, CPUSPARCState *env)
129 {
130     abi_ulong sf_addr;
131     struct target_signal_frame *sf;
132     int sigframe_size, err, i;
133 
134     /* 1. Make sure everything is clean */
135     //synchronize_user_stack();
136 
137     sigframe_size = NF_ALIGNEDSZ;
138     sf_addr = get_sigframe(ka, env, sigframe_size);
139     trace_user_setup_frame(env, sf_addr);
140 
141     sf = lock_user(VERIFY_WRITE, sf_addr,
142                    sizeof(struct target_signal_frame), 0);
143     if (!sf) {
144         goto sigsegv;
145     }
146 #if 0
147     if (invalid_frame_pointer(sf, sigframe_size))
148         goto sigill_and_return;
149 #endif
150     /* 2. Save the current process state */
151     err = setup___siginfo(&sf->info, env, set->sig[0]);
152     __put_user(0, &sf->extra_size);
153 
154     //save_fpu_state(regs, &sf->fpu_state);
155     //__put_user(&sf->fpu_state, &sf->fpu_save);
156 
157     __put_user(set->sig[0], &sf->info.si_mask);
158     for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
159         __put_user(set->sig[i + 1], &sf->extramask[i]);
160     }
161 
162     for (i = 0; i < 8; i++) {
163         __put_user(env->regwptr[i + WREG_L0], &sf->ss.win.locals[i]);
164     }
165     for (i = 0; i < 8; i++) {
166         __put_user(env->regwptr[i + WREG_I0], &sf->ss.win.ins[i]);
167     }
168     if (err)
169         goto sigsegv;
170 
171     /* 3. signal handler back-trampoline and parameters */
172     env->regwptr[WREG_SP] = sf_addr;
173     env->regwptr[WREG_O0] = sig;
174     env->regwptr[WREG_O1] = sf_addr +
175             offsetof(struct target_signal_frame, info);
176     env->regwptr[WREG_O2] = sf_addr +
177             offsetof(struct target_signal_frame, info);
178 
179     /* 4. signal handler */
180     env->pc = ka->_sa_handler;
181     env->npc = (env->pc + 4);
182     /* 5. return to kernel instructions */
183     if (ka->ka_restorer) {
184         env->regwptr[WREG_O7] = ka->ka_restorer;
185     } else {
186         uint32_t val32;
187 
188         env->regwptr[WREG_O7] = sf_addr +
189                 offsetof(struct target_signal_frame, insns) - 2 * 4;
190 
191         /* mov __NR_sigreturn, %g1 */
192         val32 = 0x821020d8;
193         __put_user(val32, &sf->insns[0]);
194 
195         /* t 0x10 */
196         val32 = 0x91d02010;
197         __put_user(val32, &sf->insns[1]);
198     }
199     unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
200     return;
201 #if 0
202 sigill_and_return:
203     force_sig(TARGET_SIGILL);
204 #endif
205 sigsegv:
206     unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
207     force_sigsegv(sig);
208 }
209 
210 void setup_rt_frame(int sig, struct target_sigaction *ka,
211                     target_siginfo_t *info,
212                     target_sigset_t *set, CPUSPARCState *env)
213 {
214     qemu_log_mask(LOG_UNIMP, "setup_rt_frame: not implemented\n");
215 }
216 
217 long do_sigreturn(CPUSPARCState *env)
218 {
219     abi_ulong sf_addr;
220     struct target_signal_frame *sf;
221     abi_ulong up_psr, pc, npc;
222     target_sigset_t set;
223     sigset_t host_set;
224     int i;
225 
226     sf_addr = env->regwptr[WREG_SP];
227     trace_user_do_sigreturn(env, sf_addr);
228     if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
229         goto segv_and_exit;
230     }
231 
232     /* 1. Make sure we are not getting garbage from the user */
233 
234     if (sf_addr & 3)
235         goto segv_and_exit;
236 
237     __get_user(pc,  &sf->info.si_regs.pc);
238     __get_user(npc, &sf->info.si_regs.npc);
239 
240     if ((pc | npc) & 3) {
241         goto segv_and_exit;
242     }
243 
244     /* 2. Restore the state */
245     __get_user(up_psr, &sf->info.si_regs.psr);
246 
247     /* User can only change condition codes and FPU enabling in %psr. */
248     env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
249             | (env->psr & ~(PSR_ICC /* | PSR_EF */));
250 
251     env->pc = pc;
252     env->npc = npc;
253     __get_user(env->y, &sf->info.si_regs.y);
254     for (i=0; i < 8; i++) {
255         __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
256     }
257     for (i=0; i < 8; i++) {
258         __get_user(env->regwptr[i + WREG_O0], &sf->info.si_regs.u_regs[i + 8]);
259     }
260 
261     /* FIXME: implement FPU save/restore:
262      * __get_user(fpu_save, &sf->fpu_save);
263      * if (fpu_save) {
264      *     if (restore_fpu_state(env, fpu_save)) {
265      *         goto segv_and_exit;
266      *     }
267      * }
268      */
269 
270     /* This is pretty much atomic, no amount locking would prevent
271          * the races which exist anyways.
272          */
273     __get_user(set.sig[0], &sf->info.si_mask);
274     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
275         __get_user(set.sig[i], &sf->extramask[i - 1]);
276     }
277 
278     target_to_host_sigset_internal(&host_set, &set);
279     set_sigmask(&host_set);
280 
281     unlock_user_struct(sf, sf_addr, 0);
282     return -TARGET_QEMU_ESIGRETURN;
283 
284 segv_and_exit:
285     unlock_user_struct(sf, sf_addr, 0);
286     force_sig(TARGET_SIGSEGV);
287     return -TARGET_QEMU_ESIGRETURN;
288 }
289 
290 long do_rt_sigreturn(CPUSPARCState *env)
291 {
292     trace_user_do_rt_sigreturn(env, 0);
293     qemu_log_mask(LOG_UNIMP, "do_rt_sigreturn: not implemented\n");
294     return -TARGET_ENOSYS;
295 }
296 
297 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
298 #define SPARC_MC_TSTATE 0
299 #define SPARC_MC_PC 1
300 #define SPARC_MC_NPC 2
301 #define SPARC_MC_Y 3
302 #define SPARC_MC_G1 4
303 #define SPARC_MC_G2 5
304 #define SPARC_MC_G3 6
305 #define SPARC_MC_G4 7
306 #define SPARC_MC_G5 8
307 #define SPARC_MC_G6 9
308 #define SPARC_MC_G7 10
309 #define SPARC_MC_O0 11
310 #define SPARC_MC_O1 12
311 #define SPARC_MC_O2 13
312 #define SPARC_MC_O3 14
313 #define SPARC_MC_O4 15
314 #define SPARC_MC_O5 16
315 #define SPARC_MC_O6 17
316 #define SPARC_MC_O7 18
317 #define SPARC_MC_NGREG 19
318 
319 typedef abi_ulong target_mc_greg_t;
320 typedef target_mc_greg_t target_mc_gregset_t[SPARC_MC_NGREG];
321 
322 struct target_mc_fq {
323     abi_ulong mcfq_addr;
324     uint32_t mcfq_insn;
325 };
326 
327 /*
328  * Note the manual 16-alignment; the kernel gets this because it
329  * includes a "long double qregs[16]" in the mcpu_fregs union,
330  * which we can't do.
331  */
332 struct target_mc_fpu {
333     union {
334         uint32_t sregs[32];
335         uint64_t dregs[32];
336         //uint128_t qregs[16];
337     } mcfpu_fregs;
338     abi_ulong mcfpu_fsr;
339     abi_ulong mcfpu_fprs;
340     abi_ulong mcfpu_gsr;
341     abi_ulong mcfpu_fq;
342     unsigned char mcfpu_qcnt;
343     unsigned char mcfpu_qentsz;
344     unsigned char mcfpu_enab;
345 } __attribute__((aligned(16)));
346 typedef struct target_mc_fpu target_mc_fpu_t;
347 
348 typedef struct {
349     target_mc_gregset_t mc_gregs;
350     target_mc_greg_t mc_fp;
351     target_mc_greg_t mc_i7;
352     target_mc_fpu_t mc_fpregs;
353 } target_mcontext_t;
354 
355 struct target_ucontext {
356     abi_ulong tuc_link;
357     abi_ulong tuc_flags;
358     target_sigset_t tuc_sigmask;
359     target_mcontext_t tuc_mcontext;
360 };
361 
362 /* {set, get}context() needed for 64-bit SparcLinux userland. */
363 void sparc64_set_context(CPUSPARCState *env)
364 {
365     abi_ulong ucp_addr;
366     struct target_ucontext *ucp;
367     target_mc_gregset_t *grp;
368     target_mc_fpu_t *fpup;
369     abi_ulong pc, npc, tstate;
370     unsigned int i;
371     unsigned char fenab;
372 
373     ucp_addr = env->regwptr[WREG_O0];
374     if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
375         goto do_sigsegv;
376     }
377     grp  = &ucp->tuc_mcontext.mc_gregs;
378     __get_user(pc, &((*grp)[SPARC_MC_PC]));
379     __get_user(npc, &((*grp)[SPARC_MC_NPC]));
380     if ((pc | npc) & 3) {
381         goto do_sigsegv;
382     }
383     if (env->regwptr[WREG_O1]) {
384         target_sigset_t target_set;
385         sigset_t set;
386 
387         if (TARGET_NSIG_WORDS == 1) {
388             __get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]);
389         } else {
390             abi_ulong *src, *dst;
391             src = ucp->tuc_sigmask.sig;
392             dst = target_set.sig;
393             for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
394                 __get_user(*dst, src);
395             }
396         }
397         target_to_host_sigset_internal(&set, &target_set);
398         set_sigmask(&set);
399     }
400     env->pc = pc;
401     env->npc = npc;
402     __get_user(env->y, &((*grp)[SPARC_MC_Y]));
403     __get_user(tstate, &((*grp)[SPARC_MC_TSTATE]));
404     /* Honour TSTATE_ASI, TSTATE_ICC and TSTATE_XCC only */
405     env->asi = (tstate >> 24) & 0xff;
406     cpu_put_ccr(env, (tstate >> 32) & 0xff);
407     __get_user(env->gregs[1], (&(*grp)[SPARC_MC_G1]));
408     __get_user(env->gregs[2], (&(*grp)[SPARC_MC_G2]));
409     __get_user(env->gregs[3], (&(*grp)[SPARC_MC_G3]));
410     __get_user(env->gregs[4], (&(*grp)[SPARC_MC_G4]));
411     __get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
412     __get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
413     /* Skip g7 as that's the thread register in userspace */
414 
415     /*
416      * Note that unlike the kernel, we didn't need to mess with the
417      * guest register window state to save it into a pt_regs to run
418      * the kernel. So for us the guest's O regs are still in WREG_O*
419      * (unlike the kernel which has put them in UREG_I* in a pt_regs)
420      * and the fp and i7 are still in WREG_I6 and WREG_I7 and don't
421      * need to be written back to userspace memory.
422      */
423     __get_user(env->regwptr[WREG_O0], (&(*grp)[SPARC_MC_O0]));
424     __get_user(env->regwptr[WREG_O1], (&(*grp)[SPARC_MC_O1]));
425     __get_user(env->regwptr[WREG_O2], (&(*grp)[SPARC_MC_O2]));
426     __get_user(env->regwptr[WREG_O3], (&(*grp)[SPARC_MC_O3]));
427     __get_user(env->regwptr[WREG_O4], (&(*grp)[SPARC_MC_O4]));
428     __get_user(env->regwptr[WREG_O5], (&(*grp)[SPARC_MC_O5]));
429     __get_user(env->regwptr[WREG_O6], (&(*grp)[SPARC_MC_O6]));
430     __get_user(env->regwptr[WREG_O7], (&(*grp)[SPARC_MC_O7]));
431 
432     __get_user(env->regwptr[WREG_FP], &(ucp->tuc_mcontext.mc_fp));
433     __get_user(env->regwptr[WREG_I7], &(ucp->tuc_mcontext.mc_i7));
434 
435     fpup = &ucp->tuc_mcontext.mc_fpregs;
436 
437     __get_user(fenab, &(fpup->mcfpu_enab));
438     if (fenab) {
439         abi_ulong fprs;
440 
441         /*
442          * We use the FPRS from the guest only in deciding whether
443          * to restore the upper, lower, or both banks of the FPU regs.
444          * The kernel here writes the FPU register data into the
445          * process's current_thread_info state and unconditionally
446          * clears FPRS and TSTATE_PEF: this disables the FPU so that the
447          * next FPU-disabled trap will copy the data out of
448          * current_thread_info and into the real FPU registers.
449          * QEMU doesn't need to handle lazy-FPU-state-restoring like that,
450          * so we always load the data directly into the FPU registers
451          * and leave FPRS and TSTATE_PEF alone (so the FPU stays enabled).
452          * Note that because we (and the kernel) always write zeroes for
453          * the fenab and fprs in sparc64_get_context() none of this code
454          * will execute unless the guest manually constructed or changed
455          * the context structure.
456          */
457         __get_user(fprs, &(fpup->mcfpu_fprs));
458         if (fprs & FPRS_DL) {
459             for (i = 0; i < 16; i++) {
460                 __get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
461             }
462         }
463         if (fprs & FPRS_DU) {
464             for (i = 16; i < 32; i++) {
465                 __get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
466             }
467         }
468         __get_user(env->fsr, &(fpup->mcfpu_fsr));
469         __get_user(env->gsr, &(fpup->mcfpu_gsr));
470     }
471     unlock_user_struct(ucp, ucp_addr, 0);
472     return;
473 do_sigsegv:
474     unlock_user_struct(ucp, ucp_addr, 0);
475     force_sig(TARGET_SIGSEGV);
476 }
477 
478 void sparc64_get_context(CPUSPARCState *env)
479 {
480     abi_ulong ucp_addr;
481     struct target_ucontext *ucp;
482     target_mc_gregset_t *grp;
483     target_mcontext_t *mcp;
484     int err;
485     unsigned int i;
486     target_sigset_t target_set;
487     sigset_t set;
488 
489     ucp_addr = env->regwptr[WREG_O0];
490     if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) {
491         goto do_sigsegv;
492     }
493 
494     memset(ucp, 0, sizeof(*ucp));
495 
496     mcp = &ucp->tuc_mcontext;
497     grp = &mcp->mc_gregs;
498 
499     /* Skip over the trap instruction, first. */
500     env->pc = env->npc;
501     env->npc += 4;
502 
503     /* If we're only reading the signal mask then do_sigprocmask()
504      * is guaranteed not to fail, which is important because we don't
505      * have any way to signal a failure or restart this operation since
506      * this is not a normal syscall.
507      */
508     err = do_sigprocmask(0, NULL, &set);
509     assert(err == 0);
510     host_to_target_sigset_internal(&target_set, &set);
511     if (TARGET_NSIG_WORDS == 1) {
512         __put_user(target_set.sig[0],
513                    (abi_ulong *)&ucp->tuc_sigmask);
514     } else {
515         abi_ulong *src, *dst;
516         src = target_set.sig;
517         dst = ucp->tuc_sigmask.sig;
518         for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
519             __put_user(*src, dst);
520         }
521     }
522 
523     __put_user(sparc64_tstate(env), &((*grp)[SPARC_MC_TSTATE]));
524     __put_user(env->pc, &((*grp)[SPARC_MC_PC]));
525     __put_user(env->npc, &((*grp)[SPARC_MC_NPC]));
526     __put_user(env->y, &((*grp)[SPARC_MC_Y]));
527     __put_user(env->gregs[1], &((*grp)[SPARC_MC_G1]));
528     __put_user(env->gregs[2], &((*grp)[SPARC_MC_G2]));
529     __put_user(env->gregs[3], &((*grp)[SPARC_MC_G3]));
530     __put_user(env->gregs[4], &((*grp)[SPARC_MC_G4]));
531     __put_user(env->gregs[5], &((*grp)[SPARC_MC_G5]));
532     __put_user(env->gregs[6], &((*grp)[SPARC_MC_G6]));
533     __put_user(env->gregs[7], &((*grp)[SPARC_MC_G7]));
534 
535     /*
536      * Note that unlike the kernel, we didn't need to mess with the
537      * guest register window state to save it into a pt_regs to run
538      * the kernel. So for us the guest's O regs are still in WREG_O*
539      * (unlike the kernel which has put them in UREG_I* in a pt_regs)
540      * and the fp and i7 are still in WREG_I6 and WREG_I7 and don't
541      * need to be fished out of userspace memory.
542      */
543     __put_user(env->regwptr[WREG_O0], &((*grp)[SPARC_MC_O0]));
544     __put_user(env->regwptr[WREG_O1], &((*grp)[SPARC_MC_O1]));
545     __put_user(env->regwptr[WREG_O2], &((*grp)[SPARC_MC_O2]));
546     __put_user(env->regwptr[WREG_O3], &((*grp)[SPARC_MC_O3]));
547     __put_user(env->regwptr[WREG_O4], &((*grp)[SPARC_MC_O4]));
548     __put_user(env->regwptr[WREG_O5], &((*grp)[SPARC_MC_O5]));
549     __put_user(env->regwptr[WREG_O6], &((*grp)[SPARC_MC_O6]));
550     __put_user(env->regwptr[WREG_O7], &((*grp)[SPARC_MC_O7]));
551 
552     __put_user(env->regwptr[WREG_FP], &(mcp->mc_fp));
553     __put_user(env->regwptr[WREG_I7], &(mcp->mc_i7));
554 
555     /*
556      * We don't write out the FPU state. This matches the kernel's
557      * implementation (which has the code for doing this but
558      * hidden behind an "if (fenab)" where fenab is always 0).
559      */
560 
561     unlock_user_struct(ucp, ucp_addr, 1);
562     return;
563 do_sigsegv:
564     unlock_user_struct(ucp, ucp_addr, 1);
565     force_sig(TARGET_SIGSEGV);
566 }
567 #endif
568