Linux 2.6.33
[pohmelfs.git] / arch / mips / kernel / signal32.c
blob03abaf048f09b3257ad7240378a53e6ddcc5588d
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.
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>
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/system.h>
33 #include <asm/fpu.h>
34 #include <asm/war.h>
36 #include "signal-common.h"
38 static int (*save_fp_context32)(struct sigcontext32 __user *sc);
39 static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
41 extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
42 extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
44 extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
45 extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
48 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
50 #define __NR_O32_sigreturn 4119
51 #define __NR_O32_rt_sigreturn 4193
52 #define __NR_O32_restart_syscall 4253
54 /* 32-bit compatibility types */
56 typedef unsigned int __sighandler32_t;
57 typedef void (*vfptr_t)(void);
59 struct sigaction32 {
60 unsigned int sa_flags;
61 __sighandler32_t sa_handler;
62 compat_sigset_t sa_mask;
65 /* IRIX compatible stack_t */
66 typedef struct sigaltstack32 {
67 s32 ss_sp;
68 compat_size_t ss_size;
69 int ss_flags;
70 } stack32_t;
72 struct ucontext32 {
73 u32 uc_flags;
74 s32 uc_link;
75 stack32_t uc_stack;
76 struct sigcontext32 uc_mcontext;
77 compat_sigset_t uc_sigmask; /* mask last for extensibility */
81 * Horribly complicated - with the bloody RM9000 workarounds enabled
82 * the signal trampolines is moving to the end of the structure so we can
83 * increase the alignment without breaking software compatibility.
85 #if ICACHE_REFILLS_WORKAROUND_WAR == 0
87 struct sigframe32 {
88 u32 sf_ass[4]; /* argument save space for o32 */
89 u32 sf_code[2]; /* signal trampoline */
90 struct sigcontext32 sf_sc;
91 compat_sigset_t sf_mask;
94 struct rt_sigframe32 {
95 u32 rs_ass[4]; /* argument save space for o32 */
96 u32 rs_code[2]; /* signal trampoline */
97 compat_siginfo_t rs_info;
98 struct ucontext32 rs_uc;
101 #else /* ICACHE_REFILLS_WORKAROUND_WAR */
103 struct sigframe32 {
104 u32 sf_ass[4]; /* argument save space for o32 */
105 u32 sf_pad[2];
106 struct sigcontext32 sf_sc; /* hw context */
107 compat_sigset_t sf_mask;
108 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
111 struct rt_sigframe32 {
112 u32 rs_ass[4]; /* argument save space for o32 */
113 u32 rs_pad[2];
114 compat_siginfo_t rs_info;
115 struct ucontext32 rs_uc;
116 u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
119 #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
122 * sigcontext handlers
124 static int protected_save_fp_context32(struct sigcontext32 __user *sc)
126 int err;
127 while (1) {
128 lock_fpu_owner();
129 own_fpu_inatomic(1);
130 err = save_fp_context32(sc); /* this might fail */
131 unlock_fpu_owner();
132 if (likely(!err))
133 break;
134 /* touch the sigcontext and try again */
135 err = __put_user(0, &sc->sc_fpregs[0]) |
136 __put_user(0, &sc->sc_fpregs[31]) |
137 __put_user(0, &sc->sc_fpc_csr);
138 if (err)
139 break; /* really bad sigcontext */
141 return err;
144 static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
146 int err, tmp;
147 while (1) {
148 lock_fpu_owner();
149 own_fpu_inatomic(0);
150 err = restore_fp_context32(sc); /* this might fail */
151 unlock_fpu_owner();
152 if (likely(!err))
153 break;
154 /* touch the sigcontext and try again */
155 err = __get_user(tmp, &sc->sc_fpregs[0]) |
156 __get_user(tmp, &sc->sc_fpregs[31]) |
157 __get_user(tmp, &sc->sc_fpc_csr);
158 if (err)
159 break; /* really bad sigcontext */
161 return err;
164 static int setup_sigcontext32(struct pt_regs *regs,
165 struct sigcontext32 __user *sc)
167 int err = 0;
168 int i;
169 u32 used_math;
171 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
173 err |= __put_user(0, &sc->sc_regs[0]);
174 for (i = 1; i < 32; i++)
175 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
177 err |= __put_user(regs->hi, &sc->sc_mdhi);
178 err |= __put_user(regs->lo, &sc->sc_mdlo);
179 if (cpu_has_dsp) {
180 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
181 err |= __put_user(mfhi1(), &sc->sc_hi1);
182 err |= __put_user(mflo1(), &sc->sc_lo1);
183 err |= __put_user(mfhi2(), &sc->sc_hi2);
184 err |= __put_user(mflo2(), &sc->sc_lo2);
185 err |= __put_user(mfhi3(), &sc->sc_hi3);
186 err |= __put_user(mflo3(), &sc->sc_lo3);
189 used_math = !!used_math();
190 err |= __put_user(used_math, &sc->sc_used_math);
192 if (used_math) {
194 * Save FPU state to signal context. Signal handler
195 * will "inherit" current FPU state.
197 err |= protected_save_fp_context32(sc);
199 return err;
202 static int
203 check_and_restore_fp_context32(struct sigcontext32 __user *sc)
205 int err, sig;
207 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
208 if (err > 0)
209 err = 0;
210 err |= protected_restore_fp_context32(sc);
211 return err ?: sig;
214 static int restore_sigcontext32(struct pt_regs *regs,
215 struct sigcontext32 __user *sc)
217 u32 used_math;
218 int err = 0;
219 s32 treg;
220 int i;
222 /* Always make any pending restarted system calls return -EINTR */
223 current_thread_info()->restart_block.fn = do_no_restart_syscall;
225 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
226 err |= __get_user(regs->hi, &sc->sc_mdhi);
227 err |= __get_user(regs->lo, &sc->sc_mdlo);
228 if (cpu_has_dsp) {
229 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
230 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
231 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
232 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
233 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
234 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
235 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
238 for (i = 1; i < 32; i++)
239 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
241 err |= __get_user(used_math, &sc->sc_used_math);
242 conditional_used_math(used_math);
244 if (used_math) {
245 /* restore fpu context if we have used it before */
246 if (!err)
247 err = check_and_restore_fp_context32(sc);
248 } else {
249 /* signal handler may have used FPU. Give it up. */
250 lose_fpu(0);
253 return err;
259 extern void __put_sigset_unknown_nsig(void);
260 extern void __get_sigset_unknown_nsig(void);
262 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
264 int err = 0;
266 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
267 return -EFAULT;
269 switch (_NSIG_WORDS) {
270 default:
271 __put_sigset_unknown_nsig();
272 case 2:
273 err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
274 err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
275 case 1:
276 err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
277 err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
280 return err;
283 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
285 int err = 0;
286 unsigned long sig[4];
288 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
289 return -EFAULT;
291 switch (_NSIG_WORDS) {
292 default:
293 __get_sigset_unknown_nsig();
294 case 2:
295 err |= __get_user(sig[3], &ubuf->sig[3]);
296 err |= __get_user(sig[2], &ubuf->sig[2]);
297 kbuf->sig[1] = sig[2] | (sig[3] << 32);
298 case 1:
299 err |= __get_user(sig[1], &ubuf->sig[1]);
300 err |= __get_user(sig[0], &ubuf->sig[0]);
301 kbuf->sig[0] = sig[0] | (sig[1] << 32);
304 return err;
308 * Atomically swap in the new signal mask, and wait for a signal.
311 asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
313 compat_sigset_t __user *uset;
314 sigset_t newset;
316 uset = (compat_sigset_t __user *) regs.regs[4];
317 if (get_sigset(&newset, uset))
318 return -EFAULT;
319 sigdelsetmask(&newset, ~_BLOCKABLE);
321 spin_lock_irq(&current->sighand->siglock);
322 current->saved_sigmask = current->blocked;
323 current->blocked = newset;
324 recalc_sigpending();
325 spin_unlock_irq(&current->sighand->siglock);
327 current->state = TASK_INTERRUPTIBLE;
328 schedule();
329 set_thread_flag(TIF_RESTORE_SIGMASK);
330 return -ERESTARTNOHAND;
333 asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
335 compat_sigset_t __user *uset;
336 sigset_t newset;
337 size_t sigsetsize;
339 /* XXX Don't preclude handling different sized sigset_t's. */
340 sigsetsize = regs.regs[5];
341 if (sigsetsize != sizeof(compat_sigset_t))
342 return -EINVAL;
344 uset = (compat_sigset_t __user *) regs.regs[4];
345 if (get_sigset(&newset, uset))
346 return -EFAULT;
347 sigdelsetmask(&newset, ~_BLOCKABLE);
349 spin_lock_irq(&current->sighand->siglock);
350 current->saved_sigmask = current->blocked;
351 current->blocked = newset;
352 recalc_sigpending();
353 spin_unlock_irq(&current->sighand->siglock);
355 current->state = TASK_INTERRUPTIBLE;
356 schedule();
357 set_thread_flag(TIF_RESTORE_SIGMASK);
358 return -ERESTARTNOHAND;
361 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
362 struct sigaction32 __user *, oact)
364 struct k_sigaction new_ka, old_ka;
365 int ret;
366 int err = 0;
368 if (act) {
369 old_sigset_t mask;
370 s32 handler;
372 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
373 return -EFAULT;
374 err |= __get_user(handler, &act->sa_handler);
375 new_ka.sa.sa_handler = (void __user *)(s64)handler;
376 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
377 err |= __get_user(mask, &act->sa_mask.sig[0]);
378 if (err)
379 return -EFAULT;
381 siginitset(&new_ka.sa.sa_mask, mask);
384 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
386 if (!ret && oact) {
387 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
388 return -EFAULT;
389 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
390 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
391 &oact->sa_handler);
392 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
393 err |= __put_user(0, &oact->sa_mask.sig[1]);
394 err |= __put_user(0, &oact->sa_mask.sig[2]);
395 err |= __put_user(0, &oact->sa_mask.sig[3]);
396 if (err)
397 return -EFAULT;
400 return ret;
403 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
405 const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
406 stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
407 unsigned long usp = regs.regs[29];
408 stack_t kss, koss;
409 int ret, err = 0;
410 mm_segment_t old_fs = get_fs();
411 s32 sp;
413 if (uss) {
414 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
415 return -EFAULT;
416 err |= __get_user(sp, &uss->ss_sp);
417 kss.ss_sp = (void __user *) (long) sp;
418 err |= __get_user(kss.ss_size, &uss->ss_size);
419 err |= __get_user(kss.ss_flags, &uss->ss_flags);
420 if (err)
421 return -EFAULT;
424 set_fs(KERNEL_DS);
425 ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
426 uoss ? (stack_t __user *)&koss : NULL, usp);
427 set_fs(old_fs);
429 if (!ret && uoss) {
430 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
431 return -EFAULT;
432 sp = (int) (unsigned long) koss.ss_sp;
433 err |= __put_user(sp, &uoss->ss_sp);
434 err |= __put_user(koss.ss_size, &uoss->ss_size);
435 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
436 if (err)
437 return -EFAULT;
439 return ret;
442 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
444 int err;
446 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
447 return -EFAULT;
449 /* If you change siginfo_t structure, please be sure
450 this code is fixed accordingly.
451 It should never copy any pad contained in the structure
452 to avoid security leaks, but must copy the generic
453 3 ints plus the relevant union member.
454 This routine must convert siginfo from 64bit to 32bit as well
455 at the same time. */
456 err = __put_user(from->si_signo, &to->si_signo);
457 err |= __put_user(from->si_errno, &to->si_errno);
458 err |= __put_user((short)from->si_code, &to->si_code);
459 if (from->si_code < 0)
460 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
461 else {
462 switch (from->si_code >> 16) {
463 case __SI_TIMER >> 16:
464 err |= __put_user(from->si_tid, &to->si_tid);
465 err |= __put_user(from->si_overrun, &to->si_overrun);
466 err |= __put_user(from->si_int, &to->si_int);
467 break;
468 case __SI_CHLD >> 16:
469 err |= __put_user(from->si_utime, &to->si_utime);
470 err |= __put_user(from->si_stime, &to->si_stime);
471 err |= __put_user(from->si_status, &to->si_status);
472 default:
473 err |= __put_user(from->si_pid, &to->si_pid);
474 err |= __put_user(from->si_uid, &to->si_uid);
475 break;
476 case __SI_FAULT >> 16:
477 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
478 break;
479 case __SI_POLL >> 16:
480 err |= __put_user(from->si_band, &to->si_band);
481 err |= __put_user(from->si_fd, &to->si_fd);
482 break;
483 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
484 case __SI_MESGQ >> 16:
485 err |= __put_user(from->si_pid, &to->si_pid);
486 err |= __put_user(from->si_uid, &to->si_uid);
487 err |= __put_user(from->si_int, &to->si_int);
488 break;
491 return err;
494 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
496 memset(to, 0, sizeof *to);
498 if (copy_from_user(to, from, 3*sizeof(int)) ||
499 copy_from_user(to->_sifields._pad,
500 from->_sifields._pad, SI_PAD_SIZE32))
501 return -EFAULT;
503 return 0;
506 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
508 struct sigframe32 __user *frame;
509 sigset_t blocked;
510 int sig;
512 frame = (struct sigframe32 __user *) regs.regs[29];
513 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
514 goto badframe;
515 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
516 goto badframe;
518 sigdelsetmask(&blocked, ~_BLOCKABLE);
519 spin_lock_irq(&current->sighand->siglock);
520 current->blocked = blocked;
521 recalc_sigpending();
522 spin_unlock_irq(&current->sighand->siglock);
524 sig = restore_sigcontext32(&regs, &frame->sf_sc);
525 if (sig < 0)
526 goto badframe;
527 else if (sig)
528 force_sig(sig, current);
531 * Don't let your children do this ...
533 __asm__ __volatile__(
534 "move\t$29, %0\n\t"
535 "j\tsyscall_exit"
536 :/* no outputs */
537 :"r" (&regs));
538 /* Unreached */
540 badframe:
541 force_sig(SIGSEGV, current);
544 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
546 struct rt_sigframe32 __user *frame;
547 mm_segment_t old_fs;
548 sigset_t set;
549 stack_t st;
550 s32 sp;
551 int sig;
553 frame = (struct rt_sigframe32 __user *) regs.regs[29];
554 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
555 goto badframe;
556 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
557 goto badframe;
559 sigdelsetmask(&set, ~_BLOCKABLE);
560 spin_lock_irq(&current->sighand->siglock);
561 current->blocked = set;
562 recalc_sigpending();
563 spin_unlock_irq(&current->sighand->siglock);
565 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
566 if (sig < 0)
567 goto badframe;
568 else if (sig)
569 force_sig(sig, current);
571 /* The ucontext contains a stack32_t, so we must convert! */
572 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
573 goto badframe;
574 st.ss_sp = (void __user *)(long) sp;
575 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
576 goto badframe;
577 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
578 goto badframe;
580 /* It is more difficult to avoid calling this function than to
581 call it and ignore errors. */
582 old_fs = get_fs();
583 set_fs(KERNEL_DS);
584 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
585 set_fs(old_fs);
588 * Don't let your children do this ...
590 __asm__ __volatile__(
591 "move\t$29, %0\n\t"
592 "j\tsyscall_exit"
593 :/* no outputs */
594 :"r" (&regs));
595 /* Unreached */
597 badframe:
598 force_sig(SIGSEGV, current);
601 static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
602 int signr, sigset_t *set)
604 struct sigframe32 __user *frame;
605 int err = 0;
607 frame = get_sigframe(ka, regs, sizeof(*frame));
608 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
609 goto give_sigsegv;
611 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
613 err |= setup_sigcontext32(regs, &frame->sf_sc);
614 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
616 if (err)
617 goto give_sigsegv;
620 * Arguments to signal handler:
622 * a0 = signal number
623 * a1 = 0 (should be cause)
624 * a2 = pointer to struct sigcontext
626 * $25 and c0_epc point to the signal handler, $29 points to the
627 * struct sigframe.
629 regs->regs[ 4] = signr;
630 regs->regs[ 5] = 0;
631 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
632 regs->regs[29] = (unsigned long) frame;
633 regs->regs[31] = (unsigned long) frame->sf_code;
634 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
636 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
637 current->comm, current->pid,
638 frame, regs->cp0_epc, regs->regs[31]);
640 return 0;
642 give_sigsegv:
643 force_sigsegv(signr, current);
644 return -EFAULT;
647 static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
648 int signr, sigset_t *set, siginfo_t *info)
650 struct rt_sigframe32 __user *frame;
651 int err = 0;
652 s32 sp;
654 frame = get_sigframe(ka, regs, sizeof(*frame));
655 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
656 goto give_sigsegv;
658 err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
660 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
661 err |= copy_siginfo_to_user32(&frame->rs_info, info);
663 /* Create the ucontext. */
664 err |= __put_user(0, &frame->rs_uc.uc_flags);
665 err |= __put_user(0, &frame->rs_uc.uc_link);
666 sp = (int) (long) current->sas_ss_sp;
667 err |= __put_user(sp,
668 &frame->rs_uc.uc_stack.ss_sp);
669 err |= __put_user(sas_ss_flags(regs->regs[29]),
670 &frame->rs_uc.uc_stack.ss_flags);
671 err |= __put_user(current->sas_ss_size,
672 &frame->rs_uc.uc_stack.ss_size);
673 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
674 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
676 if (err)
677 goto give_sigsegv;
680 * Arguments to signal handler:
682 * a0 = signal number
683 * a1 = 0 (should be cause)
684 * a2 = pointer to ucontext
686 * $25 and c0_epc point to the signal handler, $29 points to
687 * the struct rt_sigframe32.
689 regs->regs[ 4] = signr;
690 regs->regs[ 5] = (unsigned long) &frame->rs_info;
691 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
692 regs->regs[29] = (unsigned long) frame;
693 regs->regs[31] = (unsigned long) frame->rs_code;
694 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
696 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
697 current->comm, current->pid,
698 frame, regs->cp0_epc, regs->regs[31]);
700 return 0;
702 give_sigsegv:
703 force_sigsegv(signr, current);
704 return -EFAULT;
708 * o32 compatibility on 64-bit kernels, without DSP ASE
710 struct mips_abi mips_abi_32 = {
711 .setup_frame = setup_frame_32,
712 .setup_rt_frame = setup_rt_frame_32,
713 .restart = __NR_O32_restart_syscall
716 SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
717 const struct sigaction32 __user *, act,
718 struct sigaction32 __user *, oact, unsigned int, sigsetsize)
720 struct k_sigaction new_sa, old_sa;
721 int ret = -EINVAL;
723 /* XXX: Don't preclude handling different sized sigset_t's. */
724 if (sigsetsize != sizeof(sigset_t))
725 goto out;
727 if (act) {
728 s32 handler;
729 int err = 0;
731 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
732 return -EFAULT;
733 err |= __get_user(handler, &act->sa_handler);
734 new_sa.sa.sa_handler = (void __user *)(s64)handler;
735 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
736 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
737 if (err)
738 return -EFAULT;
741 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
743 if (!ret && oact) {
744 int err = 0;
746 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
747 return -EFAULT;
749 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
750 &oact->sa_handler);
751 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
752 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
753 if (err)
754 return -EFAULT;
756 out:
757 return ret;
760 SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
761 compat_sigset_t __user *, oset, unsigned int, sigsetsize)
763 sigset_t old_set, new_set;
764 int ret;
765 mm_segment_t old_fs = get_fs();
767 if (set && get_sigset(&new_set, set))
768 return -EFAULT;
770 set_fs(KERNEL_DS);
771 ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
772 oset ? (sigset_t __user *)&old_set : NULL,
773 sigsetsize);
774 set_fs(old_fs);
776 if (!ret && oset && put_sigset(&old_set, oset))
777 return -EFAULT;
779 return ret;
782 SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
783 unsigned int, sigsetsize)
785 int ret;
786 sigset_t set;
787 mm_segment_t old_fs = get_fs();
789 set_fs(KERNEL_DS);
790 ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
791 set_fs(old_fs);
793 if (!ret && put_sigset(&set, uset))
794 return -EFAULT;
796 return ret;
799 SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
800 compat_siginfo_t __user *, uinfo)
802 siginfo_t info;
803 int ret;
804 mm_segment_t old_fs = get_fs();
806 if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
807 copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
808 return -EFAULT;
809 set_fs(KERNEL_DS);
810 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
811 set_fs(old_fs);
812 return ret;
815 SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
816 compat_siginfo_t __user *, uinfo, int, options,
817 struct compat_rusage __user *, uru)
819 siginfo_t info;
820 struct rusage ru;
821 long ret;
822 mm_segment_t old_fs = get_fs();
824 info.si_signo = 0;
825 set_fs(KERNEL_DS);
826 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
827 uru ? (struct rusage __user *) &ru : NULL);
828 set_fs(old_fs);
830 if (ret < 0 || info.si_signo == 0)
831 return ret;
833 if (uru && (ret = put_compat_rusage(&ru, uru)))
834 return ret;
836 BUG_ON(info.si_code & __SI_MASK);
837 info.si_code |= __SI_CHLD;
838 return copy_siginfo_to_user32(uinfo, &info);
841 static int signal32_init(void)
843 if (cpu_has_fpu) {
844 save_fp_context32 = _save_fp_context32;
845 restore_fp_context32 = _restore_fp_context32;
846 } else {
847 save_fp_context32 = fpu_emulator_save_context32;
848 restore_fp_context32 = fpu_emulator_restore_context32;
851 return 0;
854 arch_initcall(signal32_init);