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