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