MIPS: Cleanup signal code initialization
[linux-2.6-block.git] / arch / mips / kernel / signal32.c
CommitLineData
1da177e4
LT
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
dda73d0b 7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
1da177e4
LT
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */
02416dcf 10#include <linux/cache.h>
431dc804 11#include <linux/compat.h>
1da177e4
LT
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
1da177e4
LT
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>
1da177e4
LT
21#include <linux/suspend.h>
22#include <linux/compiler.h>
faea6234 23#include <linux/uaccess.h>
1da177e4 24
e50c0a8f 25#include <asm/abi.h>
1da177e4 26#include <asm/asm.h>
431dc804 27#include <asm/compat-signal.h>
1da177e4
LT
28#include <linux/bitops.h>
29#include <asm/cacheflush.h>
30#include <asm/sim.h>
1da177e4
LT
31#include <asm/ucontext.h>
32#include <asm/system.h>
33#include <asm/fpu.h>
02416dcf 34#include <asm/war.h>
1da177e4 35
36a1f2c2
FBH
36#include "signal-common.h"
37
137f6f3e
RB
38static int (*save_fp_context32)(struct sigcontext32 __user *sc);
39static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
40
41extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
42extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
43
44extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
45extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
46
1da177e4
LT
47/*
48 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
49 */
50#define __NR_O32_sigreturn 4119
51#define __NR_O32_rt_sigreturn 4193
151fd6ac 52#define __NR_O32_restart_syscall 4253
1da177e4 53
1da177e4
LT
54/* 32-bit compatibility types */
55
1da177e4
LT
56typedef unsigned int __sighandler32_t;
57typedef void (*vfptr_t)(void);
58
59struct sigaction32 {
60 unsigned int sa_flags;
61 __sighandler32_t sa_handler;
62 compat_sigset_t sa_mask;
63};
64
65/* IRIX compatible stack_t */
66typedef struct sigaltstack32 {
67 s32 ss_sp;
68 compat_size_t ss_size;
69 int ss_flags;
70} stack32_t;
71
72struct ucontext32 {
73 u32 uc_flags;
74 s32 uc_link;
75 stack32_t uc_stack;
76 struct sigcontext32 uc_mcontext;
01ee6037 77 compat_sigset_t uc_sigmask; /* mask last for extensibility */
1da177e4
LT
78};
79
dd02f06a
RB
80/*
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.
84 */
c0b9bae9
FBH
85#if ICACHE_REFILLS_WORKAROUND_WAR == 0
86
dd02f06a
RB
87struct sigframe32 {
88 u32 sf_ass[4]; /* argument save space for o32 */
89 u32 sf_code[2]; /* signal trampoline */
90 struct sigcontext32 sf_sc;
755f21bb 91 compat_sigset_t sf_mask;
dd02f06a
RB
92};
93
c0b9bae9
FBH
94struct 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;
99};
100
101#else /* ICACHE_REFILLS_WORKAROUND_WAR */
102
dd02f06a
RB
103struct sigframe32 {
104 u32 sf_ass[4]; /* argument save space for o32 */
105 u32 sf_pad[2];
106 struct sigcontext32 sf_sc; /* hw context */
755f21bb 107 compat_sigset_t sf_mask;
dd02f06a
RB
108 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
109};
110
c0b9bae9
FBH
111struct 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 */
117};
118
119#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
120
9432a9ba
FBH
121/*
122 * sigcontext handlers
123 */
faea6234
AN
124static int protected_save_fp_context32(struct sigcontext32 __user *sc)
125{
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 */
140 }
141 return err;
142}
143
144static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
145{
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 */
160 }
161 return err;
162}
163
9432a9ba
FBH
164static int setup_sigcontext32(struct pt_regs *regs,
165 struct sigcontext32 __user *sc)
166{
167 int err = 0;
168 int i;
53dc8028 169 u32 used_math;
9432a9ba
FBH
170
171 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
9432a9ba
FBH
172
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]);
176
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);
187 }
188
53dc8028
AN
189 used_math = !!used_math();
190 err |= __put_user(used_math, &sc->sc_used_math);
9432a9ba 191
53dc8028 192 if (used_math) {
9432a9ba
FBH
193 /*
194 * Save FPU state to signal context. Signal handler
195 * will "inherit" current FPU state.
196 */
faea6234 197 err |= protected_save_fp_context32(sc);
9432a9ba
FBH
198 }
199 return err;
200}
201
c6a2f467
AN
202static int
203check_and_restore_fp_context32(struct sigcontext32 __user *sc)
204{
205 int err, sig;
206
207 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
208 if (err > 0)
209 err = 0;
faea6234 210 err |= protected_restore_fp_context32(sc);
c6a2f467
AN
211 return err ?: sig;
212}
213
9432a9ba
FBH
214static int restore_sigcontext32(struct pt_regs *regs,
215 struct sigcontext32 __user *sc)
216{
217 u32 used_math;
218 int err = 0;
219 s32 treg;
220 int i;
221
222 /* Always make any pending restarted system calls return -EINTR */
223 current_thread_info()->restart_block.fn = do_no_restart_syscall;
224
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);
236 }
237
238 for (i = 1; i < 32; i++)
239 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
240
241 err |= __get_user(used_math, &sc->sc_used_math);
242 conditional_used_math(used_math);
243
53dc8028 244 if (used_math) {
9432a9ba 245 /* restore fpu context if we have used it before */
c6a2f467
AN
246 if (!err)
247 err = check_and_restore_fp_context32(sc);
9432a9ba
FBH
248 } else {
249 /* signal handler may have used FPU. Give it up. */
53dc8028 250 lose_fpu(0);
9432a9ba
FBH
251 }
252
9432a9ba
FBH
253 return err;
254}
255
256/*
257 *
258 */
1da177e4
LT
259extern void __put_sigset_unknown_nsig(void);
260extern void __get_sigset_unknown_nsig(void);
261
9bbf28a3 262static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
1da177e4
LT
263{
264 int err = 0;
265
266 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
267 return -EFAULT;
268
269 switch (_NSIG_WORDS) {
270 default:
271 __put_sigset_unknown_nsig();
272 case 2:
49a89efb
RB
273 err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
274 err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
1da177e4 275 case 1:
49a89efb
RB
276 err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
277 err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
1da177e4
LT
278 }
279
280 return err;
281}
282
9c6031cc 283static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
1da177e4
LT
284{
285 int err = 0;
286 unsigned long sig[4];
287
288 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
289 return -EFAULT;
290
291 switch (_NSIG_WORDS) {
292 default:
293 __get_sigset_unknown_nsig();
294 case 2:
49a89efb
RB
295 err |= __get_user(sig[3], &ubuf->sig[3]);
296 err |= __get_user(sig[2], &ubuf->sig[2]);
1da177e4
LT
297 kbuf->sig[1] = sig[2] | (sig[3] << 32);
298 case 1:
49a89efb
RB
299 err |= __get_user(sig[1], &ubuf->sig[1]);
300 err |= __get_user(sig[0], &ubuf->sig[0]);
1da177e4
LT
301 kbuf->sig[0] = sig[0] | (sig[1] << 32);
302 }
303
304 return err;
305}
306
307/*
308 * Atomically swap in the new signal mask, and wait for a signal.
309 */
310
f90080a0 311asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
1da177e4 312{
9c6031cc 313 compat_sigset_t __user *uset;
68fa383f 314 sigset_t newset;
1da177e4 315
9c6031cc 316 uset = (compat_sigset_t __user *) regs.regs[4];
1da177e4
LT
317 if (get_sigset(&newset, uset))
318 return -EFAULT;
319 sigdelsetmask(&newset, ~_BLOCKABLE);
320
321 spin_lock_irq(&current->sighand->siglock);
68fa383f 322 current->saved_sigmask = current->blocked;
1da177e4
LT
323 current->blocked = newset;
324 recalc_sigpending();
325 spin_unlock_irq(&current->sighand->siglock);
326
68fa383f
MM
327 current->state = TASK_INTERRUPTIBLE;
328 schedule();
329 set_thread_flag(TIF_RESTORE_SIGMASK);
330 return -ERESTARTNOHAND;
1da177e4
LT
331}
332
f90080a0 333asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
1da177e4 334{
9c6031cc 335 compat_sigset_t __user *uset;
68fa383f 336 sigset_t newset;
304416da 337 size_t sigsetsize;
1da177e4
LT
338
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;
343
9c6031cc 344 uset = (compat_sigset_t __user *) regs.regs[4];
1da177e4
LT
345 if (get_sigset(&newset, uset))
346 return -EFAULT;
347 sigdelsetmask(&newset, ~_BLOCKABLE);
348
349 spin_lock_irq(&current->sighand->siglock);
68fa383f 350 current->saved_sigmask = current->blocked;
1da177e4 351 current->blocked = newset;
6254944f 352 recalc_sigpending();
1da177e4
LT
353 spin_unlock_irq(&current->sighand->siglock);
354
68fa383f
MM
355 current->state = TASK_INTERRUPTIBLE;
356 schedule();
357 set_thread_flag(TIF_RESTORE_SIGMASK);
358 return -ERESTARTNOHAND;
1da177e4
LT
359}
360
dbda6ac0
RB
361SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
362 struct sigaction32 __user *, oact)
1da177e4
LT
363{
364 struct k_sigaction new_ka, old_ka;
365 int ret;
366 int err = 0;
367
368 if (act) {
369 old_sigset_t mask;
77c728c2 370 s32 handler;
1da177e4
LT
371
372 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
373 return -EFAULT;
77c728c2 374 err |= __get_user(handler, &act->sa_handler);
9bbf28a3 375 new_ka.sa.sa_handler = (void __user *)(s64)handler;
1da177e4
LT
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;
380
381 siginitset(&new_ka.sa.sa_mask, mask);
382 }
383
384 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
385
386 if (!ret && oact) {
387 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
6254944f 388 return -EFAULT;
1da177e4
LT
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);
6254944f
MM
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)
1da177e4
LT
397 return -EFAULT;
398 }
399
400 return ret;
401}
402
403asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
404{
9bbf28a3
AN
405 const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
406 stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
1da177e4
LT
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;
412
413 if (uss) {
414 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
415 return -EFAULT;
416 err |= __get_user(sp, &uss->ss_sp);
9c6031cc 417 kss.ss_sp = (void __user *) (long) sp;
1da177e4
LT
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;
422 }
423
49a89efb 424 set_fs(KERNEL_DS);
9bbf28a3
AN
425 ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
426 uoss ? (stack_t __user *)&koss : NULL, usp);
49a89efb 427 set_fs(old_fs);
1da177e4
LT
428
429 if (!ret && uoss) {
430 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
431 return -EFAULT;
9c6031cc 432 sp = (int) (unsigned long) koss.ss_sp;
1da177e4
LT
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;
438 }
439 return ret;
440}
441
9bbf28a3 442int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
1da177e4
LT
443{
444 int err;
445
446 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
447 return -EFAULT;
448
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) {
a982099c
RB
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;
1da177e4
LT
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:
5665a0ac 477 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
1da177e4
LT
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;
489 }
490 }
491 return err;
492}
493
5d9a76cd
TB
494int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
495{
496 memset(to, 0, sizeof *to);
497
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;
502
503 return 0;
504}
505
f90080a0 506asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
1da177e4 507{
dd02f06a 508 struct sigframe32 __user *frame;
1da177e4 509 sigset_t blocked;
c6a2f467 510 int sig;
1da177e4 511
dd02f06a 512 frame = (struct sigframe32 __user *) regs.regs[29];
1da177e4
LT
513 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
514 goto badframe;
431dc804 515 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
1da177e4
LT
516 goto badframe;
517
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);
523
c6a2f467
AN
524 sig = restore_sigcontext32(&regs, &frame->sf_sc);
525 if (sig < 0)
1da177e4 526 goto badframe;
c6a2f467
AN
527 else if (sig)
528 force_sig(sig, current);
1da177e4
LT
529
530 /*
531 * Don't let your children do this ...
532 */
1da177e4
LT
533 __asm__ __volatile__(
534 "move\t$29, %0\n\t"
535 "j\tsyscall_exit"
536 :/* no outputs */
537 :"r" (&regs));
538 /* Unreached */
539
540badframe:
541 force_sig(SIGSEGV, current);
542}
543
f90080a0 544asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
1da177e4 545{
9bbf28a3 546 struct rt_sigframe32 __user *frame;
1fcf1cc7 547 mm_segment_t old_fs;
1da177e4
LT
548 sigset_t set;
549 stack_t st;
550 s32 sp;
c6a2f467 551 int sig;
1da177e4 552
9bbf28a3 553 frame = (struct rt_sigframe32 __user *) regs.regs[29];
1da177e4
LT
554 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
555 goto badframe;
431dc804 556 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
1da177e4
LT
557 goto badframe;
558
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);
564
c6a2f467
AN
565 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
566 if (sig < 0)
1da177e4 567 goto badframe;
c6a2f467
AN
568 else if (sig)
569 force_sig(sig, current);
1da177e4
LT
570
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;
9c6031cc 574 st.ss_sp = (void __user *)(long) sp;
1da177e4
LT
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;
579
580 /* It is more difficult to avoid calling this function than to
581 call it and ignore errors. */
1fcf1cc7 582 old_fs = get_fs();
49a89efb 583 set_fs(KERNEL_DS);
9bbf28a3 584 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
49a89efb 585 set_fs(old_fs);
1da177e4
LT
586
587 /*
588 * Don't let your children do this ...
589 */
590 __asm__ __volatile__(
591 "move\t$29, %0\n\t"
592 "j\tsyscall_exit"
593 :/* no outputs */
594 :"r" (&regs));
595 /* Unreached */
596
597badframe:
598 force_sig(SIGSEGV, current);
599}
600
151fd6ac 601static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
16cd3951 602 int signr, sigset_t *set)
1da177e4 603{
dd02f06a 604 struct sigframe32 __user *frame;
1da177e4
LT
605 int err = 0;
606
607 frame = get_sigframe(ka, regs, sizeof(*frame));
608 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
609 goto give_sigsegv;
610
36a1f2c2 611 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
1da177e4
LT
612
613 err |= setup_sigcontext32(regs, &frame->sf_sc);
431dc804
RB
614 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
615
1da177e4
LT
616 if (err)
617 goto give_sigsegv;
618
619 /*
620 * Arguments to signal handler:
621 *
622 * a0 = signal number
623 * a1 = 0 (should be cause)
624 * a2 = pointer to struct sigcontext
625 *
626 * $25 and c0_epc point to the signal handler, $29 points to the
627 * struct sigframe.
628 */
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;
635
722bb63d 636 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1da177e4 637 current->comm, current->pid,
722bb63d
FBH
638 frame, regs->cp0_epc, regs->regs[31]);
639
7b3e2fc8 640 return 0;
1da177e4
LT
641
642give_sigsegv:
643 force_sigsegv(signr, current);
7b3e2fc8 644 return -EFAULT;
1da177e4
LT
645}
646
151fd6ac 647static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
16cd3951 648 int signr, sigset_t *set, siginfo_t *info)
1da177e4 649{
9bbf28a3 650 struct rt_sigframe32 __user *frame;
1da177e4
LT
651 int err = 0;
652 s32 sp;
653
654 frame = get_sigframe(ka, regs, sizeof(*frame));
655 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
656 goto give_sigsegv;
657
36a1f2c2 658 err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
1da177e4
LT
659
660 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
661 err |= copy_siginfo_to_user32(&frame->rs_info, info);
662
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);
431dc804 674 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
1da177e4
LT
675
676 if (err)
677 goto give_sigsegv;
678
679 /*
680 * Arguments to signal handler:
681 *
682 * a0 = signal number
683 * a1 = 0 (should be cause)
684 * a2 = pointer to ucontext
685 *
686 * $25 and c0_epc point to the signal handler, $29 points to
687 * the struct rt_sigframe32.
688 */
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;
695
722bb63d 696 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1da177e4 697 current->comm, current->pid,
722bb63d
FBH
698 frame, regs->cp0_epc, regs->regs[31]);
699
7b3e2fc8 700 return 0;
1da177e4
LT
701
702give_sigsegv:
703 force_sigsegv(signr, current);
7b3e2fc8 704 return -EFAULT;
1da177e4
LT
705}
706
151fd6ac
RB
707/*
708 * o32 compatibility on 64-bit kernels, without DSP ASE
709 */
710struct 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
714};
1da177e4 715
dbda6ac0
RB
716SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
717 const struct sigaction32 __user *, act,
718 struct sigaction32 __user *, oact, unsigned int, sigsetsize)
1da177e4
LT
719{
720 struct k_sigaction new_sa, old_sa;
721 int ret = -EINVAL;
722
723 /* XXX: Don't preclude handling different sized sigset_t's. */
724 if (sigsetsize != sizeof(sigset_t))
725 goto out;
726
727 if (act) {
77c728c2 728 s32 handler;
1da177e4
LT
729 int err = 0;
730
731 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
732 return -EFAULT;
77c728c2 733 err |= __get_user(handler, &act->sa_handler);
9bbf28a3 734 new_sa.sa.sa_handler = (void __user *)(s64)handler;
1da177e4
LT
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;
739 }
740
741 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
742
743 if (!ret && oact) {
744 int err = 0;
745
746 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
747 return -EFAULT;
748
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;
755 }
756out:
757 return ret;
758}
759
dbda6ac0
RB
760SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
761 compat_sigset_t __user *, oset, unsigned int, sigsetsize)
1da177e4
LT
762{
763 sigset_t old_set, new_set;
764 int ret;
765 mm_segment_t old_fs = get_fs();
766
767 if (set && get_sigset(&new_set, set))
768 return -EFAULT;
769
49a89efb 770 set_fs(KERNEL_DS);
9bbf28a3
AN
771 ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
772 oset ? (sigset_t __user *)&old_set : NULL,
773 sigsetsize);
49a89efb 774 set_fs(old_fs);
1da177e4
LT
775
776 if (!ret && oset && put_sigset(&old_set, oset))
777 return -EFAULT;
778
779 return ret;
780}
781
dbda6ac0
RB
782SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
783 unsigned int, sigsetsize)
1da177e4
LT
784{
785 int ret;
786 sigset_t set;
787 mm_segment_t old_fs = get_fs();
788
49a89efb 789 set_fs(KERNEL_DS);
9bbf28a3 790 ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
49a89efb 791 set_fs(old_fs);
1da177e4
LT
792
793 if (!ret && put_sigset(&set, uset))
794 return -EFAULT;
795
796 return ret;
797}
798
dbda6ac0
RB
799SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
800 compat_siginfo_t __user *, uinfo)
1da177e4
LT
801{
802 siginfo_t info;
803 int ret;
804 mm_segment_t old_fs = get_fs();
805
49a89efb
RB
806 if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
807 copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
1da177e4 808 return -EFAULT;
49a89efb 809 set_fs(KERNEL_DS);
9bbf28a3 810 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
49a89efb 811 set_fs(old_fs);
1da177e4
LT
812 return ret;
813}
54f2da75 814
dbda6ac0
RB
815SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
816 compat_siginfo_t __user *, uinfo, int, options,
817 struct compat_rusage __user *, uru)
54f2da75
RB
818{
819 siginfo_t info;
820 struct rusage ru;
821 long ret;
822 mm_segment_t old_fs = get_fs();
823
824 info.si_signo = 0;
49a89efb 825 set_fs(KERNEL_DS);
54f2da75
RB
826 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
827 uru ? (struct rusage __user *) &ru : NULL);
49a89efb 828 set_fs(old_fs);
54f2da75
RB
829
830 if (ret < 0 || info.si_signo == 0)
831 return ret;
832
833 if (uru && (ret = put_compat_rusage(&ru, uru)))
834 return ret;
835
836 BUG_ON(info.si_code & __SI_MASK);
837 info.si_code |= __SI_CHLD;
838 return copy_siginfo_to_user32(uinfo, &info);
839}
137f6f3e
RB
840
841static int signal32_init(void)
842{
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;
849 }
850
851 return 0;
852}
853
854arch_initcall(signal32_init);