also update spec file ...
[linux-flexiantxendom0-3.2.10.git] / arch / mips64 / 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  Ralf Baechle
8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9  */
10 #include <linux/sched.h>
11 #include <linux/mm.h>
12 #include <linux/smp.h>
13 #include <linux/smp_lock.h>
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/ptrace.h>
19 #include <linux/unistd.h>
20 #include <linux/compat.h>
21
22 #include <asm/asm.h>
23 #include <asm/bitops.h>
24 #include <asm/pgalloc.h>
25 #include <asm/stackframe.h>
26 #include <asm/uaccess.h>
27 #include <asm/ucontext.h>
28 #include <asm/system.h>
29 #include <asm/fpu.h>
30
31 #define DEBUG_SIG 0
32
33 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
35 extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
36
37 extern asmlinkage void do_syscall_trace(void);
38
39 /* 32-bit compatibility types */
40
41 #define _NSIG_BPW32     32
42 #define _NSIG_WORDS32   (_NSIG / _NSIG_BPW32)
43
44 typedef unsigned int __sighandler32_t;
45 typedef void (*vfptr_t)(void);
46
47 struct sigaction32 {
48         unsigned int            sa_flags;
49         __sighandler32_t        sa_handler;
50         compat_sigset_t         sa_mask;
51 };
52
53 /* IRIX compatible stack_t  */
54 typedef struct sigaltstack32 {
55         s32 ss_sp;
56         compat_size_t ss_size;
57         int ss_flags;
58 } stack32_t;
59
60 extern void __put_sigset_unknown_nsig(void);
61 extern void __get_sigset_unknown_nsig(void);
62
63 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
64 {
65         int err = 0;
66
67         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
68                 return -EFAULT;
69
70         switch (_NSIG_WORDS) {
71         default:
72                 __put_sigset_unknown_nsig();
73         case 2:
74                 err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
75                 err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
76         case 1:
77                 err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
78                 err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
79         }
80
81         return err;
82 }
83
84 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf)
85 {
86         int err = 0;
87         unsigned long sig[4];
88
89         if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
90                 return -EFAULT;
91
92         switch (_NSIG_WORDS) {
93         default:
94                 __get_sigset_unknown_nsig();
95         case 2:
96                 err |= __get_user (sig[3], &ubuf->sig[3]);
97                 err |= __get_user (sig[2], &ubuf->sig[2]);
98                 kbuf->sig[1] = sig[2] | (sig[3] << 32);
99         case 1:
100                 err |= __get_user (sig[1], &ubuf->sig[1]);
101                 err |= __get_user (sig[0], &ubuf->sig[0]);
102                 kbuf->sig[0] = sig[0] | (sig[1] << 32);
103         }
104
105         return err;
106 }
107
108 /*
109  * Atomically swap in the new signal mask, and wait for a signal.
110  */
111 asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs)
112 {
113         compat_sigset_t *uset;
114         sigset_t newset, saveset;
115
116         save_static(&regs);
117         uset = (compat_sigset_t *) regs.regs[4];
118         if (get_sigset(&newset, uset))
119                 return -EFAULT;
120         sigdelsetmask(&newset, ~_BLOCKABLE);
121
122         spin_lock_irq(&current->sighand->siglock);
123         saveset = current->blocked;
124         current->blocked = newset;
125         recalc_sigpending();
126         spin_unlock_irq(&current->sighand->siglock);
127
128         regs.regs[2] = EINTR;
129         regs.regs[7] = 1;
130         while (1) {
131                 current->state = TASK_INTERRUPTIBLE;
132                 schedule();
133                 if (do_signal32(&saveset, &regs))
134                         return -EINTR;
135         }
136 }
137
138 asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
139 {
140         compat_sigset_t *uset;
141         sigset_t newset, saveset;
142         size_t sigsetsize;
143
144         save_static(&regs);
145         /* XXX Don't preclude handling different sized sigset_t's.  */
146         sigsetsize = regs.regs[5];
147         if (sigsetsize != sizeof(compat_sigset_t))
148                 return -EINVAL;
149
150         uset = (compat_sigset_t *) regs.regs[4];
151         if (get_sigset(&newset, uset))
152                 return -EFAULT;
153         sigdelsetmask(&newset, ~_BLOCKABLE);
154
155         spin_lock_irq(&current->sighand->siglock);
156         saveset = current->blocked;
157         current->blocked = newset;
158         recalc_sigpending();
159         spin_unlock_irq(&current->sighand->siglock);
160
161         regs.regs[2] = EINTR;
162         regs.regs[7] = 1;
163         while (1) {
164                 current->state = TASK_INTERRUPTIBLE;
165                 schedule();
166                 if (do_signal32(&saveset, &regs))
167                         return -EINTR;
168         }
169 }
170
171 asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
172                                struct sigaction32 *oact)
173 {
174         struct k_sigaction new_ka, old_ka;
175         int ret;
176         int err = 0;
177
178         if (act) {
179                 old_sigset_t mask;
180
181                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
182                         return -EFAULT;
183                 err |= __get_user((u32)(u64)new_ka.sa.sa_handler,
184                                   &act->sa_handler);
185                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
186                 err |= __get_user(mask, &act->sa_mask.sig[0]);
187                 if (err)
188                         return -EFAULT;
189
190                 siginitset(&new_ka.sa.sa_mask, mask);
191         }
192
193         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
194
195         if (!ret && oact) {
196                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
197                         return -EFAULT;
198                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
199                 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
200                                   &oact->sa_handler);
201                 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
202                 err |= __put_user(0, &oact->sa_mask.sig[1]);
203                 err |= __put_user(0, &oact->sa_mask.sig[2]);
204                 err |= __put_user(0, &oact->sa_mask.sig[3]);
205                 if (err)
206                         return -EFAULT;
207         }
208
209         return ret;
210 }
211
212 asmlinkage int sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs)
213 {
214         const stack32_t *uss = (const stack32_t *) regs.regs[4];
215         stack32_t *uoss = (stack32_t *) regs.regs[5];
216         unsigned long usp = regs.regs[29];
217         stack_t kss, koss;
218         int ret, err = 0;
219         mm_segment_t old_fs = get_fs();
220         s32 sp;
221
222         if (uss) {
223                 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
224                         return -EFAULT;
225                 err |= __get_user(sp, &uss->ss_sp);
226                 kss.ss_size = (long) sp;
227                 err |= __get_user(kss.ss_size, &uss->ss_size);
228                 err |= __get_user(kss.ss_flags, &uss->ss_flags);
229                 if (err)
230                         return -EFAULT;
231         }
232
233         set_fs (KERNEL_DS);
234         ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
235         set_fs (old_fs);
236
237         if (!ret && uoss) {
238                 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
239                         return -EFAULT;
240                 sp = (int) (long) koss.ss_sp;
241                 err |= __put_user(sp, &uoss->ss_sp);
242                 err |= __put_user(koss.ss_size, &uoss->ss_size);
243                 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
244                 if (err)
245                         return -EFAULT;
246         }
247         return ret;
248 }
249
250 static asmlinkage int restore_sigcontext(struct pt_regs *regs,
251                                          struct sigcontext *sc)
252 {
253         int err = 0;
254
255         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
256         err |= __get_user(regs->hi, &sc->sc_mdhi);
257         err |= __get_user(regs->lo, &sc->sc_mdlo);
258
259 #define restore_gp_reg(i) do {                                          \
260         err |= __get_user(regs->regs[i], &sc->sc_regs[i]);              \
261 } while(0)
262         restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
263         restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
264         restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
265         restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
266         restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
267         restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
268         restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
269         restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
270         restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
271         restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
272         restore_gp_reg(31);
273 #undef restore_gp_reg
274
275         err |= __get_user(current->used_math, &sc->sc_used_math);
276
277         if (current->used_math) {
278                 /* restore fpu context if we have used it before */
279                 own_fpu();
280                 err |= restore_fp_context(sc);
281         } else {
282                 /* signal handler may have used FPU.  Give it up. */
283                 loose_fpu();
284         }
285
286         return err;
287 }
288
289 struct sigframe {
290         u32 sf_ass[4];                  /* argument save space for o32 */
291         u32 sf_code[2];                 /* signal trampoline */
292         struct sigcontext sf_sc;
293         sigset_t sf_mask;
294 };
295
296 struct rt_sigframe32 {
297         u32 rs_ass[4];                  /* argument save space for o32 */
298         u32 rs_code[2];                 /* signal trampoline */
299         struct siginfo32 rs_info;
300         struct ucontext rs_uc;
301 };
302
303 static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
304 {
305         int err;
306
307         if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
308                 return -EFAULT;
309
310         /* If you change siginfo_t structure, please be sure
311            this code is fixed accordingly.
312            It should never copy any pad contained in the structure
313            to avoid security leaks, but must copy the generic
314            3 ints plus the relevant union member.
315            This routine must convert siginfo from 64bit to 32bit as well
316            at the same time.  */
317         err = __put_user(from->si_signo, &to->si_signo);
318         err |= __put_user(from->si_errno, &to->si_errno);
319         err |= __put_user((short)from->si_code, &to->si_code);
320         if (from->si_code < 0)
321                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
322         else {
323                 switch (from->si_code >> 16) {
324                 case __SI_CHLD >> 16:
325                         err |= __put_user(from->si_utime, &to->si_utime);
326                         err |= __put_user(from->si_stime, &to->si_stime);
327                         err |= __put_user(from->si_status, &to->si_status);
328                 default:
329                         err |= __put_user(from->si_pid, &to->si_pid);
330                         err |= __put_user(from->si_uid, &to->si_uid);
331                         break;
332                 case __SI_FAULT >> 16:
333                         err |= __put_user((long)from->si_addr, &to->si_addr);
334                         break;
335                 case __SI_POLL >> 16:
336                         err |= __put_user(from->si_band, &to->si_band);
337                         err |= __put_user(from->si_fd, &to->si_fd);
338                         break;
339                 /* case __SI_RT: This is not generated by the kernel as of now.  */
340                 }
341         }
342         return err;
343 }
344
345 asmlinkage void sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
346 {
347         struct sigframe *frame;
348         sigset_t blocked;
349
350         frame = (struct sigframe *) regs.regs[29];
351         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
352                 goto badframe;
353         if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
354                 goto badframe;
355
356         sigdelsetmask(&blocked, ~_BLOCKABLE);
357         spin_lock_irq(&current->sighand->siglock);
358         current->blocked = blocked;
359         recalc_sigpending();
360         spin_unlock_irq(&current->sighand->siglock);
361
362         if (restore_sigcontext(&regs, &frame->sf_sc))
363                 goto badframe;
364
365         /*
366          * Don't let your children do this ...
367          */
368         if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
369                 do_syscall_trace();
370         __asm__ __volatile__(
371                 "move\t$29, %0\n\t"
372                 "j\tsyscall_exit"
373                 :/* no outputs */
374                 :"r" (&regs));
375         /* Unreached */
376
377 badframe:
378         force_sig(SIGSEGV, current);
379 }
380
381 asmlinkage void sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
382 {
383         struct rt_sigframe32 *frame;
384         sigset_t set;
385         stack_t st;
386
387         frame = (struct rt_sigframe32 *) regs.regs[29];
388         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
389                 goto badframe;
390         if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
391                 goto badframe;
392
393         sigdelsetmask(&set, ~_BLOCKABLE);
394         spin_lock_irq(&current->sighand->siglock);
395         current->blocked = set;
396         recalc_sigpending();
397         spin_unlock_irq(&current->sighand->siglock);
398
399         if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
400                 goto badframe;
401
402         if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
403                 goto badframe;
404         /* It is more difficult to avoid calling this function than to
405            call it and ignore errors.  */
406         do_sigaltstack(&st, NULL, regs.regs[29]);
407
408         /*
409          * Don't let your children do this ...
410          */
411         __asm__ __volatile__(
412                 "move\t$29, %0\n\t"
413                 "j\tsyscall_exit"
414                 :/* no outputs */
415                 :"r" (&regs));
416         /* Unreached */
417
418 badframe:
419         force_sig(SIGSEGV, current);
420 }
421
422 static inline int setup_sigcontext(struct pt_regs *regs,
423                                    struct sigcontext *sc)
424 {
425         int err = 0;
426
427         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
428         err |= __put_user(regs->cp0_status, &sc->sc_status);
429
430 #define save_gp_reg(i) {                                                \
431         err |= __put_user(regs->regs[i], &sc->sc_regs[i]);              \
432 } while(0)
433         __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
434         save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
435         save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
436         save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
437         save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
438         save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
439         save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
440         save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
441         save_gp_reg(31);
442 #undef save_gp_reg
443
444         err |= __put_user(regs->hi, &sc->sc_mdhi);
445         err |= __put_user(regs->lo, &sc->sc_mdlo);
446         err |= __put_user(regs->cp0_cause, &sc->sc_cause);
447         err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
448
449         err |= __put_user(current->used_math, &sc->sc_used_math);
450
451         if (!current->used_math)
452                 goto out;
453
454         /* 
455          * Save FPU state to signal context.  Signal handler will "inherit"
456          * current FPU state.
457          */
458         if (!is_fpu_owner()) {
459                 own_fpu();
460                 restore_fp(current);
461         }
462         err |= save_fp_context(sc);
463
464 out:
465         return err;
466 }
467
468 /*
469  * Determine which stack to use..
470  */
471 static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
472                                  size_t frame_size)
473 {
474         unsigned long sp;
475
476         /* Default to using normal stack */
477         sp = regs->regs[29];
478
479         /*
480          * FPU emulator may have it's own trampoline active just
481          * above the user stack, 16-bytes before the next lowest
482          * 16 byte boundary.  Try to avoid trashing it.
483          */
484         sp -= 32;
485
486         /* This is the X/Open sanctioned signal stack switching.  */
487         if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
488                 sp = current->sas_ss_sp + current->sas_ss_size;
489
490         return (void *)((sp - frame_size) & ALMASK);
491 }
492
493 static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
494                                int signr, sigset_t *set)
495 {
496         struct sigframe *frame;
497         int err = 0;
498
499         frame = get_sigframe(ka, regs, sizeof(*frame));
500         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
501                 goto give_sigsegv;
502
503         /*
504          * Set up the return code ...
505          *
506          *         li      v0, __NR_O32_sigreturn
507          *         syscall
508          */
509         err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
510         err |= __put_user(0x0000000c                     , frame->sf_code + 1);
511         flush_cache_sigtramp((unsigned long) frame->sf_code);
512
513         err |= setup_sigcontext(regs, &frame->sf_sc);
514         err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
515         if (err)
516                 goto give_sigsegv;
517
518         /*
519          * Arguments to signal handler:
520          *
521          *   a0 = signal number
522          *   a1 = 0 (should be cause)
523          *   a2 = pointer to struct sigcontext
524          *
525          * $25 and c0_epc point to the signal handler, $29 points to the
526          * struct sigframe.
527          */
528         regs->regs[ 4] = signr;
529         regs->regs[ 5] = 0;
530         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
531         regs->regs[29] = (unsigned long) frame;
532         regs->regs[31] = (unsigned long) frame->sf_code;
533         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
534
535 #if DEBUG_SIG
536         printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
537                current->comm, current->pid,
538                frame, regs->cp0_epc, frame->sf_code);
539 #endif
540         return;
541
542 give_sigsegv:
543         if (signr == SIGSEGV)
544                 ka->sa.sa_handler = SIG_DFL;
545         force_sig(SIGSEGV, current);
546 }
547
548 static inline void setup_rt_frame(struct k_sigaction * ka,
549                                   struct pt_regs *regs, int signr,
550                                   sigset_t *set, siginfo_t *info)
551 {
552         struct rt_sigframe32 *frame;
553         int err = 0;
554
555         frame = get_sigframe(ka, regs, sizeof(*frame));
556         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
557                 goto give_sigsegv;
558
559         /* Set up to return from userspace.  If provided, use a stub already
560            in userspace.  */
561         /*
562          * Set up the return code ...
563          *
564          *         li      v0, __NR_O32_rt_sigreturn
565          *         syscall
566          */
567         err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
568         err |= __put_user(0x0000000c                      , frame->rs_code + 1);
569         flush_cache_sigtramp((unsigned long) frame->rs_code);
570
571         /* Convert (siginfo_t -> siginfo_t32) and copy to user. */
572         err |= copy_siginfo_to_user32(&frame->rs_info, info);
573
574         /* Create the ucontext.  */
575         err |= __put_user(0, &frame->rs_uc.uc_flags);
576         err |= __put_user(0, &frame->rs_uc.uc_link);
577         err |= __put_user((void *)current->sas_ss_sp,
578                           &frame->rs_uc.uc_stack.ss_sp);
579         err |= __put_user(sas_ss_flags(regs->regs[29]),
580                           &frame->rs_uc.uc_stack.ss_flags);
581         err |= __put_user(current->sas_ss_size,
582                           &frame->rs_uc.uc_stack.ss_size);
583         err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
584         err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
585
586         if (err)
587                 goto give_sigsegv;
588
589         /*
590          * Arguments to signal handler:
591          *
592          *   a0 = signal number
593          *   a1 = 0 (should be cause)
594          *   a2 = pointer to ucontext
595          *
596          * $25 and c0_epc point to the signal handler, $29 points to
597          * the struct rt_sigframe32.
598          */
599         regs->regs[ 4] = signr;
600         regs->regs[ 5] = (unsigned long) &frame->rs_info;
601         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
602         regs->regs[29] = (unsigned long) frame;
603         regs->regs[31] = (unsigned long) frame->rs_code;
604         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
605
606 #if DEBUG_SIG
607         printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
608                current->comm, current->pid,
609                frame, regs->cp0_epc, frame->rs_code);
610 #endif
611         return;
612
613 give_sigsegv:
614         if (signr == SIGSEGV)
615                 ka->sa.sa_handler = SIG_DFL;
616         force_sig(SIGSEGV, current);
617 }
618
619 static inline void handle_signal(unsigned long sig, siginfo_t *info,
620         sigset_t *oldset, struct pt_regs * regs)
621 {
622         struct k_sigaction *ka = &current->sighand->action[sig-1];
623
624         switch (regs->regs[0]) {
625         case ERESTARTNOHAND:
626                 regs->regs[2] = EINTR;
627                 break;
628         case ERESTARTSYS:
629                 if(!(ka->sa.sa_flags & SA_RESTART)) {
630                         regs->regs[2] = EINTR;
631                         break;
632                 }
633         /* fallthrough */
634         case ERESTARTNOINTR:            /* Userland will reload $v0.  */
635                 regs->regs[7] = regs->regs[26];
636                 regs->cp0_epc -= 8;
637         }
638
639         regs->regs[0] = 0;              /* Don't deal with this again.  */
640
641         if (ka->sa.sa_flags & SA_SIGINFO)
642                 setup_rt_frame(ka, regs, sig, oldset, info);
643         else
644                 setup_frame(ka, regs, sig, oldset);
645
646         if (ka->sa.sa_flags & SA_ONESHOT)
647                 ka->sa.sa_handler = SIG_DFL;
648         if (!(ka->sa.sa_flags & SA_NODEFER)) {
649                 spin_lock_irq(&current->sighand->siglock);
650                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
651                 sigaddset(&current->blocked,sig);
652                 recalc_sigpending();
653                 spin_unlock_irq(&current->sighand->siglock);
654         }
655 }
656
657 asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
658 {
659         siginfo_t info;
660         int signr;
661
662         if (!oldset)
663                 oldset = &current->blocked;
664
665         signr = get_signal_to_deliver(&info, regs, NULL);
666         if (signr > 0) {
667                 handle_signal(signr, &info, oldset, regs);
668                 return 1;
669         }
670
671         /*
672          * Who's code doesn't conform to the restartable syscall convention
673          * dies here!!!  The li instruction, a single machine instruction,
674          * must directly be followed by the syscall instruction.
675          */
676         if (regs->regs[0]) {
677                 if (regs->regs[2] == ERESTARTNOHAND ||
678                     regs->regs[2] == ERESTARTSYS ||
679                     regs->regs[2] == ERESTARTNOINTR) {
680                         regs->regs[7] = regs->regs[26];
681                         regs->cp0_epc -= 8;
682                 }
683         }
684         return 0;
685 }
686
687 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
688                                   struct sigaction32 *oact,
689                                   unsigned int sigsetsize)
690 {
691         struct k_sigaction new_sa, old_sa;
692         int ret = -EINVAL;
693
694         /* XXX: Don't preclude handling different sized sigset_t's.  */
695         if (sigsetsize != sizeof(sigset_t))
696                 goto out;
697
698         if (act) {
699                 int err = 0;
700
701                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
702                         return -EFAULT;
703                 err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
704                                   &act->sa_handler);
705                 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
706                 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
707                 if (err)
708                         return -EFAULT;
709         }
710
711         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
712
713         if (!ret && oact) {
714                 int err = 0;
715
716                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
717                         return -EFAULT;
718
719                 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
720                                    &oact->sa_handler);
721                 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
722                 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
723                 if (err)
724                         return -EFAULT;
725         }
726 out:
727         return ret;
728 }
729
730 asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
731                                    size_t sigsetsize);
732
733 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
734         compat_sigset_t *oset, unsigned int sigsetsize)
735 {
736         sigset_t old_set, new_set;
737         int ret;
738         mm_segment_t old_fs = get_fs();
739
740         if (set && get_sigset(&new_set, set))
741                 return -EFAULT;
742
743         set_fs (KERNEL_DS);
744         ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
745                                  oset ? &old_set : NULL, sigsetsize);
746         set_fs (old_fs);
747
748         if (!ret && oset && put_sigset(&old_set, oset))
749                 return -EFAULT;
750
751         return ret;
752 }
753
754 asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
755
756 asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
757         unsigned int sigsetsize)
758 {
759         int ret;
760         sigset_t set;
761         mm_segment_t old_fs = get_fs();
762
763         set_fs (KERNEL_DS);
764         ret = sys_rt_sigpending(&set, sigsetsize);
765         set_fs (old_fs);
766
767         if (!ret && put_sigset(&set, uset))
768                 return -EFAULT;
769
770         return ret;
771 }
772
773 asmlinkage int sys32_rt_sigtimedwait(compat_sigset_t *uthese,
774         siginfo_t32 *uinfo, struct compat_timespec *uts,
775         compat_time_t sigsetsize)
776 {
777         int ret, sig;
778         sigset_t these;
779         compat_sigset_t these32;
780         struct timespec ts;
781         siginfo_t info;
782         long timeout = 0;
783
784         /*
785          * As the result of a brainfarting competition a few years ago the
786          * size of sigset_t for the 32-bit kernel was choosen to be 128 bits
787          * but nothing so far is actually using that many, 64 are enough.  So
788          * for now we just drop the high bits.
789          */
790         if (copy_from_user (&these32, uthese, sizeof(compat_old_sigset_t)))
791                 return -EFAULT;
792
793         switch (_NSIG_WORDS) {
794 #ifdef __MIPSEB__
795         case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
796         case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
797         case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
798         case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
799 #endif
800 #ifdef __MIPSEL__
801         case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32);
802         case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32);
803         case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32);
804         case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32);
805 #endif
806         }
807
808         /*
809          * Invert the set of allowed signals to get those we
810          * want to block.
811          */
812         sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
813         signotset(&these);
814
815         if (uts) {
816                 if (get_user (ts.tv_sec, &uts->tv_sec) ||
817                     get_user (ts.tv_nsec, &uts->tv_nsec))
818                         return -EINVAL;
819                 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
820                     || ts.tv_sec < 0)
821                         return -EINVAL;
822         }
823
824         spin_lock_irq(&current->sighand->siglock);
825         sig = dequeue_signal(current, &these, &info);
826         if (!sig) {
827                 /* None ready -- temporarily unblock those we're interested
828                    in so that we'll be awakened when they arrive.  */
829                 sigset_t oldblocked = current->blocked;
830                 sigandsets(&current->blocked, &current->blocked, &these);
831                 recalc_sigpending();
832                 spin_unlock_irq(&current->sighand->siglock);
833
834                 timeout = MAX_SCHEDULE_TIMEOUT;
835                 if (uts)
836                         timeout = (timespec_to_jiffies(&ts)
837                                    + (ts.tv_sec || ts.tv_nsec));
838
839                 current->state = TASK_INTERRUPTIBLE;
840                 timeout = schedule_timeout(timeout);
841
842                 spin_lock_irq(&current->sighand->siglock);
843                 sig = dequeue_signal(current, &these, &info);
844                 current->blocked = oldblocked;
845                 recalc_sigpending();
846         }
847         spin_unlock_irq(&current->sighand->siglock);
848
849         if (sig) {
850                 ret = sig;
851                 if (uinfo) {
852                         if (copy_siginfo_to_user32(uinfo, &info))
853                                 ret = -EFAULT;
854                 }
855         } else {
856                 ret = -EAGAIN;
857                 if (timeout)
858                         ret = -EINTR;
859         }
860
861         return ret;
862 }
863
864 extern asmlinkage int sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
865
866 asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
867 {
868         siginfo_t info;
869         int ret;
870         mm_segment_t old_fs = get_fs();
871
872         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
873             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
874                 return -EFAULT;
875         set_fs (KERNEL_DS);
876         ret = sys_rt_sigqueueinfo(pid, sig, &info);
877         set_fs (old_fs);
878         return ret;
879 }