Handle ERESTART_RESTARTBLOCK.
[linux-2.6/linux-mips.git] / arch / mips64 / kernel / signal32.c
blob7c7ee8c32ccd9cea4ccba5f4caa7d89b710544c6
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 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>
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>
31 #define DEBUG_SIG 0
33 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35 extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
37 extern asmlinkage void do_syscall_trace(void);
39 /* 32-bit compatibility types */
41 #define _NSIG_BPW32 32
42 #define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32)
44 typedef unsigned int __sighandler32_t;
45 typedef void (*vfptr_t)(void);
47 struct sigaction32 {
48 unsigned int sa_flags;
49 __sighandler32_t sa_handler;
50 compat_sigset_t sa_mask;
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;
60 extern void __put_sigset_unknown_nsig(void);
61 extern void __get_sigset_unknown_nsig(void);
63 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
65 int err = 0;
67 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
68 return -EFAULT;
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]);
81 return err;
84 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf)
86 int err = 0;
87 unsigned long sig[4];
89 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
90 return -EFAULT;
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);
105 return err;
109 * Atomically swap in the new signal mask, and wait for a signal.
111 asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs)
113 compat_sigset_t *uset;
114 sigset_t newset, saveset;
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);
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);
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;
138 asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs)
140 compat_sigset_t *uset;
141 sigset_t newset, saveset;
142 size_t sigsetsize;
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;
150 uset = (compat_sigset_t *) regs.regs[4];
151 if (get_sigset(&newset, uset))
152 return -EFAULT;
153 sigdelsetmask(&newset, ~_BLOCKABLE);
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);
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;
171 asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
172 struct sigaction32 *oact)
174 struct k_sigaction new_ka, old_ka;
175 int ret;
176 int err = 0;
178 if (act) {
179 old_sigset_t mask;
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;
190 siginitset(&new_ka.sa.sa_mask, mask);
193 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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;
209 return ret;
212 asmlinkage int sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs)
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;
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;
233 set_fs (KERNEL_DS);
234 ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
235 set_fs (old_fs);
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;
247 return ret;
250 static asmlinkage int restore_sigcontext(struct pt_regs *regs,
251 struct sigcontext *sc)
253 int err = 0;
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);
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
275 err |= __get_user(current->used_math, &sc->sc_used_math);
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();
286 return err;
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;
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;
303 static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
305 int err;
307 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
308 return -EFAULT;
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. */
342 return err;
345 asmlinkage void sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
347 struct sigframe *frame;
348 sigset_t blocked;
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;
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);
362 if (restore_sigcontext(&regs, &frame->sf_sc))
363 goto badframe;
366 * Don't let your children do this ...
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 */
377 badframe:
378 force_sig(SIGSEGV, current);
381 asmlinkage void sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
383 struct rt_sigframe32 *frame;
384 sigset_t set;
385 stack_t st;
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;
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);
399 if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
400 goto badframe;
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]);
409 * Don't let your children do this ...
411 __asm__ __volatile__(
412 "move\t$29, %0\n\t"
413 "j\tsyscall_exit"
414 :/* no outputs */
415 :"r" (&regs));
416 /* Unreached */
418 badframe:
419 force_sig(SIGSEGV, current);
422 static inline int setup_sigcontext(struct pt_regs *regs,
423 struct sigcontext *sc)
425 int err = 0;
427 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
428 err |= __put_user(regs->cp0_status, &sc->sc_status);
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
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);
449 err |= __put_user(current->used_math, &sc->sc_used_math);
451 if (!current->used_math)
452 goto out;
455 * Save FPU state to signal context. Signal handler will "inherit"
456 * current FPU state.
458 if (!is_fpu_owner()) {
459 own_fpu();
460 restore_fp(current);
462 err |= save_fp_context(sc);
464 out:
465 return err;
469 * Determine which stack to use..
471 static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
472 size_t frame_size)
474 unsigned long sp;
476 /* Default to using normal stack */
477 sp = regs->regs[29];
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.
484 sp -= 32;
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;
490 return (void *)((sp - frame_size) & ALMASK);
493 static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
494 int signr, sigset_t *set)
496 struct sigframe *frame;
497 int err = 0;
499 frame = get_sigframe(ka, regs, sizeof(*frame));
500 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
501 goto give_sigsegv;
504 * Set up the return code ...
506 * li v0, __NR_O32_sigreturn
507 * syscall
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);
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;
519 * Arguments to signal handler:
521 * a0 = signal number
522 * a1 = 0 (should be cause)
523 * a2 = pointer to struct sigcontext
525 * $25 and c0_epc point to the signal handler, $29 points to the
526 * struct sigframe.
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;
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;
542 give_sigsegv:
543 if (signr == SIGSEGV)
544 ka->sa.sa_handler = SIG_DFL;
545 force_sig(SIGSEGV, current);
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)
552 struct rt_sigframe32 *frame;
553 int err = 0;
555 frame = get_sigframe(ka, regs, sizeof(*frame));
556 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
557 goto give_sigsegv;
559 /* Set up to return from userspace. If provided, use a stub already
560 in userspace. */
562 * Set up the return code ...
564 * li v0, __NR_O32_rt_sigreturn
565 * syscall
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);
571 /* Convert (siginfo_t -> siginfo_t32) and copy to user. */
572 err |= copy_siginfo_to_user32(&frame->rs_info, info);
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));
586 if (err)
587 goto give_sigsegv;
590 * Arguments to signal handler:
592 * a0 = signal number
593 * a1 = 0 (should be cause)
594 * a2 = pointer to ucontext
596 * $25 and c0_epc point to the signal handler, $29 points to
597 * the struct rt_sigframe32.
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;
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;
613 give_sigsegv:
614 if (signr == SIGSEGV)
615 ka->sa.sa_handler = SIG_DFL;
616 force_sig(SIGSEGV, current);
619 static inline void handle_signal(unsigned long sig, siginfo_t *info,
620 sigset_t *oldset, struct pt_regs * regs)
622 struct k_sigaction *ka = &current->sighand->action[sig-1];
624 switch (regs->regs[0]) {
625 case ERESTART_RESTARTBLOCK:
626 current_thread_info()->restart_block.fn = do_no_restart_syscall;
627 case ERESTARTNOHAND:
628 regs->regs[2] = EINTR;
629 break;
630 case ERESTARTSYS:
631 if(!(ka->sa.sa_flags & SA_RESTART)) {
632 regs->regs[2] = EINTR;
633 break;
635 /* fallthrough */
636 case ERESTARTNOINTR: /* Userland will reload $v0. */
637 regs->regs[7] = regs->regs[26];
638 regs->cp0_epc -= 8;
641 regs->regs[0] = 0; /* Don't deal with this again. */
643 if (ka->sa.sa_flags & SA_SIGINFO)
644 setup_rt_frame(ka, regs, sig, oldset, info);
645 else
646 setup_frame(ka, regs, sig, oldset);
648 if (ka->sa.sa_flags & SA_ONESHOT)
649 ka->sa.sa_handler = SIG_DFL;
650 if (!(ka->sa.sa_flags & SA_NODEFER)) {
651 spin_lock_irq(&current->sighand->siglock);
652 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
653 sigaddset(&current->blocked,sig);
654 recalc_sigpending();
655 spin_unlock_irq(&current->sighand->siglock);
659 asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
661 siginfo_t info;
662 int signr;
664 if (!oldset)
665 oldset = &current->blocked;
667 signr = get_signal_to_deliver(&info, regs, NULL);
668 if (signr > 0) {
669 handle_signal(signr, &info, oldset, regs);
670 return 1;
674 * Who's code doesn't conform to the restartable syscall convention
675 * dies here!!! The li instruction, a single machine instruction,
676 * must directly be followed by the syscall instruction.
678 if (regs->regs[0]) {
679 if (regs->regs[2] == ERESTARTNOHAND ||
680 regs->regs[2] == ERESTARTSYS ||
681 regs->regs[2] == ERESTARTNOINTR) {
682 regs->regs[7] = regs->regs[26];
683 regs->cp0_epc -= 8;
685 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
686 regs->regs[2] = __NR_O32_restart_syscall;
687 regs->cp0_epc -= 4;
690 return 0;
693 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
694 struct sigaction32 *oact,
695 unsigned int sigsetsize)
697 struct k_sigaction new_sa, old_sa;
698 int ret = -EINVAL;
700 /* XXX: Don't preclude handling different sized sigset_t's. */
701 if (sigsetsize != sizeof(sigset_t))
702 goto out;
704 if (act) {
705 int err = 0;
707 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
708 return -EFAULT;
709 err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
710 &act->sa_handler);
711 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
712 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
713 if (err)
714 return -EFAULT;
717 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
719 if (!ret && oact) {
720 int err = 0;
722 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
723 return -EFAULT;
725 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
726 &oact->sa_handler);
727 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
728 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
729 if (err)
730 return -EFAULT;
732 out:
733 return ret;
736 asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
737 size_t sigsetsize);
739 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
740 compat_sigset_t *oset, unsigned int sigsetsize)
742 sigset_t old_set, new_set;
743 int ret;
744 mm_segment_t old_fs = get_fs();
746 if (set && get_sigset(&new_set, set))
747 return -EFAULT;
749 set_fs (KERNEL_DS);
750 ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
751 oset ? &old_set : NULL, sigsetsize);
752 set_fs (old_fs);
754 if (!ret && oset && put_sigset(&old_set, oset))
755 return -EFAULT;
757 return ret;
760 asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
762 asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
763 unsigned int sigsetsize)
765 int ret;
766 sigset_t set;
767 mm_segment_t old_fs = get_fs();
769 set_fs (KERNEL_DS);
770 ret = sys_rt_sigpending(&set, sigsetsize);
771 set_fs (old_fs);
773 if (!ret && put_sigset(&set, uset))
774 return -EFAULT;
776 return ret;
779 asmlinkage int sys32_rt_sigtimedwait(compat_sigset_t *uthese,
780 siginfo_t32 *uinfo, struct compat_timespec *uts,
781 compat_time_t sigsetsize)
783 int ret, sig;
784 sigset_t these;
785 compat_sigset_t these32;
786 struct timespec ts;
787 siginfo_t info;
788 long timeout = 0;
791 * As the result of a brainfarting competition a few years ago the
792 * size of sigset_t for the 32-bit kernel was choosen to be 128 bits
793 * but nothing so far is actually using that many, 64 are enough. So
794 * for now we just drop the high bits.
796 if (copy_from_user (&these32, uthese, sizeof(compat_old_sigset_t)))
797 return -EFAULT;
799 switch (_NSIG_WORDS) {
800 #ifdef __MIPSEB__
801 case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
802 case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
803 case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
804 case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
805 #endif
806 #ifdef __MIPSEL__
807 case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32);
808 case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32);
809 case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32);
810 case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32);
811 #endif
815 * Invert the set of allowed signals to get those we
816 * want to block.
818 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
819 signotset(&these);
821 if (uts) {
822 if (get_user (ts.tv_sec, &uts->tv_sec) ||
823 get_user (ts.tv_nsec, &uts->tv_nsec))
824 return -EINVAL;
825 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
826 || ts.tv_sec < 0)
827 return -EINVAL;
830 spin_lock_irq(&current->sighand->siglock);
831 sig = dequeue_signal(current, &these, &info);
832 if (!sig) {
833 /* None ready -- temporarily unblock those we're interested
834 in so that we'll be awakened when they arrive. */
835 sigset_t oldblocked = current->blocked;
836 sigandsets(&current->blocked, &current->blocked, &these);
837 recalc_sigpending();
838 spin_unlock_irq(&current->sighand->siglock);
840 timeout = MAX_SCHEDULE_TIMEOUT;
841 if (uts)
842 timeout = (timespec_to_jiffies(&ts)
843 + (ts.tv_sec || ts.tv_nsec));
845 current->state = TASK_INTERRUPTIBLE;
846 timeout = schedule_timeout(timeout);
848 spin_lock_irq(&current->sighand->siglock);
849 sig = dequeue_signal(current, &these, &info);
850 current->blocked = oldblocked;
851 recalc_sigpending();
853 spin_unlock_irq(&current->sighand->siglock);
855 if (sig) {
856 ret = sig;
857 if (uinfo) {
858 if (copy_siginfo_to_user32(uinfo, &info))
859 ret = -EFAULT;
861 } else {
862 ret = -EAGAIN;
863 if (timeout)
864 ret = -EINTR;
867 return ret;
870 extern asmlinkage int sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
872 asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
874 siginfo_t info;
875 int ret;
876 mm_segment_t old_fs = get_fs();
878 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
879 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
880 return -EFAULT;
881 set_fs (KERNEL_DS);
882 ret = sys_rt_sigqueueinfo(pid, sig, &info);
883 set_fs (old_fs);
884 return ret;