new helper: sigsuspend()
[cascardo/linux.git] / arch / mips / kernel / signal32.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1991, 1992  Linus Torvalds
7  * Copyright (C) 1994 - 2000, 2006  Ralf Baechle
8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9  */
10 #include <linux/cache.h>
11 #include <linux/compat.h>
12 #include <linux/sched.h>
13 #include <linux/mm.h>
14 #include <linux/smp.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/syscalls.h>
18 #include <linux/errno.h>
19 #include <linux/wait.h>
20 #include <linux/ptrace.h>
21 #include <linux/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         sigdelsetmask(&blocked, ~_BLOCKABLE);
469         set_current_blocked(&blocked);
470
471         sig = restore_sigcontext32(&regs, &frame->sf_sc);
472         if (sig < 0)
473                 goto badframe;
474         else if (sig)
475                 force_sig(sig, current);
476
477         /*
478          * Don't let your children do this ...
479          */
480         __asm__ __volatile__(
481                 "move\t$29, %0\n\t"
482                 "j\tsyscall_exit"
483                 :/* no outputs */
484                 :"r" (&regs));
485         /* Unreached */
486
487 badframe:
488         force_sig(SIGSEGV, current);
489 }
490
491 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
492 {
493         struct rt_sigframe32 __user *frame;
494         mm_segment_t old_fs;
495         sigset_t set;
496         stack_t st;
497         s32 sp;
498         int sig;
499
500         frame = (struct rt_sigframe32 __user *) regs.regs[29];
501         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
502                 goto badframe;
503         if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
504                 goto badframe;
505
506         sigdelsetmask(&set, ~_BLOCKABLE);
507         set_current_blocked(&set);
508
509         sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
510         if (sig < 0)
511                 goto badframe;
512         else if (sig)
513                 force_sig(sig, current);
514
515         /* The ucontext contains a stack32_t, so we must convert!  */
516         if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
517                 goto badframe;
518         st.ss_sp = (void __user *)(long) sp;
519         if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
520                 goto badframe;
521         if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
522                 goto badframe;
523
524         /* It is more difficult to avoid calling this function than to
525            call it and ignore errors.  */
526         old_fs = get_fs();
527         set_fs(KERNEL_DS);
528         do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
529         set_fs(old_fs);
530
531         /*
532          * Don't let your children do this ...
533          */
534         __asm__ __volatile__(
535                 "move\t$29, %0\n\t"
536                 "j\tsyscall_exit"
537                 :/* no outputs */
538                 :"r" (&regs));
539         /* Unreached */
540
541 badframe:
542         force_sig(SIGSEGV, current);
543 }
544
545 static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
546                           struct pt_regs *regs, int signr, sigset_t *set)
547 {
548         struct sigframe32 __user *frame;
549         int err = 0;
550
551         frame = get_sigframe(ka, regs, sizeof(*frame));
552         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
553                 goto give_sigsegv;
554
555         err |= setup_sigcontext32(regs, &frame->sf_sc);
556         err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
557
558         if (err)
559                 goto give_sigsegv;
560
561         /*
562          * Arguments to signal handler:
563          *
564          *   a0 = signal number
565          *   a1 = 0 (should be cause)
566          *   a2 = pointer to struct sigcontext
567          *
568          * $25 and c0_epc point to the signal handler, $29 points to the
569          * struct sigframe.
570          */
571         regs->regs[ 4] = signr;
572         regs->regs[ 5] = 0;
573         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
574         regs->regs[29] = (unsigned long) frame;
575         regs->regs[31] = (unsigned long) sig_return;
576         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
577
578         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
579                current->comm, current->pid,
580                frame, regs->cp0_epc, regs->regs[31]);
581
582         return 0;
583
584 give_sigsegv:
585         force_sigsegv(signr, current);
586         return -EFAULT;
587 }
588
589 static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
590                              struct pt_regs *regs, int signr, sigset_t *set,
591                              siginfo_t *info)
592 {
593         struct rt_sigframe32 __user *frame;
594         int err = 0;
595         s32 sp;
596
597         frame = get_sigframe(ka, regs, sizeof(*frame));
598         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
599                 goto give_sigsegv;
600
601         /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
602         err |= copy_siginfo_to_user32(&frame->rs_info, info);
603
604         /* Create the ucontext.  */
605         err |= __put_user(0, &frame->rs_uc.uc_flags);
606         err |= __put_user(0, &frame->rs_uc.uc_link);
607         sp = (int) (long) current->sas_ss_sp;
608         err |= __put_user(sp,
609                           &frame->rs_uc.uc_stack.ss_sp);
610         err |= __put_user(sas_ss_flags(regs->regs[29]),
611                           &frame->rs_uc.uc_stack.ss_flags);
612         err |= __put_user(current->sas_ss_size,
613                           &frame->rs_uc.uc_stack.ss_size);
614         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
615         err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
616
617         if (err)
618                 goto give_sigsegv;
619
620         /*
621          * Arguments to signal handler:
622          *
623          *   a0 = signal number
624          *   a1 = 0 (should be cause)
625          *   a2 = pointer to ucontext
626          *
627          * $25 and c0_epc point to the signal handler, $29 points to
628          * the struct rt_sigframe32.
629          */
630         regs->regs[ 4] = signr;
631         regs->regs[ 5] = (unsigned long) &frame->rs_info;
632         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
633         regs->regs[29] = (unsigned long) frame;
634         regs->regs[31] = (unsigned long) sig_return;
635         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
636
637         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
638                current->comm, current->pid,
639                frame, regs->cp0_epc, regs->regs[31]);
640
641         return 0;
642
643 give_sigsegv:
644         force_sigsegv(signr, current);
645         return -EFAULT;
646 }
647
648 /*
649  * o32 compatibility on 64-bit kernels, without DSP ASE
650  */
651 struct mips_abi mips_abi_32 = {
652         .setup_frame    = setup_frame_32,
653         .signal_return_offset =
654                 offsetof(struct mips_vdso, o32_signal_trampoline),
655         .setup_rt_frame = setup_rt_frame_32,
656         .rt_signal_return_offset =
657                 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
658         .restart        = __NR_O32_restart_syscall
659 };
660
661 SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
662         const struct sigaction32 __user *, act,
663         struct sigaction32 __user *, oact, unsigned int, sigsetsize)
664 {
665         struct k_sigaction new_sa, old_sa;
666         int ret = -EINVAL;
667
668         /* XXX: Don't preclude handling different sized sigset_t's.  */
669         if (sigsetsize != sizeof(sigset_t))
670                 goto out;
671
672         if (act) {
673                 s32 handler;
674                 int err = 0;
675
676                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
677                         return -EFAULT;
678                 err |= __get_user(handler, &act->sa_handler);
679                 new_sa.sa.sa_handler = (void __user *)(s64)handler;
680                 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
681                 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
682                 if (err)
683                         return -EFAULT;
684         }
685
686         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
687
688         if (!ret && oact) {
689                 int err = 0;
690
691                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
692                         return -EFAULT;
693
694                 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
695                                    &oact->sa_handler);
696                 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
697                 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
698                 if (err)
699                         return -EFAULT;
700         }
701 out:
702         return ret;
703 }
704
705 SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
706         compat_sigset_t __user *, oset, unsigned int, sigsetsize)
707 {
708         sigset_t old_set, new_set;
709         int ret;
710         mm_segment_t old_fs = get_fs();
711
712         if (set && get_sigset(&new_set, set))
713                 return -EFAULT;
714
715         set_fs(KERNEL_DS);
716         ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
717                                  oset ? (sigset_t __user *)&old_set : NULL,
718                                  sigsetsize);
719         set_fs(old_fs);
720
721         if (!ret && oset && put_sigset(&old_set, oset))
722                 return -EFAULT;
723
724         return ret;
725 }
726
727 SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
728         unsigned int, sigsetsize)
729 {
730         int ret;
731         sigset_t set;
732         mm_segment_t old_fs = get_fs();
733
734         set_fs(KERNEL_DS);
735         ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
736         set_fs(old_fs);
737
738         if (!ret && put_sigset(&set, uset))
739                 return -EFAULT;
740
741         return ret;
742 }
743
744 SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
745         compat_siginfo_t __user *, uinfo)
746 {
747         siginfo_t info;
748         int ret;
749         mm_segment_t old_fs = get_fs();
750
751         if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
752             copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
753                 return -EFAULT;
754         set_fs(KERNEL_DS);
755         ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
756         set_fs(old_fs);
757         return ret;
758 }
759
760 SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
761              compat_siginfo_t __user *, uinfo, int, options,
762              struct compat_rusage __user *, uru)
763 {
764         siginfo_t info;
765         struct rusage ru;
766         long ret;
767         mm_segment_t old_fs = get_fs();
768
769         info.si_signo = 0;
770         set_fs(KERNEL_DS);
771         ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
772                          uru ? (struct rusage __user *) &ru : NULL);
773         set_fs(old_fs);
774
775         if (ret < 0 || info.si_signo == 0)
776                 return ret;
777
778         if (uru && (ret = put_compat_rusage(&ru, uru)))
779                 return ret;
780
781         BUG_ON(info.si_code & __SI_MASK);
782         info.si_code |= __SI_CHLD;
783         return copy_siginfo_to_user32(uinfo, &info);
784 }
785
786 static int signal32_init(void)
787 {
788         if (cpu_has_fpu) {
789                 save_fp_context32 = _save_fp_context32;
790                 restore_fp_context32 = _restore_fp_context32;
791         } else {
792                 save_fp_context32 = fpu_emulator_save_context32;
793                 restore_fp_context32 = fpu_emulator_restore_context32;
794         }
795
796         return 0;
797 }
798
799 arch_initcall(signal32_init);