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