Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux/fpc-iii.git] / arch / mips / kernel / signal32.c
blob3d60f7750fa8d873c4651cd362239a0441e24c72
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/fpu.h>
33 #include <asm/war.h>
34 #include <asm/vdso.h>
35 #include <asm/dsp.h>
37 #include "signal-common.h"
39 static int (*save_fp_context32)(struct sigcontext32 __user *sc);
40 static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
42 extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
43 extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
45 extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
46 extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
49 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
51 #define __NR_O32_restart_syscall 4253
53 /* 32-bit compatibility types */
55 typedef unsigned int __sighandler32_t;
56 typedef void (*vfptr_t)(void);
58 struct ucontext32 {
59 u32 uc_flags;
60 s32 uc_link;
61 compat_stack_t uc_stack;
62 struct sigcontext32 uc_mcontext;
63 compat_sigset_t uc_sigmask; /* mask last for extensibility */
66 struct sigframe32 {
67 u32 sf_ass[4]; /* argument save space for o32 */
68 u32 sf_pad[2]; /* Was: signal trampoline */
69 struct sigcontext32 sf_sc;
70 compat_sigset_t sf_mask;
73 struct rt_sigframe32 {
74 u32 rs_ass[4]; /* argument save space for o32 */
75 u32 rs_pad[2]; /* Was: signal trampoline */
76 compat_siginfo_t rs_info;
77 struct ucontext32 rs_uc;
81 * sigcontext handlers
83 static int protected_save_fp_context32(struct sigcontext32 __user *sc)
85 int err;
86 while (1) {
87 lock_fpu_owner();
88 err = own_fpu_inatomic(1);
89 if (!err)
90 err = save_fp_context32(sc); /* this might fail */
91 unlock_fpu_owner();
92 if (likely(!err))
93 break;
94 /* touch the sigcontext and try again */
95 err = __put_user(0, &sc->sc_fpregs[0]) |
96 __put_user(0, &sc->sc_fpregs[31]) |
97 __put_user(0, &sc->sc_fpc_csr);
98 if (err)
99 break; /* really bad sigcontext */
101 return err;
104 static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
106 int err, tmp __maybe_unused;
107 while (1) {
108 lock_fpu_owner();
109 err = own_fpu_inatomic(0);
110 if (!err)
111 err = restore_fp_context32(sc); /* this might fail */
112 unlock_fpu_owner();
113 if (likely(!err))
114 break;
115 /* touch the sigcontext and try again */
116 err = __get_user(tmp, &sc->sc_fpregs[0]) |
117 __get_user(tmp, &sc->sc_fpregs[31]) |
118 __get_user(tmp, &sc->sc_fpc_csr);
119 if (err)
120 break; /* really bad sigcontext */
122 return err;
125 static int setup_sigcontext32(struct pt_regs *regs,
126 struct sigcontext32 __user *sc)
128 int err = 0;
129 int i;
130 u32 used_math;
132 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
134 err |= __put_user(0, &sc->sc_regs[0]);
135 for (i = 1; i < 32; i++)
136 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
138 err |= __put_user(regs->hi, &sc->sc_mdhi);
139 err |= __put_user(regs->lo, &sc->sc_mdlo);
140 if (cpu_has_dsp) {
141 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
142 err |= __put_user(mfhi1(), &sc->sc_hi1);
143 err |= __put_user(mflo1(), &sc->sc_lo1);
144 err |= __put_user(mfhi2(), &sc->sc_hi2);
145 err |= __put_user(mflo2(), &sc->sc_lo2);
146 err |= __put_user(mfhi3(), &sc->sc_hi3);
147 err |= __put_user(mflo3(), &sc->sc_lo3);
150 used_math = !!used_math();
151 err |= __put_user(used_math, &sc->sc_used_math);
153 if (used_math) {
155 * Save FPU state to signal context. Signal handler
156 * will "inherit" current FPU state.
158 err |= protected_save_fp_context32(sc);
160 return err;
163 static int
164 check_and_restore_fp_context32(struct sigcontext32 __user *sc)
166 int err, sig;
168 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
169 if (err > 0)
170 err = 0;
171 err |= protected_restore_fp_context32(sc);
172 return err ?: sig;
175 static int restore_sigcontext32(struct pt_regs *regs,
176 struct sigcontext32 __user *sc)
178 u32 used_math;
179 int err = 0;
180 s32 treg;
181 int i;
183 /* Always make any pending restarted system calls return -EINTR */
184 current_thread_info()->restart_block.fn = do_no_restart_syscall;
186 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
187 err |= __get_user(regs->hi, &sc->sc_mdhi);
188 err |= __get_user(regs->lo, &sc->sc_mdlo);
189 if (cpu_has_dsp) {
190 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
191 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
192 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
193 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
194 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
195 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
196 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
199 for (i = 1; i < 32; i++)
200 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
202 err |= __get_user(used_math, &sc->sc_used_math);
203 conditional_used_math(used_math);
205 if (used_math) {
206 /* restore fpu context if we have used it before */
207 if (!err)
208 err = check_and_restore_fp_context32(sc);
209 } else {
210 /* signal handler may have used FPU. Give it up. */
211 lose_fpu(0);
214 return err;
220 extern void __put_sigset_unknown_nsig(void);
221 extern void __get_sigset_unknown_nsig(void);
223 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
225 int err = 0;
227 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
228 return -EFAULT;
230 switch (_NSIG_WORDS) {
231 default:
232 __put_sigset_unknown_nsig();
233 case 2:
234 err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
235 err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
236 case 1:
237 err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
238 err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
241 return err;
244 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
246 int err = 0;
247 unsigned long sig[4];
249 if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
250 return -EFAULT;
252 switch (_NSIG_WORDS) {
253 default:
254 __get_sigset_unknown_nsig();
255 case 2:
256 err |= __get_user(sig[3], &ubuf->sig[3]);
257 err |= __get_user(sig[2], &ubuf->sig[2]);
258 kbuf->sig[1] = sig[2] | (sig[3] << 32);
259 case 1:
260 err |= __get_user(sig[1], &ubuf->sig[1]);
261 err |= __get_user(sig[0], &ubuf->sig[0]);
262 kbuf->sig[0] = sig[0] | (sig[1] << 32);
265 return err;
269 * Atomically swap in the new signal mask, and wait for a signal.
272 asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
274 return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
277 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
278 struct compat_sigaction __user *, oact)
280 struct k_sigaction new_ka, old_ka;
281 int ret;
282 int err = 0;
284 if (act) {
285 old_sigset_t mask;
286 s32 handler;
288 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
289 return -EFAULT;
290 err |= __get_user(handler, &act->sa_handler);
291 new_ka.sa.sa_handler = (void __user *)(s64)handler;
292 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
293 err |= __get_user(mask, &act->sa_mask.sig[0]);
294 if (err)
295 return -EFAULT;
297 siginitset(&new_ka.sa.sa_mask, mask);
300 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
302 if (!ret && oact) {
303 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
304 return -EFAULT;
305 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
306 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
307 &oact->sa_handler);
308 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
309 err |= __put_user(0, &oact->sa_mask.sig[1]);
310 err |= __put_user(0, &oact->sa_mask.sig[2]);
311 err |= __put_user(0, &oact->sa_mask.sig[3]);
312 if (err)
313 return -EFAULT;
316 return ret;
319 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
321 int err;
323 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
324 return -EFAULT;
326 /* If you change siginfo_t structure, please be sure
327 this code is fixed accordingly.
328 It should never copy any pad contained in the structure
329 to avoid security leaks, but must copy the generic
330 3 ints plus the relevant union member.
331 This routine must convert siginfo from 64bit to 32bit as well
332 at the same time. */
333 err = __put_user(from->si_signo, &to->si_signo);
334 err |= __put_user(from->si_errno, &to->si_errno);
335 err |= __put_user((short)from->si_code, &to->si_code);
336 if (from->si_code < 0)
337 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
338 else {
339 switch (from->si_code >> 16) {
340 case __SI_TIMER >> 16:
341 err |= __put_user(from->si_tid, &to->si_tid);
342 err |= __put_user(from->si_overrun, &to->si_overrun);
343 err |= __put_user(from->si_int, &to->si_int);
344 break;
345 case __SI_CHLD >> 16:
346 err |= __put_user(from->si_utime, &to->si_utime);
347 err |= __put_user(from->si_stime, &to->si_stime);
348 err |= __put_user(from->si_status, &to->si_status);
349 default:
350 err |= __put_user(from->si_pid, &to->si_pid);
351 err |= __put_user(from->si_uid, &to->si_uid);
352 break;
353 case __SI_FAULT >> 16:
354 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
355 break;
356 case __SI_POLL >> 16:
357 err |= __put_user(from->si_band, &to->si_band);
358 err |= __put_user(from->si_fd, &to->si_fd);
359 break;
360 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
361 case __SI_MESGQ >> 16:
362 err |= __put_user(from->si_pid, &to->si_pid);
363 err |= __put_user(from->si_uid, &to->si_uid);
364 err |= __put_user(from->si_int, &to->si_int);
365 break;
368 return err;
371 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
373 memset(to, 0, sizeof *to);
375 if (copy_from_user(to, from, 3*sizeof(int)) ||
376 copy_from_user(to->_sifields._pad,
377 from->_sifields._pad, SI_PAD_SIZE32))
378 return -EFAULT;
380 return 0;
383 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
385 struct sigframe32 __user *frame;
386 sigset_t blocked;
387 int sig;
389 frame = (struct sigframe32 __user *) regs.regs[29];
390 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
391 goto badframe;
392 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
393 goto badframe;
395 set_current_blocked(&blocked);
397 sig = restore_sigcontext32(&regs, &frame->sf_sc);
398 if (sig < 0)
399 goto badframe;
400 else if (sig)
401 force_sig(sig, current);
404 * Don't let your children do this ...
406 __asm__ __volatile__(
407 "move\t$29, %0\n\t"
408 "j\tsyscall_exit"
409 :/* no outputs */
410 :"r" (&regs));
411 /* Unreached */
413 badframe:
414 force_sig(SIGSEGV, current);
417 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
419 struct rt_sigframe32 __user *frame;
420 sigset_t set;
421 int sig;
423 frame = (struct rt_sigframe32 __user *) regs.regs[29];
424 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
425 goto badframe;
426 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
427 goto badframe;
429 set_current_blocked(&set);
431 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
432 if (sig < 0)
433 goto badframe;
434 else if (sig)
435 force_sig(sig, current);
437 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
438 goto badframe;
441 * Don't let your children do this ...
443 __asm__ __volatile__(
444 "move\t$29, %0\n\t"
445 "j\tsyscall_exit"
446 :/* no outputs */
447 :"r" (&regs));
448 /* Unreached */
450 badframe:
451 force_sig(SIGSEGV, current);
454 static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
455 struct pt_regs *regs, int signr, sigset_t *set)
457 struct sigframe32 __user *frame;
458 int err = 0;
460 frame = get_sigframe(ka, regs, sizeof(*frame));
461 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
462 goto give_sigsegv;
464 err |= setup_sigcontext32(regs, &frame->sf_sc);
465 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
467 if (err)
468 goto give_sigsegv;
471 * Arguments to signal handler:
473 * a0 = signal number
474 * a1 = 0 (should be cause)
475 * a2 = pointer to struct sigcontext
477 * $25 and c0_epc point to the signal handler, $29 points to the
478 * struct sigframe.
480 regs->regs[ 4] = signr;
481 regs->regs[ 5] = 0;
482 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
483 regs->regs[29] = (unsigned long) frame;
484 regs->regs[31] = (unsigned long) sig_return;
485 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
487 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
488 current->comm, current->pid,
489 frame, regs->cp0_epc, regs->regs[31]);
491 return 0;
493 give_sigsegv:
494 force_sigsegv(signr, current);
495 return -EFAULT;
498 static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
499 struct pt_regs *regs, int signr, sigset_t *set,
500 siginfo_t *info)
502 struct rt_sigframe32 __user *frame;
503 int err = 0;
505 frame = get_sigframe(ka, regs, sizeof(*frame));
506 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
507 goto give_sigsegv;
509 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
510 err |= copy_siginfo_to_user32(&frame->rs_info, info);
512 /* Create the ucontext. */
513 err |= __put_user(0, &frame->rs_uc.uc_flags);
514 err |= __put_user(0, &frame->rs_uc.uc_link);
515 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
516 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
517 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
519 if (err)
520 goto give_sigsegv;
523 * Arguments to signal handler:
525 * a0 = signal number
526 * a1 = 0 (should be cause)
527 * a2 = pointer to ucontext
529 * $25 and c0_epc point to the signal handler, $29 points to
530 * the struct rt_sigframe32.
532 regs->regs[ 4] = signr;
533 regs->regs[ 5] = (unsigned long) &frame->rs_info;
534 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
535 regs->regs[29] = (unsigned long) frame;
536 regs->regs[31] = (unsigned long) sig_return;
537 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
539 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
540 current->comm, current->pid,
541 frame, regs->cp0_epc, regs->regs[31]);
543 return 0;
545 give_sigsegv:
546 force_sigsegv(signr, current);
547 return -EFAULT;
551 * o32 compatibility on 64-bit kernels, without DSP ASE
553 struct mips_abi mips_abi_32 = {
554 .setup_frame = setup_frame_32,
555 .signal_return_offset =
556 offsetof(struct mips_vdso, o32_signal_trampoline),
557 .setup_rt_frame = setup_rt_frame_32,
558 .rt_signal_return_offset =
559 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
560 .restart = __NR_O32_restart_syscall
563 static int signal32_init(void)
565 if (cpu_has_fpu) {
566 save_fp_context32 = _save_fp_context32;
567 restore_fp_context32 = _restore_fp_context32;
568 } else {
569 save_fp_context32 = fpu_emulator_save_context32;
570 restore_fp_context32 = fpu_emulator_restore_context32;
573 return 0;
576 arch_initcall(signal32_init);