Support the MIPS32 / MIPS64 DSP ASE.
[linux-2.6/sactl.git] / arch / mips / kernel / signal.c
blob8504febf8b2293752132a8f1a4ebf7bad7be72e8
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/config.h>
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <linux/personality.h>
14 #include <linux/smp.h>
15 #include <linux/smp_lock.h>
16 #include <linux/kernel.h>
17 #include <linux/signal.h>
18 #include <linux/errno.h>
19 #include <linux/wait.h>
20 #include <linux/ptrace.h>
21 #include <linux/unistd.h>
22 #include <linux/compiler.h>
24 #include <asm/abi.h>
25 #include <asm/asm.h>
26 #include <linux/bitops.h>
27 #include <asm/cacheflush.h>
28 #include <asm/fpu.h>
29 #include <asm/sim.h>
30 #include <asm/uaccess.h>
31 #include <asm/ucontext.h>
32 #include <asm/cpu-features.h>
34 #include "signal-common.h"
36 #define DEBUG_SIG 0
38 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
40 int do_signal(sigset_t *oldset, struct pt_regs *regs);
43 * Atomically swap in the new signal mask, and wait for a signal.
46 #ifdef CONFIG_TRAD_SIGNALS
47 save_static_function(sys_sigsuspend);
48 __attribute_used__ noinline static int
49 _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
51 sigset_t saveset, newset;
52 sigset_t __user *uset;
54 uset = (sigset_t __user *) regs.regs[4];
55 if (copy_from_user(&newset, uset, sizeof(sigset_t)))
56 return -EFAULT;
57 sigdelsetmask(&newset, ~_BLOCKABLE);
59 spin_lock_irq(&current->sighand->siglock);
60 saveset = current->blocked;
61 current->blocked = newset;
62 recalc_sigpending();
63 spin_unlock_irq(&current->sighand->siglock);
65 regs.regs[2] = EINTR;
66 regs.regs[7] = 1;
67 while (1) {
68 current->state = TASK_INTERRUPTIBLE;
69 schedule();
70 if (do_signal(&saveset, &regs))
71 return -EINTR;
74 #endif
76 save_static_function(sys_rt_sigsuspend);
77 __attribute_used__ noinline static int
78 _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
80 sigset_t saveset, newset;
81 sigset_t __user *unewset;
82 size_t sigsetsize;
84 /* XXX Don't preclude handling different sized sigset_t's. */
85 sigsetsize = regs.regs[5];
86 if (sigsetsize != sizeof(sigset_t))
87 return -EINVAL;
89 unewset = (sigset_t __user *) regs.regs[4];
90 if (copy_from_user(&newset, unewset, sizeof(newset)))
91 return -EFAULT;
92 sigdelsetmask(&newset, ~_BLOCKABLE);
94 spin_lock_irq(&current->sighand->siglock);
95 saveset = current->blocked;
96 current->blocked = newset;
97 recalc_sigpending();
98 spin_unlock_irq(&current->sighand->siglock);
100 regs.regs[2] = EINTR;
101 regs.regs[7] = 1;
102 while (1) {
103 current->state = TASK_INTERRUPTIBLE;
104 schedule();
105 if (do_signal(&saveset, &regs))
106 return -EINTR;
110 #ifdef CONFIG_TRAD_SIGNALS
111 asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
112 struct sigaction *oact)
114 struct k_sigaction new_ka, old_ka;
115 int ret;
116 int err = 0;
118 if (act) {
119 old_sigset_t mask;
121 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
122 return -EFAULT;
123 err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
124 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
125 err |= __get_user(mask, &act->sa_mask.sig[0]);
126 if (err)
127 return -EFAULT;
129 siginitset(&new_ka.sa.sa_mask, mask);
132 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
134 if (!ret && oact) {
135 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
136 return -EFAULT;
137 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
138 err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
139 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
140 err |= __put_user(0, &oact->sa_mask.sig[1]);
141 err |= __put_user(0, &oact->sa_mask.sig[2]);
142 err |= __put_user(0, &oact->sa_mask.sig[3]);
143 if (err)
144 return -EFAULT;
147 return ret;
149 #endif
151 asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
153 const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
154 stack_t __user *uoss = (stack_t __user *) regs.regs[5];
155 unsigned long usp = regs.regs[29];
157 return do_sigaltstack(uss, uoss, usp);
160 #if PLAT_TRAMPOLINE_STUFF_LINE
161 #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
162 #else
163 #define __tramp
164 #endif
166 #ifdef CONFIG_TRAD_SIGNALS
167 struct sigframe {
168 u32 sf_ass[4]; /* argument save space for o32 */
169 u32 sf_code[2] __tramp; /* signal trampoline */
170 struct sigcontext sf_sc __tramp;
171 sigset_t sf_mask;
173 #endif
175 struct rt_sigframe {
176 u32 rs_ass[4]; /* argument save space for o32 */
177 u32 rs_code[2] __tramp; /* signal trampoline */
178 struct siginfo rs_info __tramp;
179 struct ucontext rs_uc;
182 #ifdef CONFIG_TRAD_SIGNALS
183 save_static_function(sys_sigreturn);
184 __attribute_used__ noinline static void
185 _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
187 struct sigframe *frame;
188 sigset_t blocked;
190 frame = (struct sigframe *) regs.regs[29];
191 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
192 goto badframe;
193 if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
194 goto badframe;
196 sigdelsetmask(&blocked, ~_BLOCKABLE);
197 spin_lock_irq(&current->sighand->siglock);
198 current->blocked = blocked;
199 recalc_sigpending();
200 spin_unlock_irq(&current->sighand->siglock);
202 if (restore_sigcontext(&regs, &frame->sf_sc))
203 goto badframe;
206 * Don't let your children do this ...
208 if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
209 do_syscall_trace(&regs, 1);
210 __asm__ __volatile__(
211 "move\t$29, %0\n\t"
212 "j\tsyscall_exit"
213 :/* no outputs */
214 :"r" (&regs));
215 /* Unreached */
217 badframe:
218 force_sig(SIGSEGV, current);
220 #endif /* CONFIG_TRAD_SIGNALS */
222 save_static_function(sys_rt_sigreturn);
223 __attribute_used__ noinline static void
224 _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
226 struct rt_sigframe *frame;
227 sigset_t set;
228 stack_t st;
230 frame = (struct rt_sigframe *) regs.regs[29];
231 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
232 goto badframe;
233 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
234 goto badframe;
236 sigdelsetmask(&set, ~_BLOCKABLE);
237 spin_lock_irq(&current->sighand->siglock);
238 current->blocked = set;
239 recalc_sigpending();
240 spin_unlock_irq(&current->sighand->siglock);
242 if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
243 goto badframe;
245 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
246 goto badframe;
247 /* It is more difficult to avoid calling this function than to
248 call it and ignore errors. */
249 do_sigaltstack(&st, NULL, regs.regs[29]);
252 * Don't let your children do this ...
254 __asm__ __volatile__(
255 "move\t$29, %0\n\t"
256 "j\tsyscall_exit"
257 :/* no outputs */
258 :"r" (&regs));
259 /* Unreached */
261 badframe:
262 force_sig(SIGSEGV, current);
265 #ifdef CONFIG_TRAD_SIGNALS
266 void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
267 int signr, sigset_t *set)
269 struct sigframe *frame;
270 int err = 0;
272 frame = get_sigframe(ka, regs, sizeof(*frame));
273 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
274 goto give_sigsegv;
277 * Set up the return code ...
279 * li v0, __NR_sigreturn
280 * syscall
282 if (PLAT_TRAMPOLINE_STUFF_LINE)
283 __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
284 err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
285 err |= __put_user(0x0000000c , frame->sf_code + 1);
286 flush_cache_sigtramp((unsigned long) frame->sf_code);
288 err |= setup_sigcontext(regs, &frame->sf_sc);
289 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
290 if (err)
291 goto give_sigsegv;
294 * Arguments to signal handler:
296 * a0 = signal number
297 * a1 = 0 (should be cause)
298 * a2 = pointer to struct sigcontext
300 * $25 and c0_epc point to the signal handler, $29 points to the
301 * struct sigframe.
303 regs->regs[ 4] = signr;
304 regs->regs[ 5] = 0;
305 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
306 regs->regs[29] = (unsigned long) frame;
307 regs->regs[31] = (unsigned long) frame->sf_code;
308 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
310 #if DEBUG_SIG
311 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
312 current->comm, current->pid,
313 frame, regs->cp0_epc, frame->regs[31]);
314 #endif
315 return;
317 give_sigsegv:
318 force_sigsegv(signr, current);
320 #endif
322 void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
323 int signr, sigset_t *set, siginfo_t *info)
325 struct rt_sigframe *frame;
326 int err = 0;
328 frame = get_sigframe(ka, regs, sizeof(*frame));
329 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
330 goto give_sigsegv;
333 * Set up the return code ...
335 * li v0, __NR_rt_sigreturn
336 * syscall
338 if (PLAT_TRAMPOLINE_STUFF_LINE)
339 __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
340 err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
341 err |= __put_user(0x0000000c , frame->rs_code + 1);
342 flush_cache_sigtramp((unsigned long) frame->rs_code);
344 /* Create siginfo. */
345 err |= copy_siginfo_to_user(&frame->rs_info, info);
347 /* Create the ucontext. */
348 err |= __put_user(0, &frame->rs_uc.uc_flags);
349 err |= __put_user(0, &frame->rs_uc.uc_link);
350 err |= __put_user((void *)current->sas_ss_sp,
351 &frame->rs_uc.uc_stack.ss_sp);
352 err |= __put_user(sas_ss_flags(regs->regs[29]),
353 &frame->rs_uc.uc_stack.ss_flags);
354 err |= __put_user(current->sas_ss_size,
355 &frame->rs_uc.uc_stack.ss_size);
356 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
357 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
359 if (err)
360 goto give_sigsegv;
363 * Arguments to signal handler:
365 * a0 = signal number
366 * a1 = 0 (should be cause)
367 * a2 = pointer to ucontext
369 * $25 and c0_epc point to the signal handler, $29 points to
370 * the struct rt_sigframe.
372 regs->regs[ 4] = signr;
373 regs->regs[ 5] = (unsigned long) &frame->rs_info;
374 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
375 regs->regs[29] = (unsigned long) frame;
376 regs->regs[31] = (unsigned long) frame->rs_code;
377 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
379 #if DEBUG_SIG
380 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
381 current->comm, current->pid,
382 frame, regs->cp0_epc, regs->regs[31]);
383 #endif
384 return;
386 give_sigsegv:
387 force_sigsegv(signr, current);
390 extern void setup_rt_frame_n32(struct k_sigaction * ka,
391 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
393 static inline void handle_signal(unsigned long sig, siginfo_t *info,
394 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
396 switch(regs->regs[0]) {
397 case ERESTART_RESTARTBLOCK:
398 case ERESTARTNOHAND:
399 regs->regs[2] = EINTR;
400 break;
401 case ERESTARTSYS:
402 if(!(ka->sa.sa_flags & SA_RESTART)) {
403 regs->regs[2] = EINTR;
404 break;
406 /* fallthrough */
407 case ERESTARTNOINTR: /* Userland will reload $v0. */
408 regs->regs[7] = regs->regs[26];
409 regs->cp0_epc -= 8;
412 regs->regs[0] = 0; /* Don't deal with this again. */
414 if (sig_uses_siginfo(ka))
415 current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
416 else
417 current->thread.abi->setup_frame(ka, regs, sig, oldset);
419 spin_lock_irq(&current->sighand->siglock);
420 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
421 if (!(ka->sa.sa_flags & SA_NODEFER))
422 sigaddset(&current->blocked,sig);
423 recalc_sigpending();
424 spin_unlock_irq(&current->sighand->siglock);
427 int do_signal(sigset_t *oldset, struct pt_regs *regs)
429 struct k_sigaction ka;
430 siginfo_t info;
431 int signr;
434 * We want the common case to go fast, which is why we may in certain
435 * cases get here from kernel mode. Just return without doing anything
436 * if so.
438 if (!user_mode(regs))
439 return 1;
441 if (try_to_freeze())
442 goto no_signal;
444 if (!oldset)
445 oldset = &current->blocked;
447 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
448 if (signr > 0) {
449 handle_signal(signr, &info, &ka, oldset, regs);
450 return 1;
453 no_signal:
455 * Who's code doesn't conform to the restartable syscall convention
456 * dies here!!! The li instruction, a single machine instruction,
457 * must directly be followed by the syscall instruction.
459 if (regs->regs[0]) {
460 if (regs->regs[2] == ERESTARTNOHAND ||
461 regs->regs[2] == ERESTARTSYS ||
462 regs->regs[2] == ERESTARTNOINTR) {
463 regs->regs[7] = regs->regs[26];
464 regs->cp0_epc -= 8;
466 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
467 regs->regs[2] = __NR_restart_syscall;
468 regs->regs[7] = regs->regs[26];
469 regs->cp0_epc -= 4;
472 return 0;
476 * notification of userspace execution resumption
477 * - triggered by current->work.notify_resume
479 asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
480 __u32 thread_info_flags)
482 /* deal with pending signal delivery */
483 if (thread_info_flags & _TIF_SIGPENDING) {
484 current->thread.abi->do_signal(oldset, regs);