[MIPS] Check FCSR for pending interrupts, alternative version
[safe/jmp/linux-2.6] / arch / mips / kernel / signal32.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1991, 1992  Linus Torvalds
7  * Copyright (C) 1994 - 2000, 2006  Ralf Baechle
8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9  */
10 #include <linux/cache.h>
11 #include <linux/compat.h>
12 #include <linux/sched.h>
13 #include <linux/mm.h>
14 #include <linux/smp.h>
15 #include <linux/smp_lock.h>
16 #include <linux/kernel.h>
17 #include <linux/signal.h>
18 #include <linux/syscalls.h>
19 #include <linux/errno.h>
20 #include <linux/wait.h>
21 #include <linux/ptrace.h>
22 #include <linux/compat.h>
23 #include <linux/suspend.h>
24 #include <linux/compiler.h>
25
26 #include <asm/abi.h>
27 #include <asm/asm.h>
28 #include <asm/compat-signal.h>
29 #include <linux/bitops.h>
30 #include <asm/cacheflush.h>
31 #include <asm/sim.h>
32 #include <asm/uaccess.h>
33 #include <asm/ucontext.h>
34 #include <asm/system.h>
35 #include <asm/fpu.h>
36 #include <asm/war.h>
37
38 #include "signal-common.h"
39
40 #define SI_PAD_SIZE32   ((SI_MAX_SIZE/sizeof(int)) - 3)
41
42 typedef struct compat_siginfo {
43         int si_signo;
44         int si_code;
45         int si_errno;
46
47         union {
48                 int _pad[SI_PAD_SIZE32];
49
50                 /* kill() */
51                 struct {
52                         compat_pid_t _pid;      /* sender's pid */
53                         compat_uid_t _uid;      /* sender's uid */
54                 } _kill;
55
56                 /* SIGCHLD */
57                 struct {
58                         compat_pid_t _pid;      /* which child */
59                         compat_uid_t _uid;      /* sender's uid */
60                         int _status;            /* exit code */
61                         compat_clock_t _utime;
62                         compat_clock_t _stime;
63                 } _sigchld;
64
65                 /* IRIX SIGCHLD */
66                 struct {
67                         compat_pid_t _pid;      /* which child */
68                         compat_clock_t _utime;
69                         int _status;            /* exit code */
70                         compat_clock_t _stime;
71                 } _irix_sigchld;
72
73                 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
74                 struct {
75                         s32 _addr; /* faulting insn/memory ref. */
76                 } _sigfault;
77
78                 /* SIGPOLL, SIGXFSZ (To do ...)  */
79                 struct {
80                         int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
81                         int _fd;
82                 } _sigpoll;
83
84                 /* POSIX.1b timers */
85                 struct {
86                         timer_t _tid;           /* timer id */
87                         int _overrun;           /* overrun count */
88                         compat_sigval_t _sigval;/* same as below */
89                         int _sys_private;       /* not to be passed to user */
90                 } _timer;
91
92                 /* POSIX.1b signals */
93                 struct {
94                         compat_pid_t _pid;      /* sender's pid */
95                         compat_uid_t _uid;      /* sender's uid */
96                         compat_sigval_t _sigval;
97                 } _rt;
98
99         } _sifields;
100 } compat_siginfo_t;
101
102 /*
103  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
104  */
105 #define __NR_O32_sigreturn              4119
106 #define __NR_O32_rt_sigreturn           4193
107 #define __NR_O32_restart_syscall        4253
108
109 /* 32-bit compatibility types */
110
111 typedef unsigned int __sighandler32_t;
112 typedef void (*vfptr_t)(void);
113
114 struct sigaction32 {
115         unsigned int            sa_flags;
116         __sighandler32_t        sa_handler;
117         compat_sigset_t         sa_mask;
118 };
119
120 /* IRIX compatible stack_t  */
121 typedef struct sigaltstack32 {
122         s32 ss_sp;
123         compat_size_t ss_size;
124         int ss_flags;
125 } stack32_t;
126
127 struct ucontext32 {
128         u32                 uc_flags;
129         s32                 uc_link;
130         stack32_t           uc_stack;
131         struct sigcontext32 uc_mcontext;
132         compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
133 };
134
135 /*
136  * Horribly complicated - with the bloody RM9000 workarounds enabled
137  * the signal trampolines is moving to the end of the structure so we can
138  * increase the alignment without breaking software compatibility.
139  */
140 #if ICACHE_REFILLS_WORKAROUND_WAR == 0
141
142 struct sigframe32 {
143         u32 sf_ass[4];          /* argument save space for o32 */
144         u32 sf_code[2];         /* signal trampoline */
145         struct sigcontext32 sf_sc;
146         compat_sigset_t sf_mask;
147 };
148
149 struct rt_sigframe32 {
150         u32 rs_ass[4];                  /* argument save space for o32 */
151         u32 rs_code[2];                 /* signal trampoline */
152         compat_siginfo_t rs_info;
153         struct ucontext32 rs_uc;
154 };
155
156 #else  /* ICACHE_REFILLS_WORKAROUND_WAR */
157
158 struct sigframe32 {
159         u32 sf_ass[4];                  /* argument save space for o32 */
160         u32 sf_pad[2];
161         struct sigcontext32 sf_sc;      /* hw context */
162         compat_sigset_t sf_mask;
163         u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
164 };
165
166 struct rt_sigframe32 {
167         u32 rs_ass[4];                  /* argument save space for o32 */
168         u32 rs_pad[2];
169         compat_siginfo_t rs_info;
170         struct ucontext32 rs_uc;
171         u32 rs_code[8] __attribute__((aligned(32)));    /* signal trampoline */
172 };
173
174 #endif  /* !ICACHE_REFILLS_WORKAROUND_WAR */
175
176 /*
177  * sigcontext handlers
178  */
179 static int setup_sigcontext32(struct pt_regs *regs,
180                               struct sigcontext32 __user *sc)
181 {
182         int err = 0;
183         int i;
184
185         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
186
187         err |= __put_user(0, &sc->sc_regs[0]);
188         for (i = 1; i < 32; i++)
189                 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
190
191         err |= __put_user(regs->hi, &sc->sc_mdhi);
192         err |= __put_user(regs->lo, &sc->sc_mdlo);
193         if (cpu_has_dsp) {
194                 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
195                 err |= __put_user(mfhi1(), &sc->sc_hi1);
196                 err |= __put_user(mflo1(), &sc->sc_lo1);
197                 err |= __put_user(mfhi2(), &sc->sc_hi2);
198                 err |= __put_user(mflo2(), &sc->sc_lo2);
199                 err |= __put_user(mfhi3(), &sc->sc_hi3);
200                 err |= __put_user(mflo3(), &sc->sc_lo3);
201         }
202
203         err |= __put_user(!!used_math(), &sc->sc_used_math);
204
205         if (used_math()) {
206                 /*
207                  * Save FPU state to signal context.  Signal handler
208                  * will "inherit" current FPU state.
209                  */
210                 preempt_disable();
211
212                 if (!is_fpu_owner()) {
213                         own_fpu();
214                         restore_fp(current);
215                 }
216                 err |= save_fp_context32(sc);
217
218                 preempt_enable();
219         }
220         return err;
221 }
222
223 static int
224 check_and_restore_fp_context32(struct sigcontext32 __user *sc)
225 {
226         int err, sig;
227
228         err = sig = fpcsr_pending(&sc->sc_fpc_csr);
229         if (err > 0)
230                 err = 0;
231         err |= restore_fp_context32(sc);
232         return err ?: sig;
233 }
234
235 static int restore_sigcontext32(struct pt_regs *regs,
236                                 struct sigcontext32 __user *sc)
237 {
238         u32 used_math;
239         int err = 0;
240         s32 treg;
241         int i;
242
243         /* Always make any pending restarted system calls return -EINTR */
244         current_thread_info()->restart_block.fn = do_no_restart_syscall;
245
246         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
247         err |= __get_user(regs->hi, &sc->sc_mdhi);
248         err |= __get_user(regs->lo, &sc->sc_mdlo);
249         if (cpu_has_dsp) {
250                 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
251                 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
252                 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
253                 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
254                 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
255                 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
256                 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
257         }
258
259         for (i = 1; i < 32; i++)
260                 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
261
262         err |= __get_user(used_math, &sc->sc_used_math);
263         conditional_used_math(used_math);
264
265         preempt_disable();
266
267         if (used_math()) {
268                 /* restore fpu context if we have used it before */
269                 own_fpu();
270                 if (!err)
271                         err = check_and_restore_fp_context32(sc);
272         } else {
273                 /* signal handler may have used FPU.  Give it up. */
274                 lose_fpu();
275         }
276
277         preempt_enable();
278
279         return err;
280 }
281
282 /*
283  *
284  */
285 extern void __put_sigset_unknown_nsig(void);
286 extern void __get_sigset_unknown_nsig(void);
287
288 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
289 {
290         int err = 0;
291
292         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
293                 return -EFAULT;
294
295         switch (_NSIG_WORDS) {
296         default:
297                 __put_sigset_unknown_nsig();
298         case 2:
299                 err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
300                 err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
301         case 1:
302                 err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
303                 err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
304         }
305
306         return err;
307 }
308
309 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
310 {
311         int err = 0;
312         unsigned long sig[4];
313
314         if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
315                 return -EFAULT;
316
317         switch (_NSIG_WORDS) {
318         default:
319                 __get_sigset_unknown_nsig();
320         case 2:
321                 err |= __get_user (sig[3], &ubuf->sig[3]);
322                 err |= __get_user (sig[2], &ubuf->sig[2]);
323                 kbuf->sig[1] = sig[2] | (sig[3] << 32);
324         case 1:
325                 err |= __get_user (sig[1], &ubuf->sig[1]);
326                 err |= __get_user (sig[0], &ubuf->sig[0]);
327                 kbuf->sig[0] = sig[0] | (sig[1] << 32);
328         }
329
330         return err;
331 }
332
333 /*
334  * Atomically swap in the new signal mask, and wait for a signal.
335  */
336
337 asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
338 {
339         compat_sigset_t __user *uset;
340         sigset_t newset;
341
342         uset = (compat_sigset_t __user *) regs.regs[4];
343         if (get_sigset(&newset, uset))
344                 return -EFAULT;
345         sigdelsetmask(&newset, ~_BLOCKABLE);
346
347         spin_lock_irq(&current->sighand->siglock);
348         current->saved_sigmask = current->blocked;
349         current->blocked = newset;
350         recalc_sigpending();
351         spin_unlock_irq(&current->sighand->siglock);
352
353         current->state = TASK_INTERRUPTIBLE;
354         schedule();
355         set_thread_flag(TIF_RESTORE_SIGMASK);
356         return -ERESTARTNOHAND;
357 }
358
359 asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
360 {
361         compat_sigset_t __user *uset;
362         sigset_t newset;
363         size_t sigsetsize;
364
365         /* XXX Don't preclude handling different sized sigset_t's.  */
366         sigsetsize = regs.regs[5];
367         if (sigsetsize != sizeof(compat_sigset_t))
368                 return -EINVAL;
369
370         uset = (compat_sigset_t __user *) regs.regs[4];
371         if (get_sigset(&newset, uset))
372                 return -EFAULT;
373         sigdelsetmask(&newset, ~_BLOCKABLE);
374
375         spin_lock_irq(&current->sighand->siglock);
376         current->saved_sigmask = current->blocked;
377         current->blocked = newset;
378         recalc_sigpending();
379         spin_unlock_irq(&current->sighand->siglock);
380
381         current->state = TASK_INTERRUPTIBLE;
382         schedule();
383         set_thread_flag(TIF_RESTORE_SIGMASK);
384         return -ERESTARTNOHAND;
385 }
386
387 asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act,
388                                struct sigaction32 __user *oact)
389 {
390         struct k_sigaction new_ka, old_ka;
391         int ret;
392         int err = 0;
393
394         if (act) {
395                 old_sigset_t mask;
396                 s32 handler;
397
398                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
399                         return -EFAULT;
400                 err |= __get_user(handler, &act->sa_handler);
401                 new_ka.sa.sa_handler = (void __user *)(s64)handler;
402                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
403                 err |= __get_user(mask, &act->sa_mask.sig[0]);
404                 if (err)
405                         return -EFAULT;
406
407                 siginitset(&new_ka.sa.sa_mask, mask);
408         }
409
410         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
411
412         if (!ret && oact) {
413                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
414                         return -EFAULT;
415                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
416                 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
417                                   &oact->sa_handler);
418                 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
419                 err |= __put_user(0, &oact->sa_mask.sig[1]);
420                 err |= __put_user(0, &oact->sa_mask.sig[2]);
421                 err |= __put_user(0, &oact->sa_mask.sig[3]);
422                 if (err)
423                         return -EFAULT;
424         }
425
426         return ret;
427 }
428
429 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
430 {
431         const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
432         stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
433         unsigned long usp = regs.regs[29];
434         stack_t kss, koss;
435         int ret, err = 0;
436         mm_segment_t old_fs = get_fs();
437         s32 sp;
438
439         if (uss) {
440                 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
441                         return -EFAULT;
442                 err |= __get_user(sp, &uss->ss_sp);
443                 kss.ss_sp = (void __user *) (long) sp;
444                 err |= __get_user(kss.ss_size, &uss->ss_size);
445                 err |= __get_user(kss.ss_flags, &uss->ss_flags);
446                 if (err)
447                         return -EFAULT;
448         }
449
450         set_fs (KERNEL_DS);
451         ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
452                              uoss ? (stack_t __user *)&koss : NULL, usp);
453         set_fs (old_fs);
454
455         if (!ret && uoss) {
456                 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
457                         return -EFAULT;
458                 sp = (int) (unsigned long) koss.ss_sp;
459                 err |= __put_user(sp, &uoss->ss_sp);
460                 err |= __put_user(koss.ss_size, &uoss->ss_size);
461                 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
462                 if (err)
463                         return -EFAULT;
464         }
465         return ret;
466 }
467
468 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
469 {
470         int err;
471
472         if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
473                 return -EFAULT;
474
475         /* If you change siginfo_t structure, please be sure
476            this code is fixed accordingly.
477            It should never copy any pad contained in the structure
478            to avoid security leaks, but must copy the generic
479            3 ints plus the relevant union member.
480            This routine must convert siginfo from 64bit to 32bit as well
481            at the same time.  */
482         err = __put_user(from->si_signo, &to->si_signo);
483         err |= __put_user(from->si_errno, &to->si_errno);
484         err |= __put_user((short)from->si_code, &to->si_code);
485         if (from->si_code < 0)
486                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
487         else {
488                 switch (from->si_code >> 16) {
489                 case __SI_TIMER >> 16:
490                         err |= __put_user(from->si_tid, &to->si_tid);
491                         err |= __put_user(from->si_overrun, &to->si_overrun);
492                         err |= __put_user(from->si_int, &to->si_int);
493                         break;
494                 case __SI_CHLD >> 16:
495                         err |= __put_user(from->si_utime, &to->si_utime);
496                         err |= __put_user(from->si_stime, &to->si_stime);
497                         err |= __put_user(from->si_status, &to->si_status);
498                 default:
499                         err |= __put_user(from->si_pid, &to->si_pid);
500                         err |= __put_user(from->si_uid, &to->si_uid);
501                         break;
502                 case __SI_FAULT >> 16:
503                         err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
504                         break;
505                 case __SI_POLL >> 16:
506                         err |= __put_user(from->si_band, &to->si_band);
507                         err |= __put_user(from->si_fd, &to->si_fd);
508                         break;
509                 case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
510                 case __SI_MESGQ >> 16:
511                         err |= __put_user(from->si_pid, &to->si_pid);
512                         err |= __put_user(from->si_uid, &to->si_uid);
513                         err |= __put_user(from->si_int, &to->si_int);
514                         break;
515                 }
516         }
517         return err;
518 }
519
520 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
521 {
522         struct sigframe32 __user *frame;
523         sigset_t blocked;
524         int sig;
525
526         frame = (struct sigframe32 __user *) regs.regs[29];
527         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
528                 goto badframe;
529         if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
530                 goto badframe;
531
532         sigdelsetmask(&blocked, ~_BLOCKABLE);
533         spin_lock_irq(&current->sighand->siglock);
534         current->blocked = blocked;
535         recalc_sigpending();
536         spin_unlock_irq(&current->sighand->siglock);
537
538         sig = restore_sigcontext32(&regs, &frame->sf_sc);
539         if (sig < 0)
540                 goto badframe;
541         else if (sig)
542                 force_sig(sig, current);
543
544         /*
545          * Don't let your children do this ...
546          */
547         __asm__ __volatile__(
548                 "move\t$29, %0\n\t"
549                 "j\tsyscall_exit"
550                 :/* no outputs */
551                 :"r" (&regs));
552         /* Unreached */
553
554 badframe:
555         force_sig(SIGSEGV, current);
556 }
557
558 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
559 {
560         struct rt_sigframe32 __user *frame;
561         mm_segment_t old_fs;
562         sigset_t set;
563         stack_t st;
564         s32 sp;
565         int sig;
566
567         frame = (struct rt_sigframe32 __user *) regs.regs[29];
568         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
569                 goto badframe;
570         if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
571                 goto badframe;
572
573         sigdelsetmask(&set, ~_BLOCKABLE);
574         spin_lock_irq(&current->sighand->siglock);
575         current->blocked = set;
576         recalc_sigpending();
577         spin_unlock_irq(&current->sighand->siglock);
578
579         sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
580         if (sig < 0)
581                 goto badframe;
582         else if (sig)
583                 force_sig(sig, current);
584
585         /* The ucontext contains a stack32_t, so we must convert!  */
586         if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
587                 goto badframe;
588         st.ss_sp = (void __user *)(long) sp;
589         if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
590                 goto badframe;
591         if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
592                 goto badframe;
593
594         /* It is more difficult to avoid calling this function than to
595            call it and ignore errors.  */
596         old_fs = get_fs();
597         set_fs (KERNEL_DS);
598         do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
599         set_fs (old_fs);
600
601         /*
602          * Don't let your children do this ...
603          */
604         __asm__ __volatile__(
605                 "move\t$29, %0\n\t"
606                 "j\tsyscall_exit"
607                 :/* no outputs */
608                 :"r" (&regs));
609         /* Unreached */
610
611 badframe:
612         force_sig(SIGSEGV, current);
613 }
614
615 static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
616         int signr, sigset_t *set)
617 {
618         struct sigframe32 __user *frame;
619         int err = 0;
620
621         frame = get_sigframe(ka, regs, sizeof(*frame));
622         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
623                 goto give_sigsegv;
624
625         err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
626
627         err |= setup_sigcontext32(regs, &frame->sf_sc);
628         err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
629
630         if (err)
631                 goto give_sigsegv;
632
633         /*
634          * Arguments to signal handler:
635          *
636          *   a0 = signal number
637          *   a1 = 0 (should be cause)
638          *   a2 = pointer to struct sigcontext
639          *
640          * $25 and c0_epc point to the signal handler, $29 points to the
641          * struct sigframe.
642          */
643         regs->regs[ 4] = signr;
644         regs->regs[ 5] = 0;
645         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
646         regs->regs[29] = (unsigned long) frame;
647         regs->regs[31] = (unsigned long) frame->sf_code;
648         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
649
650         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
651                current->comm, current->pid,
652                frame, regs->cp0_epc, regs->regs[31]);
653
654         return 0;
655
656 give_sigsegv:
657         force_sigsegv(signr, current);
658         return -EFAULT;
659 }
660
661 static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
662         int signr, sigset_t *set, siginfo_t *info)
663 {
664         struct rt_sigframe32 __user *frame;
665         int err = 0;
666         s32 sp;
667
668         frame = get_sigframe(ka, regs, sizeof(*frame));
669         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
670                 goto give_sigsegv;
671
672         err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
673
674         /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
675         err |= copy_siginfo_to_user32(&frame->rs_info, info);
676
677         /* Create the ucontext.  */
678         err |= __put_user(0, &frame->rs_uc.uc_flags);
679         err |= __put_user(0, &frame->rs_uc.uc_link);
680         sp = (int) (long) current->sas_ss_sp;
681         err |= __put_user(sp,
682                           &frame->rs_uc.uc_stack.ss_sp);
683         err |= __put_user(sas_ss_flags(regs->regs[29]),
684                           &frame->rs_uc.uc_stack.ss_flags);
685         err |= __put_user(current->sas_ss_size,
686                           &frame->rs_uc.uc_stack.ss_size);
687         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
688         err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
689
690         if (err)
691                 goto give_sigsegv;
692
693         /*
694          * Arguments to signal handler:
695          *
696          *   a0 = signal number
697          *   a1 = 0 (should be cause)
698          *   a2 = pointer to ucontext
699          *
700          * $25 and c0_epc point to the signal handler, $29 points to
701          * the struct rt_sigframe32.
702          */
703         regs->regs[ 4] = signr;
704         regs->regs[ 5] = (unsigned long) &frame->rs_info;
705         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
706         regs->regs[29] = (unsigned long) frame;
707         regs->regs[31] = (unsigned long) frame->rs_code;
708         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
709
710         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
711                current->comm, current->pid,
712                frame, regs->cp0_epc, regs->regs[31]);
713
714         return 0;
715
716 give_sigsegv:
717         force_sigsegv(signr, current);
718         return -EFAULT;
719 }
720
721 /*
722  * o32 compatibility on 64-bit kernels, without DSP ASE
723  */
724 struct mips_abi mips_abi_32 = {
725         .setup_frame    = setup_frame_32,
726         .setup_rt_frame = setup_rt_frame_32,
727         .restart        = __NR_O32_restart_syscall
728 };
729
730 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
731                                   struct sigaction32 __user *oact,
732                                   unsigned int sigsetsize)
733 {
734         struct k_sigaction new_sa, old_sa;
735         int ret = -EINVAL;
736
737         /* XXX: Don't preclude handling different sized sigset_t's.  */
738         if (sigsetsize != sizeof(sigset_t))
739                 goto out;
740
741         if (act) {
742                 s32 handler;
743                 int err = 0;
744
745                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
746                         return -EFAULT;
747                 err |= __get_user(handler, &act->sa_handler);
748                 new_sa.sa.sa_handler = (void __user *)(s64)handler;
749                 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
750                 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
751                 if (err)
752                         return -EFAULT;
753         }
754
755         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
756
757         if (!ret && oact) {
758                 int err = 0;
759
760                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
761                         return -EFAULT;
762
763                 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
764                                    &oact->sa_handler);
765                 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
766                 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
767                 if (err)
768                         return -EFAULT;
769         }
770 out:
771         return ret;
772 }
773
774 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
775         compat_sigset_t __user *oset, unsigned int sigsetsize)
776 {
777         sigset_t old_set, new_set;
778         int ret;
779         mm_segment_t old_fs = get_fs();
780
781         if (set && get_sigset(&new_set, set))
782                 return -EFAULT;
783
784         set_fs (KERNEL_DS);
785         ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
786                                  oset ? (sigset_t __user *)&old_set : NULL,
787                                  sigsetsize);
788         set_fs (old_fs);
789
790         if (!ret && oset && put_sigset(&old_set, oset))
791                 return -EFAULT;
792
793         return ret;
794 }
795
796 asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
797         unsigned int sigsetsize)
798 {
799         int ret;
800         sigset_t set;
801         mm_segment_t old_fs = get_fs();
802
803         set_fs (KERNEL_DS);
804         ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
805         set_fs (old_fs);
806
807         if (!ret && put_sigset(&set, uset))
808                 return -EFAULT;
809
810         return ret;
811 }
812
813 asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
814 {
815         siginfo_t info;
816         int ret;
817         mm_segment_t old_fs = get_fs();
818
819         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
820             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
821                 return -EFAULT;
822         set_fs (KERNEL_DS);
823         ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
824         set_fs (old_fs);
825         return ret;
826 }
827
828 asmlinkage long
829 sys32_waitid(int which, compat_pid_t pid,
830              compat_siginfo_t __user *uinfo, int options,
831              struct compat_rusage __user *uru)
832 {
833         siginfo_t info;
834         struct rusage ru;
835         long ret;
836         mm_segment_t old_fs = get_fs();
837
838         info.si_signo = 0;
839         set_fs (KERNEL_DS);
840         ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
841                          uru ? (struct rusage __user *) &ru : NULL);
842         set_fs (old_fs);
843
844         if (ret < 0 || info.si_signo == 0)
845                 return ret;
846
847         if (uru && (ret = put_compat_rusage(&ru, uru)))
848                 return ret;
849
850         BUG_ON(info.si_code & __SI_MASK);
851         info.si_code |= __SI_CHLD;
852         return copy_siginfo_to_user32(uinfo, &info);
853 }