ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / h8300 / kernel / signal.c
1 /*
2  *  linux/arch/h8300/kernel/signal.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file COPYING in the main directory of this archive
8  * for more details.
9  */
10
11 /*
12  * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp>
13  *                and David McCullough <davidm@snapgear.com>
14  *
15  * Based on
16  * Linux/m68k by Hamish Macdonald
17  */
18
19 /*
20  * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
21  * Atari :-) Current limitation: Only one sigstack can be active at one time.
22  * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
23  * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
24  * signal handlers!
25  */
26
27 #include <linux/sched.h>
28 #include <linux/mm.h>
29 #include <linux/kernel.h>
30 #include <linux/signal.h>
31 #include <linux/syscalls.h>
32 #include <linux/errno.h>
33 #include <linux/wait.h>
34 #include <linux/ptrace.h>
35 #include <linux/unistd.h>
36 #include <linux/stddef.h>
37 #include <linux/highuid.h>
38 #include <linux/personality.h>
39 #include <linux/tty.h>
40 #include <linux/binfmts.h>
41
42 #include <asm/setup.h>
43 #include <asm/uaccess.h>
44 #include <asm/pgtable.h>
45 #include <asm/traps.h>
46 #include <asm/ucontext.h>
47
48 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
49
50 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
51
52 /*
53  * Atomically swap in the new signal mask, and wait for a signal.
54  */
55 asmlinkage int do_sigsuspend(struct pt_regs *regs)
56 {
57         old_sigset_t mask = regs->er3;
58         sigset_t saveset;
59
60         mask &= _BLOCKABLE;
61         spin_lock_irq(&current->sighand->siglock);
62         saveset = current->blocked;
63         siginitset(&current->blocked, mask);
64         recalc_sigpending();
65         spin_unlock_irq(&current->sighand->siglock);
66
67         regs->er0 = -EINTR;
68         while (1) {
69                 current->state = TASK_INTERRUPTIBLE;
70                 schedule();
71                 if (do_signal(&saveset, regs))
72                         return -EINTR;
73         }
74 }
75
76 asmlinkage int
77 do_rt_sigsuspend(struct pt_regs *regs)
78 {
79         sigset_t *unewset = (sigset_t *)regs->er1;
80         size_t sigsetsize = (size_t)regs->er2;
81         sigset_t saveset, newset;
82
83         /* XXX: Don't preclude handling different sized sigset_t's.  */
84         if (sigsetsize != sizeof(sigset_t))
85                 return -EINVAL;
86
87         if (copy_from_user(&newset, unewset, sizeof(newset)))
88                 return -EFAULT;
89         sigdelsetmask(&newset, ~_BLOCKABLE);
90
91         spin_lock_irq(&current->sighand->siglock);
92         saveset = current->blocked;
93         current->blocked = newset;
94         recalc_sigpending();
95         spin_unlock_irq(&current->sighand->siglock);
96
97         regs->er0 = -EINTR;
98         while (1) {
99                 current->state = TASK_INTERRUPTIBLE;
100                 schedule();
101                 if (do_signal(&saveset, regs))
102                         return -EINTR;
103         }
104 }
105
106 asmlinkage int 
107 sys_sigaction(int sig, const struct old_sigaction *act,
108               struct old_sigaction *oact)
109 {
110         struct k_sigaction new_ka, old_ka;
111         int ret;
112
113         if (act) {
114                 old_sigset_t mask;
115                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
116                     __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
117                     __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
118                         return -EFAULT;
119                 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
120                 __get_user(mask, &act->sa_mask);
121                 siginitset(&new_ka.sa.sa_mask, mask);
122         }
123
124         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
125
126         if (!ret && oact) {
127                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
128                     __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
129                     __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
130                         return -EFAULT;
131                 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
132                 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
133         }
134
135         return ret;
136 }
137
138 asmlinkage int
139 sys_sigaltstack(const stack_t *uss, stack_t *uoss)
140 {
141         return do_sigaltstack(uss, uoss, rdusp());
142 }
143
144
145 /*
146  * Do a signal return; undo the signal stack.
147  *
148  * Keep the return code on the stack quadword aligned!
149  * That makes the cache flush below easier.
150  */
151
152 struct sigframe
153 {
154         long dummy_er0;
155         long dummy_vector;
156 #if defined(CONFIG_CPU_H8S)
157         short dummy_exr;
158 #endif
159         long dummy_pc;
160         char *pretcode;
161         unsigned char retcode[8];
162         unsigned long extramask[_NSIG_WORDS-1];
163         struct sigcontext sc;
164 } __attribute__((aligned(2),packed));
165
166 struct rt_sigframe
167 {
168         long dummy_er0;
169         long dummy_vector;
170 #if defined(CONFIG_CPU_H8S)
171         short dummy_exr;
172 #endif
173         long dummy_pc;
174         char *pretcode;
175         unsigned char retcode[8];
176         struct siginfo info;
177         struct ucontext uc;
178 } __attribute__((aligned(2),packed));
179
180 static inline int
181 restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
182                    int *pd0)
183 {
184         struct sigcontext context;
185         int err = 0;
186
187         /* get previous context */
188         if (copy_from_user(&context, usc, sizeof(context)))
189                 goto badframe;
190         
191         /* restore passed registers */
192         regs->er1 = context.sc_er1;
193         regs->er2 = context.sc_er2;
194         regs->er3 = context.sc_er3;
195         regs->ccr = (regs->ccr & 0x10)|(context.sc_ccr & 0xef);
196         regs->pc = context.sc_pc;
197         regs->orig_er0 = -1;            /* disable syscall checks */
198         wrusp(context.sc_usp);
199
200         *pd0 = context.sc_er0;
201         return err;
202
203 badframe:
204         return 1;
205 }
206
207 static inline int
208 rt_restore_ucontext(struct pt_regs *regs, struct ucontext *uc, int *pd0)
209 {
210         int temp;
211         greg_t *gregs = uc->uc_mcontext.gregs;
212         unsigned long usp;
213         int err;
214
215         err = __get_user(temp, &uc->uc_mcontext.version);
216         if (temp != MCONTEXT_VERSION)
217                 goto badframe;
218         /* restore passed registers */
219         err |= __get_user(regs->er0, &gregs[0]);
220         err |= __get_user(regs->er1, &gregs[1]);
221         err |= __get_user(regs->er2, &gregs[2]);
222         err |= __get_user(regs->er3, &gregs[3]);
223         err |= __get_user(regs->er4, &gregs[4]);
224         err |= __get_user(regs->er5, &gregs[5]);
225         err |= __get_user(regs->er6, &gregs[6]);
226         err |= __get_user(usp, &gregs[7]);
227         wrusp(usp);
228         err |= __get_user(regs->pc, &gregs[8]);
229         err |= __get_user(temp, &gregs[9]);
230         regs->ccr = (regs->ccr & 0x10) | (temp & 0xef);
231         regs->orig_er0 = -1;            /* disable syscall checks */
232
233         if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
234                 goto badframe;
235
236         *pd0 = regs->er0;
237         return err;
238
239 badframe:
240         return 1;
241 }
242
243 asmlinkage int do_sigreturn(unsigned long __unused,...)
244 {
245         struct pt_regs *regs = (struct pt_regs *) (&__unused - 1);
246         unsigned long usp = rdusp();
247         struct sigframe *frame = (struct sigframe *)(usp - 4);
248         sigset_t set;
249         int er0;
250
251         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
252                 goto badframe;
253         if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
254             (_NSIG_WORDS > 1 &&
255              __copy_from_user(&set.sig[1], &frame->extramask,
256                               sizeof(frame->extramask))))
257                 goto badframe;
258
259         sigdelsetmask(&set, ~_BLOCKABLE);
260         spin_lock_irq(&current->sighand->siglock);
261         current->blocked = set;
262         recalc_sigpending();
263         spin_unlock_irq(&current->sighand->siglock);
264         
265         if (restore_sigcontext(regs, &frame->sc, frame + 1, &er0))
266                 goto badframe;
267         return er0;
268
269 badframe:
270         force_sig(SIGSEGV, current);
271         return 0;
272 }
273
274 asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
275 {
276         struct pt_regs *regs = (struct pt_regs *) &__unused;
277         unsigned long usp = rdusp();
278         struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
279         sigset_t set;
280         int er0;
281
282         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
283                 goto badframe;
284         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
285                 goto badframe;
286
287         sigdelsetmask(&set, ~_BLOCKABLE);
288         spin_unlock_irq(&current->sighand->siglock);
289         current->blocked = set;
290         recalc_sigpending();
291         spin_lock_irq(&current->sighand->siglock);
292         
293         if (rt_restore_ucontext(regs, &frame->uc, &er0))
294                 goto badframe;
295         return er0;
296
297 badframe:
298         force_sig(SIGSEGV, current);
299         return 0;
300 }
301
302 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
303                              unsigned long mask)
304 {
305         sc->sc_mask = mask;
306         sc->sc_usp = rdusp();
307         sc->sc_er0 = regs->er0;
308         sc->sc_er1 = regs->er1;
309         sc->sc_er2 = regs->er2;
310         sc->sc_er3 = regs->er3;
311         sc->sc_ccr = regs->ccr;
312         sc->sc_pc = regs->pc;
313 }
314
315 static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
316 {
317         greg_t *gregs = uc->uc_mcontext.gregs;
318         int err = 0;
319
320         err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
321         err |= __put_user(regs->er0, &gregs[0]);
322         err |= __put_user(regs->er1, &gregs[1]);
323         err |= __put_user(regs->er2, &gregs[2]);
324         err |= __put_user(regs->er3, &gregs[3]);
325         err |= __put_user(regs->er4, &gregs[4]);
326         err |= __put_user(regs->er5, &gregs[5]);
327         err |= __put_user(regs->er6, &gregs[6]);
328         err |= __put_user(rdusp(), &gregs[7]);
329         err |= __put_user(regs->pc, &gregs[8]);
330         err |= __put_user(regs->ccr, &gregs[9]);
331         return err;
332 }
333
334 static inline void *
335 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
336 {
337         unsigned long usp;
338
339         /* Default to using normal stack.  */
340         usp = rdusp();
341
342         /* This is the X/Open sanctioned signal stack switching.  */
343         if (ka->sa.sa_flags & SA_ONSTACK) {
344                 if (!on_sig_stack(usp))
345                         usp = current->sas_ss_sp + current->sas_ss_size;
346         }
347         return (void *)((usp - frame_size) & -8UL);
348 }
349
350 static void setup_frame (int sig, struct k_sigaction *ka,
351                          sigset_t *set, struct pt_regs *regs)
352 {
353         struct sigframe *frame;
354         struct sigcontext context;
355         int err = 0;
356
357         frame = get_sigframe(ka, regs, sizeof(*frame));
358
359         if (_NSIG_WORDS > 1)
360                 err |= copy_to_user(frame->extramask, &set->sig[1],
361                                     sizeof(frame->extramask));
362
363         setup_sigcontext(&context, regs, set->sig[0]);
364         err |= copy_to_user (&frame->sc, &context, sizeof(context));
365
366         /* Set up to return from userspace.  */
367         err |= __put_user(frame->retcode, &frame->pretcode);
368
369         /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
370         err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
371                         (unsigned long *)(frame->retcode + 0));
372         err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
373
374
375         if (err)
376                 goto give_sigsegv;
377
378         /* Set up registers for signal handler */
379         wrusp ((unsigned long) frame);
380         regs->pc = (unsigned long) ka->sa.sa_handler;
381         regs->er0 = (current_thread_info()->exec_domain
382                            && current_thread_info()->exec_domain->signal_invmap
383                            && sig < 32
384                            ? current_thread_info()->exec_domain->signal_invmap[sig]
385                           : sig);
386         regs->er1 = (unsigned long)&(frame->sc);
387
388         return;
389
390 give_sigsegv:
391         if (sig == SIGSEGV)
392                 ka->sa.sa_handler = SIG_DFL;
393         force_sig(SIGSEGV, current);
394 }
395
396 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
397                             sigset_t *set, struct pt_regs *regs)
398 {
399         struct rt_sigframe *frame;
400         int err = 0;
401
402         frame = get_sigframe(ka, regs, sizeof(*frame));
403
404         err |= copy_siginfo_to_user(&frame->info, info);
405
406         /* Create the ucontext.  */
407         err |= __put_user(0, &frame->uc.uc_flags);
408         err |= __put_user(0, &frame->uc.uc_link);
409         err |= __put_user((void *)current->sas_ss_sp,
410                           &frame->uc.uc_stack.ss_sp);
411         err |= __put_user(sas_ss_flags(rdusp()),
412                           &frame->uc.uc_stack.ss_flags);
413         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
414         err |= rt_setup_ucontext(&frame->uc, regs);
415         err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
416
417         /* Set up to return from userspace.  */
418         err |= __put_user(frame->retcode, &frame->pretcode);
419
420         /* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
421         err != __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
422                         (long *)(frame->retcode + 0));
423         err |= __put_user(0x5700, (short *)(frame->retcode + 4));
424
425         if (err)
426                 goto give_sigsegv;
427
428         /* Set up registers for signal handler */
429         wrusp ((unsigned long) frame);
430         regs->pc  = (unsigned long) ka->sa.sa_handler;
431         regs->er0 = (current_thread_info()->exec_domain
432                      && current_thread_info()->exec_domain->signal_invmap
433                      && sig < 32
434                      ? current_thread_info()->exec_domain->signal_invmap[sig]
435                      : sig);
436         regs->er1 = (unsigned long)&(frame->info);
437         regs->er2 = (unsigned long)&frame->uc;
438
439         return;
440
441 give_sigsegv:
442         if (sig == SIGSEGV)
443                 ka->sa.sa_handler = SIG_DFL;
444         force_sig(SIGSEGV, current);
445 }
446
447 static inline void
448 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
449 {
450         switch (regs->er0) {
451         case -ERESTARTNOHAND:
452                 if (!has_handler)
453                         goto do_restart;
454                 regs->er0 = -EINTR;
455                 break;
456
457         case -ERESTARTSYS:
458                 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
459                         regs->er0 = -EINTR;
460                         break;
461                 }
462         /* fallthrough */
463         case -ERESTARTNOINTR:
464         do_restart:
465                 regs->er0 = regs->orig_er0;
466                 regs->pc -= 2;
467                 break;
468         }
469 }
470
471 /*
472  * OK, we're invoking a handler
473  */
474 static void
475 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
476               sigset_t *oldset, struct pt_regs *regs)
477 {
478         /* are we from a system call? */
479         if (regs->orig_er0 >= 0)
480                 /* If so, check system call restarting.. */
481                 handle_restart(regs, ka, 1);
482
483         /* set up the stack frame */
484         if (ka->sa.sa_flags & SA_SIGINFO)
485                 setup_rt_frame(sig, ka, info, oldset, regs);
486         else
487                 setup_frame(sig, ka, oldset, regs);
488
489         if (ka->sa.sa_flags & SA_ONESHOT)
490                 ka->sa.sa_handler = SIG_DFL;
491
492         if (!(ka->sa.sa_flags & SA_NODEFER)) {
493                 spin_lock_irq(&current->sighand->siglock);
494                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
495                 sigaddset(&current->blocked,sig);
496                 recalc_sigpending();
497                 spin_unlock_irq(&current->sighand->siglock);
498         }
499 }
500
501 /*
502  * Note that 'init' is a special process: it doesn't get signals it doesn't
503  * want to handle. Thus you cannot kill init even with a SIGKILL even by
504  * mistake.
505  *
506  * Note that we go through the signals twice: once to check the signals
507  * that the kernel can handle, and then we build all the user-level signal
508  * handling stack-frames in one go after that.
509  */
510 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
511 {
512         siginfo_t info;
513         struct k_sigaction *ka;
514
515         current->thread.esp0 = (unsigned long) regs;
516
517         if (!oldset)
518                 oldset = &current->blocked;
519
520         for (;;) {
521                 int signr;
522
523                 signr = get_signal_to_deliver(&info, regs, NULL);
524
525                 if (!signr)
526                         break;
527
528                 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
529                         current->exit_code = signr;
530                         current->state = TASK_STOPPED;
531
532                         /* Did we come from a system call? */
533                         if (regs->orig_er0 >= 0) {
534                                 /* Restart the system call the same way as
535                                    if the process were not traced.  */
536                                 struct k_sigaction *ka =
537                                         &current->sighand->action[signr-1];
538                                 int has_handler =
539                                         (ka->sa.sa_handler != SIG_IGN &&
540                                          ka->sa.sa_handler != SIG_DFL);
541                                 handle_restart(regs, ka, has_handler);
542                         }
543                         notify_parent(current, SIGCHLD);
544                         schedule();
545
546                         /* We're back.  Did the debugger cancel the sig?  */
547                         if (!(signr = current->exit_code)) {
548                         discard_frame:
549                             continue;
550                         }
551                         current->exit_code = 0;
552
553                         /* The debugger continued.  Ignore SIGSTOP.  */
554                         if (signr == SIGSTOP)
555                                 goto discard_frame;
556
557                         /* Update the siginfo structure.  Is this good?  */
558                         if (signr != info.si_signo) {
559                                 info.si_signo = signr;
560                                 info.si_errno = 0;
561                                 info.si_code = SI_USER;
562                                 info.si_pid = current->parent->pid;
563                                 info.si_uid = current->parent->uid;
564                         }
565
566                         /* If the (new) signal is now blocked, requeue it.  */
567                         if (sigismember(&current->blocked, signr)) {
568                                 send_sig_info(signr, &info, current);
569                                 continue;
570                         }
571                 }
572
573                 ka = &current->sighand->action[signr-1];
574                 if (ka->sa.sa_handler == SIG_IGN) {
575                         if (signr != SIGCHLD)
576                                 continue;
577                         /* Check for SIGCHLD: it's special.  */
578                         while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
579                                 /* nothing */;
580                         continue;
581                 }
582
583                 if (ka->sa.sa_handler == SIG_DFL) {
584                         int exit_code = signr;
585
586                         if (current->pid == 1)
587                                 continue;
588
589                         switch (signr) {
590                         case SIGCONT: case SIGCHLD:
591                         case SIGWINCH: case SIGURG:
592                                 continue;
593
594                         case SIGTSTP: case SIGTTIN: case SIGTTOU:
595                                 if (is_orphaned_pgrp(process_group(current)))
596                                         continue;
597                                 /* FALLTHRU */
598
599                         case SIGSTOP: {
600                                 struct sighand_struct *sig;
601                                 current->state = TASK_STOPPED;
602                                 current->exit_code = signr;
603                                 sig = current->parent->sighand;
604                                 if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
605 & SA_NOCLDSTOP))
606                                         notify_parent(current, SIGCHLD);
607                                 schedule();
608                                 continue;
609                         }
610
611                         case SIGQUIT: case SIGILL: case SIGTRAP:
612                         case SIGIOT: case SIGFPE: case SIGSEGV:
613                         case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
614                                 if (do_coredump(signr, exit_code, regs))
615                                         exit_code |= 0x80;
616                                 /* FALLTHRU */
617
618                         default:
619                                 sigaddset(&current->pending.signal, signr);
620                                 recalc_sigpending();
621                                 current->flags |= PF_SIGNALED;
622                                 do_exit(exit_code);
623                                 /* NOTREACHED */
624                         }
625                 }
626
627                 /* Whee!  Actually deliver the signal.  */
628                 handle_signal(signr, ka, &info, oldset, regs);
629                 return 1;
630         }
631
632         /* Did we come from a system call? */
633         if (regs->orig_er0 >= 0)
634                 /* Restart the system call - no handlers present */
635                 handle_restart(regs, NULL, 0);
636
637         return 0;
638 }