Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-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/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         u32 used_math;
185
186         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
187
188         err |= __put_user(0, &sc->sc_regs[0]);
189         for (i = 1; i < 32; i++)
190                 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
191
192         err |= __put_user(regs->hi, &sc->sc_mdhi);
193         err |= __put_user(regs->lo, &sc->sc_mdlo);
194         if (cpu_has_dsp) {
195                 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
196                 err |= __put_user(mfhi1(), &sc->sc_hi1);
197                 err |= __put_user(mflo1(), &sc->sc_lo1);
198                 err |= __put_user(mfhi2(), &sc->sc_hi2);
199                 err |= __put_user(mflo2(), &sc->sc_lo2);
200                 err |= __put_user(mfhi3(), &sc->sc_hi3);
201                 err |= __put_user(mflo3(), &sc->sc_lo3);
202         }
203
204         used_math = !!used_math();
205         err |= __put_user(used_math, &sc->sc_used_math);
206
207         if (used_math) {
208                 /*
209                  * Save FPU state to signal context.  Signal handler
210                  * will "inherit" current FPU state.
211                  */
212                 own_fpu(1);
213                 enable_fp_in_kernel();
214                 err |= save_fp_context32(sc);
215                 disable_fp_in_kernel();
216         }
217         return err;
218 }
219
220 static int
221 check_and_restore_fp_context32(struct sigcontext32 __user *sc)
222 {
223         int err, sig;
224
225         err = sig = fpcsr_pending(&sc->sc_fpc_csr);
226         if (err > 0)
227                 err = 0;
228         err |= restore_fp_context32(sc);
229         return err ?: sig;
230 }
231
232 static int restore_sigcontext32(struct pt_regs *regs,
233                                 struct sigcontext32 __user *sc)
234 {
235         u32 used_math;
236         int err = 0;
237         s32 treg;
238         int i;
239
240         /* Always make any pending restarted system calls return -EINTR */
241         current_thread_info()->restart_block.fn = do_no_restart_syscall;
242
243         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
244         err |= __get_user(regs->hi, &sc->sc_mdhi);
245         err |= __get_user(regs->lo, &sc->sc_mdlo);
246         if (cpu_has_dsp) {
247                 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
248                 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
249                 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
250                 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
251                 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
252                 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
253                 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
254         }
255
256         for (i = 1; i < 32; i++)
257                 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
258
259         err |= __get_user(used_math, &sc->sc_used_math);
260         conditional_used_math(used_math);
261
262         if (used_math) {
263                 /* restore fpu context if we have used it before */
264                 own_fpu(0);
265                 enable_fp_in_kernel();
266                 if (!err)
267                         err = check_and_restore_fp_context32(sc);
268                 disable_fp_in_kernel();
269         } else {
270                 /* signal handler may have used FPU.  Give it up. */
271                 lose_fpu(0);
272         }
273
274         return err;
275 }
276
277 /*
278  *
279  */
280 extern void __put_sigset_unknown_nsig(void);
281 extern void __get_sigset_unknown_nsig(void);
282
283 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
284 {
285         int err = 0;
286
287         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
288                 return -EFAULT;
289
290         switch (_NSIG_WORDS) {
291         default:
292                 __put_sigset_unknown_nsig();
293         case 2:
294                 err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
295                 err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
296         case 1:
297                 err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
298                 err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
299         }
300
301         return err;
302 }
303
304 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
305 {
306         int err = 0;
307         unsigned long sig[4];
308
309         if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
310                 return -EFAULT;
311
312         switch (_NSIG_WORDS) {
313         default:
314                 __get_sigset_unknown_nsig();
315         case 2:
316                 err |= __get_user (sig[3], &ubuf->sig[3]);
317                 err |= __get_user (sig[2], &ubuf->sig[2]);
318                 kbuf->sig[1] = sig[2] | (sig[3] << 32);
319         case 1:
320                 err |= __get_user (sig[1], &ubuf->sig[1]);
321                 err |= __get_user (sig[0], &ubuf->sig[0]);
322                 kbuf->sig[0] = sig[0] | (sig[1] << 32);
323         }
324
325         return err;
326 }
327
328 /*
329  * Atomically swap in the new signal mask, and wait for a signal.
330  */
331
332 asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
333 {
334         compat_sigset_t __user *uset;
335         sigset_t newset;
336
337         uset = (compat_sigset_t __user *) regs.regs[4];
338         if (get_sigset(&newset, uset))
339                 return -EFAULT;
340         sigdelsetmask(&newset, ~_BLOCKABLE);
341
342         spin_lock_irq(&current->sighand->siglock);
343         current->saved_sigmask = current->blocked;
344         current->blocked = newset;
345         recalc_sigpending();
346         spin_unlock_irq(&current->sighand->siglock);
347
348         current->state = TASK_INTERRUPTIBLE;
349         schedule();
350         set_thread_flag(TIF_RESTORE_SIGMASK);
351         return -ERESTARTNOHAND;
352 }
353
354 asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
355 {
356         compat_sigset_t __user *uset;
357         sigset_t newset;
358         size_t sigsetsize;
359
360         /* XXX Don't preclude handling different sized sigset_t's.  */
361         sigsetsize = regs.regs[5];
362         if (sigsetsize != sizeof(compat_sigset_t))
363                 return -EINVAL;
364
365         uset = (compat_sigset_t __user *) regs.regs[4];
366         if (get_sigset(&newset, uset))
367                 return -EFAULT;
368         sigdelsetmask(&newset, ~_BLOCKABLE);
369
370         spin_lock_irq(&current->sighand->siglock);
371         current->saved_sigmask = current->blocked;
372         current->blocked = newset;
373         recalc_sigpending();
374         spin_unlock_irq(&current->sighand->siglock);
375
376         current->state = TASK_INTERRUPTIBLE;
377         schedule();
378         set_thread_flag(TIF_RESTORE_SIGMASK);
379         return -ERESTARTNOHAND;
380 }
381
382 asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act,
383                                struct sigaction32 __user *oact)
384 {
385         struct k_sigaction new_ka, old_ka;
386         int ret;
387         int err = 0;
388
389         if (act) {
390                 old_sigset_t mask;
391                 s32 handler;
392
393                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
394                         return -EFAULT;
395                 err |= __get_user(handler, &act->sa_handler);
396                 new_ka.sa.sa_handler = (void __user *)(s64)handler;
397                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
398                 err |= __get_user(mask, &act->sa_mask.sig[0]);
399                 if (err)
400                         return -EFAULT;
401
402                 siginitset(&new_ka.sa.sa_mask, mask);
403         }
404
405         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
406
407         if (!ret && oact) {
408                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
409                         return -EFAULT;
410                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
411                 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
412                                   &oact->sa_handler);
413                 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
414                 err |= __put_user(0, &oact->sa_mask.sig[1]);
415                 err |= __put_user(0, &oact->sa_mask.sig[2]);
416                 err |= __put_user(0, &oact->sa_mask.sig[3]);
417                 if (err)
418                         return -EFAULT;
419         }
420
421         return ret;
422 }
423
424 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
425 {
426         const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
427         stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
428         unsigned long usp = regs.regs[29];
429         stack_t kss, koss;
430         int ret, err = 0;
431         mm_segment_t old_fs = get_fs();
432         s32 sp;
433
434         if (uss) {
435                 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
436                         return -EFAULT;
437                 err |= __get_user(sp, &uss->ss_sp);
438                 kss.ss_sp = (void __user *) (long) sp;
439                 err |= __get_user(kss.ss_size, &uss->ss_size);
440                 err |= __get_user(kss.ss_flags, &uss->ss_flags);
441                 if (err)
442                         return -EFAULT;
443         }
444
445         set_fs (KERNEL_DS);
446         ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
447                              uoss ? (stack_t __user *)&koss : NULL, usp);
448         set_fs (old_fs);
449
450         if (!ret && uoss) {
451                 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
452                         return -EFAULT;
453                 sp = (int) (unsigned long) koss.ss_sp;
454                 err |= __put_user(sp, &uoss->ss_sp);
455                 err |= __put_user(koss.ss_size, &uoss->ss_size);
456                 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
457                 if (err)
458                         return -EFAULT;
459         }
460         return ret;
461 }
462
463 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
464 {
465         int err;
466
467         if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
468                 return -EFAULT;
469
470         /* If you change siginfo_t structure, please be sure
471            this code is fixed accordingly.
472            It should never copy any pad contained in the structure
473            to avoid security leaks, but must copy the generic
474            3 ints plus the relevant union member.
475            This routine must convert siginfo from 64bit to 32bit as well
476            at the same time.  */
477         err = __put_user(from->si_signo, &to->si_signo);
478         err |= __put_user(from->si_errno, &to->si_errno);
479         err |= __put_user((short)from->si_code, &to->si_code);
480         if (from->si_code < 0)
481                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
482         else {
483                 switch (from->si_code >> 16) {
484                 case __SI_TIMER >> 16:
485                         err |= __put_user(from->si_tid, &to->si_tid);
486                         err |= __put_user(from->si_overrun, &to->si_overrun);
487                         err |= __put_user(from->si_int, &to->si_int);
488                         break;
489                 case __SI_CHLD >> 16:
490                         err |= __put_user(from->si_utime, &to->si_utime);
491                         err |= __put_user(from->si_stime, &to->si_stime);
492                         err |= __put_user(from->si_status, &to->si_status);
493                 default:
494                         err |= __put_user(from->si_pid, &to->si_pid);
495                         err |= __put_user(from->si_uid, &to->si_uid);
496                         break;
497                 case __SI_FAULT >> 16:
498                         err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
499                         break;
500                 case __SI_POLL >> 16:
501                         err |= __put_user(from->si_band, &to->si_band);
502                         err |= __put_user(from->si_fd, &to->si_fd);
503                         break;
504                 case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
505                 case __SI_MESGQ >> 16:
506                         err |= __put_user(from->si_pid, &to->si_pid);
507                         err |= __put_user(from->si_uid, &to->si_uid);
508                         err |= __put_user(from->si_int, &to->si_int);
509                         break;
510                 }
511         }
512         return err;
513 }
514
515 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
516 {
517         struct sigframe32 __user *frame;
518         sigset_t blocked;
519         int sig;
520
521         frame = (struct sigframe32 __user *) regs.regs[29];
522         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
523                 goto badframe;
524         if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
525                 goto badframe;
526
527         sigdelsetmask(&blocked, ~_BLOCKABLE);
528         spin_lock_irq(&current->sighand->siglock);
529         current->blocked = blocked;
530         recalc_sigpending();
531         spin_unlock_irq(&current->sighand->siglock);
532
533         sig = restore_sigcontext32(&regs, &frame->sf_sc);
534         if (sig < 0)
535                 goto badframe;
536         else if (sig)
537                 force_sig(sig, current);
538
539         /*
540          * Don't let your children do this ...
541          */
542         __asm__ __volatile__(
543                 "move\t$29, %0\n\t"
544                 "j\tsyscall_exit"
545                 :/* no outputs */
546                 :"r" (&regs));
547         /* Unreached */
548
549 badframe:
550         force_sig(SIGSEGV, current);
551 }
552
553 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
554 {
555         struct rt_sigframe32 __user *frame;
556         mm_segment_t old_fs;
557         sigset_t set;
558         stack_t st;
559         s32 sp;
560         int sig;
561
562         frame = (struct rt_sigframe32 __user *) regs.regs[29];
563         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
564                 goto badframe;
565         if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
566                 goto badframe;
567
568         sigdelsetmask(&set, ~_BLOCKABLE);
569         spin_lock_irq(&current->sighand->siglock);
570         current->blocked = set;
571         recalc_sigpending();
572         spin_unlock_irq(&current->sighand->siglock);
573
574         sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
575         if (sig < 0)
576                 goto badframe;
577         else if (sig)
578                 force_sig(sig, current);
579
580         /* The ucontext contains a stack32_t, so we must convert!  */
581         if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
582                 goto badframe;
583         st.ss_sp = (void __user *)(long) sp;
584         if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
585                 goto badframe;
586         if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
587                 goto badframe;
588
589         /* It is more difficult to avoid calling this function than to
590            call it and ignore errors.  */
591         old_fs = get_fs();
592         set_fs (KERNEL_DS);
593         do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
594         set_fs (old_fs);
595
596         /*
597          * Don't let your children do this ...
598          */
599         __asm__ __volatile__(
600                 "move\t$29, %0\n\t"
601                 "j\tsyscall_exit"
602                 :/* no outputs */
603                 :"r" (&regs));
604         /* Unreached */
605
606 badframe:
607         force_sig(SIGSEGV, current);
608 }
609
610 static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
611         int signr, sigset_t *set)
612 {
613         struct sigframe32 __user *frame;
614         int err = 0;
615
616         frame = get_sigframe(ka, regs, sizeof(*frame));
617         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
618                 goto give_sigsegv;
619
620         err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
621
622         err |= setup_sigcontext32(regs, &frame->sf_sc);
623         err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
624
625         if (err)
626                 goto give_sigsegv;
627
628         /*
629          * Arguments to signal handler:
630          *
631          *   a0 = signal number
632          *   a1 = 0 (should be cause)
633          *   a2 = pointer to struct sigcontext
634          *
635          * $25 and c0_epc point to the signal handler, $29 points to the
636          * struct sigframe.
637          */
638         regs->regs[ 4] = signr;
639         regs->regs[ 5] = 0;
640         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
641         regs->regs[29] = (unsigned long) frame;
642         regs->regs[31] = (unsigned long) frame->sf_code;
643         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
644
645         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
646                current->comm, current->pid,
647                frame, regs->cp0_epc, regs->regs[31]);
648
649         return 0;
650
651 give_sigsegv:
652         force_sigsegv(signr, current);
653         return -EFAULT;
654 }
655
656 static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
657         int signr, sigset_t *set, siginfo_t *info)
658 {
659         struct rt_sigframe32 __user *frame;
660         int err = 0;
661         s32 sp;
662
663         frame = get_sigframe(ka, regs, sizeof(*frame));
664         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
665                 goto give_sigsegv;
666
667         err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
668
669         /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
670         err |= copy_siginfo_to_user32(&frame->rs_info, info);
671
672         /* Create the ucontext.  */
673         err |= __put_user(0, &frame->rs_uc.uc_flags);
674         err |= __put_user(0, &frame->rs_uc.uc_link);
675         sp = (int) (long) current->sas_ss_sp;
676         err |= __put_user(sp,
677                           &frame->rs_uc.uc_stack.ss_sp);
678         err |= __put_user(sas_ss_flags(regs->regs[29]),
679                           &frame->rs_uc.uc_stack.ss_flags);
680         err |= __put_user(current->sas_ss_size,
681                           &frame->rs_uc.uc_stack.ss_size);
682         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
683         err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
684
685         if (err)
686                 goto give_sigsegv;
687
688         /*
689          * Arguments to signal handler:
690          *
691          *   a0 = signal number
692          *   a1 = 0 (should be cause)
693          *   a2 = pointer to ucontext
694          *
695          * $25 and c0_epc point to the signal handler, $29 points to
696          * the struct rt_sigframe32.
697          */
698         regs->regs[ 4] = signr;
699         regs->regs[ 5] = (unsigned long) &frame->rs_info;
700         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
701         regs->regs[29] = (unsigned long) frame;
702         regs->regs[31] = (unsigned long) frame->rs_code;
703         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
704
705         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
706                current->comm, current->pid,
707                frame, regs->cp0_epc, regs->regs[31]);
708
709         return 0;
710
711 give_sigsegv:
712         force_sigsegv(signr, current);
713         return -EFAULT;
714 }
715
716 /*
717  * o32 compatibility on 64-bit kernels, without DSP ASE
718  */
719 struct mips_abi mips_abi_32 = {
720         .setup_frame    = setup_frame_32,
721         .setup_rt_frame = setup_rt_frame_32,
722         .restart        = __NR_O32_restart_syscall
723 };
724
725 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
726                                   struct sigaction32 __user *oact,
727                                   unsigned int sigsetsize)
728 {
729         struct k_sigaction new_sa, old_sa;
730         int ret = -EINVAL;
731
732         /* XXX: Don't preclude handling different sized sigset_t's.  */
733         if (sigsetsize != sizeof(sigset_t))
734                 goto out;
735
736         if (act) {
737                 s32 handler;
738                 int err = 0;
739
740                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
741                         return -EFAULT;
742                 err |= __get_user(handler, &act->sa_handler);
743                 new_sa.sa.sa_handler = (void __user *)(s64)handler;
744                 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
745                 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
746                 if (err)
747                         return -EFAULT;
748         }
749
750         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
751
752         if (!ret && oact) {
753                 int err = 0;
754
755                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
756                         return -EFAULT;
757
758                 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
759                                    &oact->sa_handler);
760                 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
761                 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
762                 if (err)
763                         return -EFAULT;
764         }
765 out:
766         return ret;
767 }
768
769 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
770         compat_sigset_t __user *oset, unsigned int sigsetsize)
771 {
772         sigset_t old_set, new_set;
773         int ret;
774         mm_segment_t old_fs = get_fs();
775
776         if (set && get_sigset(&new_set, set))
777                 return -EFAULT;
778
779         set_fs (KERNEL_DS);
780         ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
781                                  oset ? (sigset_t __user *)&old_set : NULL,
782                                  sigsetsize);
783         set_fs (old_fs);
784
785         if (!ret && oset && put_sigset(&old_set, oset))
786                 return -EFAULT;
787
788         return ret;
789 }
790
791 asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
792         unsigned int sigsetsize)
793 {
794         int ret;
795         sigset_t set;
796         mm_segment_t old_fs = get_fs();
797
798         set_fs (KERNEL_DS);
799         ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
800         set_fs (old_fs);
801
802         if (!ret && put_sigset(&set, uset))
803                 return -EFAULT;
804
805         return ret;
806 }
807
808 asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
809 {
810         siginfo_t info;
811         int ret;
812         mm_segment_t old_fs = get_fs();
813
814         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
815             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
816                 return -EFAULT;
817         set_fs (KERNEL_DS);
818         ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
819         set_fs (old_fs);
820         return ret;
821 }
822
823 asmlinkage long
824 sys32_waitid(int which, compat_pid_t pid,
825              compat_siginfo_t __user *uinfo, int options,
826              struct compat_rusage __user *uru)
827 {
828         siginfo_t info;
829         struct rusage ru;
830         long ret;
831         mm_segment_t old_fs = get_fs();
832
833         info.si_signo = 0;
834         set_fs (KERNEL_DS);
835         ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
836                          uru ? (struct rusage __user *) &ru : NULL);
837         set_fs (old_fs);
838
839         if (ret < 0 || info.si_signo == 0)
840                 return ret;
841
842         if (uru && (ret = put_compat_rusage(&ru, uru)))
843                 return ret;
844
845         BUG_ON(info.si_code & __SI_MASK);
846         info.si_code |= __SI_CHLD;
847         return copy_siginfo_to_user32(uinfo, &info);
848 }