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