Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
[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
1da177e4
LT
38/*
39 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
40 */
41#define __NR_O32_sigreturn 4119
42#define __NR_O32_rt_sigreturn 4193
151fd6ac 43#define __NR_O32_restart_syscall 4253
1da177e4 44
1da177e4
LT
45/* 32-bit compatibility types */
46
1da177e4
LT
47typedef unsigned int __sighandler32_t;
48typedef void (*vfptr_t)(void);
49
50struct sigaction32 {
51 unsigned int sa_flags;
52 __sighandler32_t sa_handler;
53 compat_sigset_t sa_mask;
54};
55
56/* IRIX compatible stack_t */
57typedef struct sigaltstack32 {
58 s32 ss_sp;
59 compat_size_t ss_size;
60 int ss_flags;
61} stack32_t;
62
63struct ucontext32 {
64 u32 uc_flags;
65 s32 uc_link;
66 stack32_t uc_stack;
67 struct sigcontext32 uc_mcontext;
01ee6037 68 compat_sigset_t uc_sigmask; /* mask last for extensibility */
1da177e4
LT
69};
70
dd02f06a
RB
71/*
72 * Horribly complicated - with the bloody RM9000 workarounds enabled
73 * the signal trampolines is moving to the end of the structure so we can
74 * increase the alignment without breaking software compatibility.
75 */
c0b9bae9
FBH
76#if ICACHE_REFILLS_WORKAROUND_WAR == 0
77
dd02f06a
RB
78struct sigframe32 {
79 u32 sf_ass[4]; /* argument save space for o32 */
80 u32 sf_code[2]; /* signal trampoline */
81 struct sigcontext32 sf_sc;
755f21bb 82 compat_sigset_t sf_mask;
dd02f06a
RB
83};
84
c0b9bae9
FBH
85struct rt_sigframe32 {
86 u32 rs_ass[4]; /* argument save space for o32 */
87 u32 rs_code[2]; /* signal trampoline */
88 compat_siginfo_t rs_info;
89 struct ucontext32 rs_uc;
90};
91
92#else /* ICACHE_REFILLS_WORKAROUND_WAR */
93
dd02f06a
RB
94struct sigframe32 {
95 u32 sf_ass[4]; /* argument save space for o32 */
96 u32 sf_pad[2];
97 struct sigcontext32 sf_sc; /* hw context */
755f21bb 98 compat_sigset_t sf_mask;
dd02f06a
RB
99 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
100};
101
c0b9bae9
FBH
102struct rt_sigframe32 {
103 u32 rs_ass[4]; /* argument save space for o32 */
104 u32 rs_pad[2];
105 compat_siginfo_t rs_info;
106 struct ucontext32 rs_uc;
107 u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
108};
109
110#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
111
9432a9ba
FBH
112/*
113 * sigcontext handlers
114 */
faea6234
AN
115static int protected_save_fp_context32(struct sigcontext32 __user *sc)
116{
117 int err;
118 while (1) {
119 lock_fpu_owner();
120 own_fpu_inatomic(1);
121 err = save_fp_context32(sc); /* this might fail */
122 unlock_fpu_owner();
123 if (likely(!err))
124 break;
125 /* touch the sigcontext and try again */
126 err = __put_user(0, &sc->sc_fpregs[0]) |
127 __put_user(0, &sc->sc_fpregs[31]) |
128 __put_user(0, &sc->sc_fpc_csr);
129 if (err)
130 break; /* really bad sigcontext */
131 }
132 return err;
133}
134
135static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
136{
137 int err, tmp;
138 while (1) {
139 lock_fpu_owner();
140 own_fpu_inatomic(0);
141 err = restore_fp_context32(sc); /* this might fail */
142 unlock_fpu_owner();
143 if (likely(!err))
144 break;
145 /* touch the sigcontext and try again */
146 err = __get_user(tmp, &sc->sc_fpregs[0]) |
147 __get_user(tmp, &sc->sc_fpregs[31]) |
148 __get_user(tmp, &sc->sc_fpc_csr);
149 if (err)
150 break; /* really bad sigcontext */
151 }
152 return err;
153}
154
9432a9ba
FBH
155static int setup_sigcontext32(struct pt_regs *regs,
156 struct sigcontext32 __user *sc)
157{
158 int err = 0;
159 int i;
53dc8028 160 u32 used_math;
9432a9ba
FBH
161
162 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
9432a9ba
FBH
163
164 err |= __put_user(0, &sc->sc_regs[0]);
165 for (i = 1; i < 32; i++)
166 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
167
168 err |= __put_user(regs->hi, &sc->sc_mdhi);
169 err |= __put_user(regs->lo, &sc->sc_mdlo);
170 if (cpu_has_dsp) {
171 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
172 err |= __put_user(mfhi1(), &sc->sc_hi1);
173 err |= __put_user(mflo1(), &sc->sc_lo1);
174 err |= __put_user(mfhi2(), &sc->sc_hi2);
175 err |= __put_user(mflo2(), &sc->sc_lo2);
176 err |= __put_user(mfhi3(), &sc->sc_hi3);
177 err |= __put_user(mflo3(), &sc->sc_lo3);
178 }
179
53dc8028
AN
180 used_math = !!used_math();
181 err |= __put_user(used_math, &sc->sc_used_math);
9432a9ba 182
53dc8028 183 if (used_math) {
9432a9ba
FBH
184 /*
185 * Save FPU state to signal context. Signal handler
186 * will "inherit" current FPU state.
187 */
faea6234 188 err |= protected_save_fp_context32(sc);
9432a9ba
FBH
189 }
190 return err;
191}
192
c6a2f467
AN
193static int
194check_and_restore_fp_context32(struct sigcontext32 __user *sc)
195{
196 int err, sig;
197
198 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
199 if (err > 0)
200 err = 0;
faea6234 201 err |= protected_restore_fp_context32(sc);
c6a2f467
AN
202 return err ?: sig;
203}
204
9432a9ba
FBH
205static int restore_sigcontext32(struct pt_regs *regs,
206 struct sigcontext32 __user *sc)
207{
208 u32 used_math;
209 int err = 0;
210 s32 treg;
211 int i;
212
213 /* Always make any pending restarted system calls return -EINTR */
214 current_thread_info()->restart_block.fn = do_no_restart_syscall;
215
216 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
217 err |= __get_user(regs->hi, &sc->sc_mdhi);
218 err |= __get_user(regs->lo, &sc->sc_mdlo);
219 if (cpu_has_dsp) {
220 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
221 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
222 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
223 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
224 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
225 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
226 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
227 }
228
229 for (i = 1; i < 32; i++)
230 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
231
232 err |= __get_user(used_math, &sc->sc_used_math);
233 conditional_used_math(used_math);
234
53dc8028 235 if (used_math) {
9432a9ba 236 /* restore fpu context if we have used it before */
c6a2f467
AN
237 if (!err)
238 err = check_and_restore_fp_context32(sc);
9432a9ba
FBH
239 } else {
240 /* signal handler may have used FPU. Give it up. */
53dc8028 241 lose_fpu(0);
9432a9ba
FBH
242 }
243
9432a9ba
FBH
244 return err;
245}
246
247/*
248 *
249 */
1da177e4
LT
250extern void __put_sigset_unknown_nsig(void);
251extern void __get_sigset_unknown_nsig(void);
252
9bbf28a3 253static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
1da177e4
LT
254{
255 int err = 0;
256
257 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
258 return -EFAULT;
259
260 switch (_NSIG_WORDS) {
261 default:
262 __put_sigset_unknown_nsig();
263 case 2:
49a89efb
RB
264 err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
265 err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
1da177e4 266 case 1:
49a89efb
RB
267 err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
268 err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
1da177e4
LT
269 }
270
271 return err;
272}
273
9c6031cc 274static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
1da177e4
LT
275{
276 int err = 0;
277 unsigned long sig[4];
278
279 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
280 return -EFAULT;
281
282 switch (_NSIG_WORDS) {
283 default:
284 __get_sigset_unknown_nsig();
285 case 2:
49a89efb
RB
286 err |= __get_user(sig[3], &ubuf->sig[3]);
287 err |= __get_user(sig[2], &ubuf->sig[2]);
1da177e4
LT
288 kbuf->sig[1] = sig[2] | (sig[3] << 32);
289 case 1:
49a89efb
RB
290 err |= __get_user(sig[1], &ubuf->sig[1]);
291 err |= __get_user(sig[0], &ubuf->sig[0]);
1da177e4
LT
292 kbuf->sig[0] = sig[0] | (sig[1] << 32);
293 }
294
295 return err;
296}
297
298/*
299 * Atomically swap in the new signal mask, and wait for a signal.
300 */
301
f90080a0 302asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
1da177e4 303{
9c6031cc 304 compat_sigset_t __user *uset;
68fa383f 305 sigset_t newset;
1da177e4 306
9c6031cc 307 uset = (compat_sigset_t __user *) regs.regs[4];
1da177e4
LT
308 if (get_sigset(&newset, uset))
309 return -EFAULT;
310 sigdelsetmask(&newset, ~_BLOCKABLE);
311
312 spin_lock_irq(&current->sighand->siglock);
68fa383f 313 current->saved_sigmask = current->blocked;
1da177e4
LT
314 current->blocked = newset;
315 recalc_sigpending();
316 spin_unlock_irq(&current->sighand->siglock);
317
68fa383f
MM
318 current->state = TASK_INTERRUPTIBLE;
319 schedule();
320 set_thread_flag(TIF_RESTORE_SIGMASK);
321 return -ERESTARTNOHAND;
1da177e4
LT
322}
323
f90080a0 324asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
1da177e4 325{
9c6031cc 326 compat_sigset_t __user *uset;
68fa383f 327 sigset_t newset;
304416da 328 size_t sigsetsize;
1da177e4
LT
329
330 /* XXX Don't preclude handling different sized sigset_t's. */
331 sigsetsize = regs.regs[5];
332 if (sigsetsize != sizeof(compat_sigset_t))
333 return -EINVAL;
334
9c6031cc 335 uset = (compat_sigset_t __user *) regs.regs[4];
1da177e4
LT
336 if (get_sigset(&newset, uset))
337 return -EFAULT;
338 sigdelsetmask(&newset, ~_BLOCKABLE);
339
340 spin_lock_irq(&current->sighand->siglock);
68fa383f 341 current->saved_sigmask = current->blocked;
1da177e4 342 current->blocked = newset;
6254944f 343 recalc_sigpending();
1da177e4
LT
344 spin_unlock_irq(&current->sighand->siglock);
345
68fa383f
MM
346 current->state = TASK_INTERRUPTIBLE;
347 schedule();
348 set_thread_flag(TIF_RESTORE_SIGMASK);
349 return -ERESTARTNOHAND;
1da177e4
LT
350}
351
dbda6ac0
RB
352SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
353 struct sigaction32 __user *, oact)
1da177e4
LT
354{
355 struct k_sigaction new_ka, old_ka;
356 int ret;
357 int err = 0;
358
359 if (act) {
360 old_sigset_t mask;
77c728c2 361 s32 handler;
1da177e4
LT
362
363 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
364 return -EFAULT;
77c728c2 365 err |= __get_user(handler, &act->sa_handler);
9bbf28a3 366 new_ka.sa.sa_handler = (void __user *)(s64)handler;
1da177e4
LT
367 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
368 err |= __get_user(mask, &act->sa_mask.sig[0]);
369 if (err)
370 return -EFAULT;
371
372 siginitset(&new_ka.sa.sa_mask, mask);
373 }
374
375 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
376
377 if (!ret && oact) {
378 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
6254944f 379 return -EFAULT;
1da177e4
LT
380 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
381 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
382 &oact->sa_handler);
383 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
6254944f
MM
384 err |= __put_user(0, &oact->sa_mask.sig[1]);
385 err |= __put_user(0, &oact->sa_mask.sig[2]);
386 err |= __put_user(0, &oact->sa_mask.sig[3]);
387 if (err)
1da177e4
LT
388 return -EFAULT;
389 }
390
391 return ret;
392}
393
394asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
395{
9bbf28a3
AN
396 const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
397 stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
1da177e4
LT
398 unsigned long usp = regs.regs[29];
399 stack_t kss, koss;
400 int ret, err = 0;
401 mm_segment_t old_fs = get_fs();
402 s32 sp;
403
404 if (uss) {
405 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
406 return -EFAULT;
407 err |= __get_user(sp, &uss->ss_sp);
9c6031cc 408 kss.ss_sp = (void __user *) (long) sp;
1da177e4
LT
409 err |= __get_user(kss.ss_size, &uss->ss_size);
410 err |= __get_user(kss.ss_flags, &uss->ss_flags);
411 if (err)
412 return -EFAULT;
413 }
414
49a89efb 415 set_fs(KERNEL_DS);
9bbf28a3
AN
416 ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
417 uoss ? (stack_t __user *)&koss : NULL, usp);
49a89efb 418 set_fs(old_fs);
1da177e4
LT
419
420 if (!ret && uoss) {
421 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
422 return -EFAULT;
9c6031cc 423 sp = (int) (unsigned long) koss.ss_sp;
1da177e4
LT
424 err |= __put_user(sp, &uoss->ss_sp);
425 err |= __put_user(koss.ss_size, &uoss->ss_size);
426 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
427 if (err)
428 return -EFAULT;
429 }
430 return ret;
431}
432
9bbf28a3 433int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
1da177e4
LT
434{
435 int err;
436
437 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
438 return -EFAULT;
439
440 /* If you change siginfo_t structure, please be sure
441 this code is fixed accordingly.
442 It should never copy any pad contained in the structure
443 to avoid security leaks, but must copy the generic
444 3 ints plus the relevant union member.
445 This routine must convert siginfo from 64bit to 32bit as well
446 at the same time. */
447 err = __put_user(from->si_signo, &to->si_signo);
448 err |= __put_user(from->si_errno, &to->si_errno);
449 err |= __put_user((short)from->si_code, &to->si_code);
450 if (from->si_code < 0)
451 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
452 else {
453 switch (from->si_code >> 16) {
a982099c
RB
454 case __SI_TIMER >> 16:
455 err |= __put_user(from->si_tid, &to->si_tid);
456 err |= __put_user(from->si_overrun, &to->si_overrun);
457 err |= __put_user(from->si_int, &to->si_int);
458 break;
1da177e4
LT
459 case __SI_CHLD >> 16:
460 err |= __put_user(from->si_utime, &to->si_utime);
461 err |= __put_user(from->si_stime, &to->si_stime);
462 err |= __put_user(from->si_status, &to->si_status);
463 default:
464 err |= __put_user(from->si_pid, &to->si_pid);
465 err |= __put_user(from->si_uid, &to->si_uid);
466 break;
467 case __SI_FAULT >> 16:
5665a0ac 468 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
1da177e4
LT
469 break;
470 case __SI_POLL >> 16:
471 err |= __put_user(from->si_band, &to->si_band);
472 err |= __put_user(from->si_fd, &to->si_fd);
473 break;
474 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
475 case __SI_MESGQ >> 16:
476 err |= __put_user(from->si_pid, &to->si_pid);
477 err |= __put_user(from->si_uid, &to->si_uid);
478 err |= __put_user(from->si_int, &to->si_int);
479 break;
480 }
481 }
482 return err;
483}
484
5d9a76cd
TB
485int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
486{
487 memset(to, 0, sizeof *to);
488
489 if (copy_from_user(to, from, 3*sizeof(int)) ||
490 copy_from_user(to->_sifields._pad,
491 from->_sifields._pad, SI_PAD_SIZE32))
492 return -EFAULT;
493
494 return 0;
495}
496
f90080a0 497asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
1da177e4 498{
dd02f06a 499 struct sigframe32 __user *frame;
1da177e4 500 sigset_t blocked;
c6a2f467 501 int sig;
1da177e4 502
dd02f06a 503 frame = (struct sigframe32 __user *) regs.regs[29];
1da177e4
LT
504 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
505 goto badframe;
431dc804 506 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
1da177e4
LT
507 goto badframe;
508
509 sigdelsetmask(&blocked, ~_BLOCKABLE);
510 spin_lock_irq(&current->sighand->siglock);
511 current->blocked = blocked;
512 recalc_sigpending();
513 spin_unlock_irq(&current->sighand->siglock);
514
c6a2f467
AN
515 sig = restore_sigcontext32(&regs, &frame->sf_sc);
516 if (sig < 0)
1da177e4 517 goto badframe;
c6a2f467
AN
518 else if (sig)
519 force_sig(sig, current);
1da177e4
LT
520
521 /*
522 * Don't let your children do this ...
523 */
1da177e4
LT
524 __asm__ __volatile__(
525 "move\t$29, %0\n\t"
526 "j\tsyscall_exit"
527 :/* no outputs */
528 :"r" (&regs));
529 /* Unreached */
530
531badframe:
532 force_sig(SIGSEGV, current);
533}
534
f90080a0 535asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
1da177e4 536{
9bbf28a3 537 struct rt_sigframe32 __user *frame;
1fcf1cc7 538 mm_segment_t old_fs;
1da177e4
LT
539 sigset_t set;
540 stack_t st;
541 s32 sp;
c6a2f467 542 int sig;
1da177e4 543
9bbf28a3 544 frame = (struct rt_sigframe32 __user *) regs.regs[29];
1da177e4
LT
545 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
546 goto badframe;
431dc804 547 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
1da177e4
LT
548 goto badframe;
549
550 sigdelsetmask(&set, ~_BLOCKABLE);
551 spin_lock_irq(&current->sighand->siglock);
552 current->blocked = set;
553 recalc_sigpending();
554 spin_unlock_irq(&current->sighand->siglock);
555
c6a2f467
AN
556 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
557 if (sig < 0)
1da177e4 558 goto badframe;
c6a2f467
AN
559 else if (sig)
560 force_sig(sig, current);
1da177e4
LT
561
562 /* The ucontext contains a stack32_t, so we must convert! */
563 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
564 goto badframe;
9c6031cc 565 st.ss_sp = (void __user *)(long) sp;
1da177e4
LT
566 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
567 goto badframe;
568 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
569 goto badframe;
570
571 /* It is more difficult to avoid calling this function than to
572 call it and ignore errors. */
1fcf1cc7 573 old_fs = get_fs();
49a89efb 574 set_fs(KERNEL_DS);
9bbf28a3 575 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
49a89efb 576 set_fs(old_fs);
1da177e4
LT
577
578 /*
579 * Don't let your children do this ...
580 */
581 __asm__ __volatile__(
582 "move\t$29, %0\n\t"
583 "j\tsyscall_exit"
584 :/* no outputs */
585 :"r" (&regs));
586 /* Unreached */
587
588badframe:
589 force_sig(SIGSEGV, current);
590}
591
151fd6ac 592static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
16cd3951 593 int signr, sigset_t *set)
1da177e4 594{
dd02f06a 595 struct sigframe32 __user *frame;
1da177e4
LT
596 int err = 0;
597
598 frame = get_sigframe(ka, regs, sizeof(*frame));
599 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
600 goto give_sigsegv;
601
36a1f2c2 602 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
1da177e4
LT
603
604 err |= setup_sigcontext32(regs, &frame->sf_sc);
431dc804
RB
605 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
606
1da177e4
LT
607 if (err)
608 goto give_sigsegv;
609
610 /*
611 * Arguments to signal handler:
612 *
613 * a0 = signal number
614 * a1 = 0 (should be cause)
615 * a2 = pointer to struct sigcontext
616 *
617 * $25 and c0_epc point to the signal handler, $29 points to the
618 * struct sigframe.
619 */
620 regs->regs[ 4] = signr;
621 regs->regs[ 5] = 0;
622 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
623 regs->regs[29] = (unsigned long) frame;
624 regs->regs[31] = (unsigned long) frame->sf_code;
625 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
626
722bb63d 627 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1da177e4 628 current->comm, current->pid,
722bb63d
FBH
629 frame, regs->cp0_epc, regs->regs[31]);
630
7b3e2fc8 631 return 0;
1da177e4
LT
632
633give_sigsegv:
634 force_sigsegv(signr, current);
7b3e2fc8 635 return -EFAULT;
1da177e4
LT
636}
637
151fd6ac 638static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
16cd3951 639 int signr, sigset_t *set, siginfo_t *info)
1da177e4 640{
9bbf28a3 641 struct rt_sigframe32 __user *frame;
1da177e4
LT
642 int err = 0;
643 s32 sp;
644
645 frame = get_sigframe(ka, regs, sizeof(*frame));
646 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
647 goto give_sigsegv;
648
36a1f2c2 649 err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
1da177e4
LT
650
651 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
652 err |= copy_siginfo_to_user32(&frame->rs_info, info);
653
654 /* Create the ucontext. */
655 err |= __put_user(0, &frame->rs_uc.uc_flags);
656 err |= __put_user(0, &frame->rs_uc.uc_link);
657 sp = (int) (long) current->sas_ss_sp;
658 err |= __put_user(sp,
659 &frame->rs_uc.uc_stack.ss_sp);
660 err |= __put_user(sas_ss_flags(regs->regs[29]),
661 &frame->rs_uc.uc_stack.ss_flags);
662 err |= __put_user(current->sas_ss_size,
663 &frame->rs_uc.uc_stack.ss_size);
664 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
431dc804 665 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
1da177e4
LT
666
667 if (err)
668 goto give_sigsegv;
669
670 /*
671 * Arguments to signal handler:
672 *
673 * a0 = signal number
674 * a1 = 0 (should be cause)
675 * a2 = pointer to ucontext
676 *
677 * $25 and c0_epc point to the signal handler, $29 points to
678 * the struct rt_sigframe32.
679 */
680 regs->regs[ 4] = signr;
681 regs->regs[ 5] = (unsigned long) &frame->rs_info;
682 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
683 regs->regs[29] = (unsigned long) frame;
684 regs->regs[31] = (unsigned long) frame->rs_code;
685 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
686
722bb63d 687 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1da177e4 688 current->comm, current->pid,
722bb63d
FBH
689 frame, regs->cp0_epc, regs->regs[31]);
690
7b3e2fc8 691 return 0;
1da177e4
LT
692
693give_sigsegv:
694 force_sigsegv(signr, current);
7b3e2fc8 695 return -EFAULT;
1da177e4
LT
696}
697
151fd6ac
RB
698/*
699 * o32 compatibility on 64-bit kernels, without DSP ASE
700 */
701struct mips_abi mips_abi_32 = {
702 .setup_frame = setup_frame_32,
703 .setup_rt_frame = setup_rt_frame_32,
704 .restart = __NR_O32_restart_syscall
705};
1da177e4 706
dbda6ac0
RB
707SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
708 const struct sigaction32 __user *, act,
709 struct sigaction32 __user *, oact, unsigned int, sigsetsize)
1da177e4
LT
710{
711 struct k_sigaction new_sa, old_sa;
712 int ret = -EINVAL;
713
714 /* XXX: Don't preclude handling different sized sigset_t's. */
715 if (sigsetsize != sizeof(sigset_t))
716 goto out;
717
718 if (act) {
77c728c2 719 s32 handler;
1da177e4
LT
720 int err = 0;
721
722 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
723 return -EFAULT;
77c728c2 724 err |= __get_user(handler, &act->sa_handler);
9bbf28a3 725 new_sa.sa.sa_handler = (void __user *)(s64)handler;
1da177e4
LT
726 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
727 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
728 if (err)
729 return -EFAULT;
730 }
731
732 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
733
734 if (!ret && oact) {
735 int err = 0;
736
737 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
738 return -EFAULT;
739
740 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
741 &oact->sa_handler);
742 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
743 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
744 if (err)
745 return -EFAULT;
746 }
747out:
748 return ret;
749}
750
dbda6ac0
RB
751SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
752 compat_sigset_t __user *, oset, unsigned int, sigsetsize)
1da177e4
LT
753{
754 sigset_t old_set, new_set;
755 int ret;
756 mm_segment_t old_fs = get_fs();
757
758 if (set && get_sigset(&new_set, set))
759 return -EFAULT;
760
49a89efb 761 set_fs(KERNEL_DS);
9bbf28a3
AN
762 ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
763 oset ? (sigset_t __user *)&old_set : NULL,
764 sigsetsize);
49a89efb 765 set_fs(old_fs);
1da177e4
LT
766
767 if (!ret && oset && put_sigset(&old_set, oset))
768 return -EFAULT;
769
770 return ret;
771}
772
dbda6ac0
RB
773SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
774 unsigned int, sigsetsize)
1da177e4
LT
775{
776 int ret;
777 sigset_t set;
778 mm_segment_t old_fs = get_fs();
779
49a89efb 780 set_fs(KERNEL_DS);
9bbf28a3 781 ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
49a89efb 782 set_fs(old_fs);
1da177e4
LT
783
784 if (!ret && put_sigset(&set, uset))
785 return -EFAULT;
786
787 return ret;
788}
789
dbda6ac0
RB
790SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
791 compat_siginfo_t __user *, uinfo)
1da177e4
LT
792{
793 siginfo_t info;
794 int ret;
795 mm_segment_t old_fs = get_fs();
796
49a89efb
RB
797 if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
798 copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
1da177e4 799 return -EFAULT;
49a89efb 800 set_fs(KERNEL_DS);
9bbf28a3 801 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
49a89efb 802 set_fs(old_fs);
1da177e4
LT
803 return ret;
804}
54f2da75 805
dbda6ac0
RB
806SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
807 compat_siginfo_t __user *, uinfo, int, options,
808 struct compat_rusage __user *, uru)
54f2da75
RB
809{
810 siginfo_t info;
811 struct rusage ru;
812 long ret;
813 mm_segment_t old_fs = get_fs();
814
815 info.si_signo = 0;
49a89efb 816 set_fs(KERNEL_DS);
54f2da75
RB
817 ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
818 uru ? (struct rusage __user *) &ru : NULL);
49a89efb 819 set_fs(old_fs);
54f2da75
RB
820
821 if (ret < 0 || info.si_signo == 0)
822 return ret;
823
824 if (uru && (ret = put_compat_rusage(&ru, uru)))
825 return ret;
826
827 BUG_ON(info.si_code & __SI_MASK);
828 info.si_code |= __SI_CHLD;
829 return copy_siginfo_to_user32(uinfo, &info);
830}