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