2 * linux/arch/m68k/kernel/signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
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
12 * Linux/m68k support by Hamish Macdonald
14 * 68060 fixes by Jesper Skov
16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
18 * mathemu support by Roman Zippel
19 * (Note: fpstate in the signal context is completly ignored for the emulator
20 * and the internal floating point format is put on stack)
24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
25 * Atari :-) Current limitation: Only one sigstack can be active at one time.
26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
31 #include <linux/sched.h>
33 #include <linux/kernel.h>
34 #include <linux/signal.h>
35 #include <linux/errno.h>
36 #include <linux/wait.h>
37 #include <linux/ptrace.h>
38 #include <linux/unistd.h>
39 #include <linux/stddef.h>
40 #include <linux/highuid.h>
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>
48 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
50 asmlinkage
int sys_wait4(pid_t pid
, unsigned long *stat_addr
,
51 int options
, unsigned long *ru
);
52 asmlinkage
int do_signal(sigset_t
*oldset
, struct pt_regs
*regs
);
54 const int frame_extra_sizes
[16] = {
56 -1, /* sizeof(((struct frame *)0)->un.fmt1), */
57 sizeof(((struct frame
*)0)->un
.fmt2
),
58 sizeof(((struct frame
*)0)->un
.fmt3
),
59 sizeof(((struct frame
*)0)->un
.fmt4
),
60 -1, /* sizeof(((struct frame *)0)->un.fmt5), */
61 -1, /* sizeof(((struct frame *)0)->un.fmt6), */
62 sizeof(((struct frame
*)0)->un
.fmt7
),
63 -1, /* sizeof(((struct frame *)0)->un.fmt8), */
64 sizeof(((struct frame
*)0)->un
.fmt9
),
65 sizeof(((struct frame
*)0)->un
.fmta
),
66 sizeof(((struct frame
*)0)->un
.fmtb
),
67 -1, /* sizeof(((struct frame *)0)->un.fmtc), */
68 -1, /* sizeof(((struct frame *)0)->un.fmtd), */
69 -1, /* sizeof(((struct frame *)0)->un.fmte), */
70 -1, /* sizeof(((struct frame *)0)->un.fmtf), */
74 * Atomically swap in the new signal mask, and wait for a signal.
76 asmlinkage
int do_sigsuspend(struct pt_regs
*regs
)
78 old_sigset_t mask
= regs
->d3
;
82 saveset
= current
->blocked
;
83 siginitset(¤t
->blocked
, mask
);
84 recalc_sigpending(current
);
88 current
->state
= TASK_INTERRUPTIBLE
;
90 if (do_signal(&saveset
, regs
))
96 do_rt_sigsuspend(struct pt_regs
*regs
)
98 sigset_t
*unewset
= (sigset_t
*)regs
->d1
;
99 size_t sigsetsize
= (size_t)regs
->d2
;
100 sigset_t saveset
, newset
;
102 /* XXX: Don't preclude handling different sized sigset_t's. */
103 if (sigsetsize
!= sizeof(sigset_t
))
106 if (copy_from_user(&newset
, unewset
, sizeof(newset
)))
108 sigdelsetmask(&newset
, ~_BLOCKABLE
);
110 saveset
= current
->blocked
;
111 current
->blocked
= newset
;
112 recalc_sigpending(current
);
116 current
->state
= TASK_INTERRUPTIBLE
;
118 if (do_signal(&saveset
, regs
))
124 sys_sigaction(int sig
, const struct old_sigaction
*act
,
125 struct old_sigaction
*oact
)
127 struct k_sigaction new_ka
, old_ka
;
132 if (verify_area(VERIFY_READ
, act
, sizeof(*act
)) ||
133 __get_user(new_ka
.sa
.sa_handler
, &act
->sa_handler
) ||
134 __get_user(new_ka
.sa
.sa_restorer
, &act
->sa_restorer
))
136 __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
137 __get_user(mask
, &act
->sa_mask
);
138 siginitset(&new_ka
.sa
.sa_mask
, mask
);
141 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
144 if (verify_area(VERIFY_WRITE
, oact
, sizeof(*oact
)) ||
145 __put_user(old_ka
.sa
.sa_handler
, &oact
->sa_handler
) ||
146 __put_user(old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
))
148 __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
149 __put_user(old_ka
.sa
.sa_mask
.sig
[0], &oact
->sa_mask
);
156 sys_sigaltstack(const stack_t
*uss
, stack_t
*uoss
)
158 return do_sigaltstack(uss
, uoss
, rdusp());
163 * Do a signal return; undo the signal stack.
165 * Keep the return code on the stack quadword aligned!
166 * That makes the cache flush below easier.
174 struct sigcontext
*psc
;
176 unsigned long extramask
[_NSIG_WORDS
-1];
177 struct sigcontext sc
;
184 struct siginfo
*pinfo
;
192 int copy_siginfo_to_user(siginfo_t
*to
, siginfo_t
*from
)
194 if (!access_ok (VERIFY_WRITE
, to
, sizeof(siginfo_t
)))
196 if (from
->si_code
< 0)
197 return __copy_to_user(to
, from
, sizeof(siginfo_t
));
201 /* If you change siginfo_t structure, please be sure
202 this code is fixed accordingly.
203 It should never copy any pad contained in the structure
204 to avoid security leaks, but must copy the generic
205 3 ints plus the relevant union member. */
206 err
= __put_user(from
->si_signo
, &to
->si_signo
);
207 err
|= __put_user(from
->si_errno
, &to
->si_errno
);
208 err
|= __put_user((short)from
->si_code
, &to
->si_code
);
209 /* First 32bits of unions are always present. */
210 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
211 switch (from
->si_code
>> 16) {
212 case __SI_FAULT
>> 16:
214 case __SI_CHLD
>> 16:
215 err
|= __put_user(from
->si_utime
, &to
->si_utime
);
216 err
|= __put_user(from
->si_stime
, &to
->si_stime
);
217 err
|= __put_user(from
->si_status
, &to
->si_status
);
219 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
221 /* case __SI_RT: This is not generated by the kernel as of now. */
227 static unsigned char fpu_version
= 0; /* version number of fpu, set by setup_frame */
229 static inline int restore_fpu_state(struct sigcontext
*sc
)
234 /* restore registers */
235 memcpy(current
->thread
.fpcntl
, sc
->sc_fpcntl
, 12);
236 memcpy(current
->thread
.fp
, sc
->sc_fpregs
, 24);
240 if (CPU_IS_060
? sc
->sc_fpstate
[2] : sc
->sc_fpstate
[0]) {
241 /* Verify the frame format. */
242 if (!CPU_IS_060
&& (sc
->sc_fpstate
[0] != fpu_version
))
244 if (CPU_IS_020_OR_030
) {
245 if (m68k_fputype
& FPU_68881
&&
246 !(sc
->sc_fpstate
[1] == 0x18 || sc
->sc_fpstate
[1] == 0xb4))
248 if (m68k_fputype
& FPU_68882
&&
249 !(sc
->sc_fpstate
[1] == 0x38 || sc
->sc_fpstate
[1] == 0xd4))
251 } else if (CPU_IS_040
) {
252 if (!(sc
->sc_fpstate
[1] == 0x00 ||
253 sc
->sc_fpstate
[1] == 0x28 ||
254 sc
->sc_fpstate
[1] == 0x60))
256 } else if (CPU_IS_060
) {
257 if (!(sc
->sc_fpstate
[3] == 0x00 ||
258 sc
->sc_fpstate
[3] == 0x60 ||
259 sc
->sc_fpstate
[3] == 0xe0))
264 __asm__
volatile (".chip 68k/68881\n\t"
265 "fmovemx %0,%/fp0-%/fp1\n\t"
266 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
269 : "m" (*sc
->sc_fpregs
), "m" (*sc
->sc_fpcntl
));
271 __asm__
volatile (".chip 68k/68881\n\t"
273 ".chip 68k" : : "m" (*sc
->sc_fpstate
));
280 #define FPCONTEXT_SIZE 216
281 #define uc_fpstate uc_filler[0]
282 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
283 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
285 static inline int rt_restore_fpu_state(struct ucontext
*uc
)
287 unsigned char fpstate
[FPCONTEXT_SIZE
];
288 int context_size
= CPU_IS_060
? 8 : 0;
293 /* restore fpu control register */
294 if (__copy_from_user(current
->thread
.fpcntl
,
295 &uc
->uc_mcontext
.fpregs
.f_pcr
, 12))
297 /* restore all other fpu register */
298 if (__copy_from_user(current
->thread
.fp
,
299 uc
->uc_mcontext
.fpregs
.f_fpregs
, 96))
304 if (__get_user(*(long *)fpstate
, (long *)&uc
->uc_fpstate
))
306 if (CPU_IS_060
? fpstate
[2] : fpstate
[0]) {
308 context_size
= fpstate
[1];
309 /* Verify the frame format. */
310 if (!CPU_IS_060
&& (fpstate
[0] != fpu_version
))
312 if (CPU_IS_020_OR_030
) {
313 if (m68k_fputype
& FPU_68881
&&
314 !(context_size
== 0x18 || context_size
== 0xb4))
316 if (m68k_fputype
& FPU_68882
&&
317 !(context_size
== 0x38 || context_size
== 0xd4))
319 } else if (CPU_IS_040
) {
320 if (!(context_size
== 0x00 ||
321 context_size
== 0x28 ||
322 context_size
== 0x60))
324 } else if (CPU_IS_060
) {
325 if (!(fpstate
[3] == 0x00 ||
326 fpstate
[3] == 0x60 ||
331 if (__copy_from_user(&fpregs
, &uc
->uc_mcontext
.fpregs
,
334 __asm__
volatile (".chip 68k/68881\n\t"
335 "fmovemx %0,%/fp0-%/fp7\n\t"
336 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
339 : "m" (*fpregs
.f_fpregs
),
343 __copy_from_user(fpstate
+ 4, (long *)&uc
->uc_fpstate
+ 1,
346 __asm__
volatile (".chip 68k/68881\n\t"
348 ".chip 68k" : : "m" (*fpstate
));
356 restore_sigcontext(struct pt_regs
*regs
, struct sigcontext
*usc
, void *fp
,
359 int fsize
, formatvec
;
360 struct sigcontext context
;
363 /* get previous context */
364 if (copy_from_user(&context
, usc
, sizeof(context
)))
367 /* restore passed registers */
368 regs
->d1
= context
.sc_d1
;
369 regs
->a0
= context
.sc_a0
;
370 regs
->a1
= context
.sc_a1
;
371 regs
->sr
= (regs
->sr
& 0xff00) | (context
.sc_sr
& 0xff);
372 regs
->pc
= context
.sc_pc
;
373 regs
->orig_d0
= -1; /* disable syscall checks */
374 wrusp(context
.sc_usp
);
375 formatvec
= context
.sc_formatvec
;
376 regs
->format
= formatvec
>> 12;
377 regs
->vector
= formatvec
& 0xfff;
379 err
= restore_fpu_state(&context
);
381 fsize
= frame_extra_sizes
[regs
->format
];
384 * user process trying to return with weird frame format
387 printk("user process returning with weird frame format\n");
392 /* OK. Make room on the supervisor stack for the extra junk,
397 struct switch_stack
*sw
= (struct switch_stack
*)regs
- 1;
398 regs
->d0
= context
.sc_d0
;
399 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
401 (" movel %0,%/a0\n\t"
402 " subl %1,%/a0\n\t" /* make room on stack */
403 " movel %/a0,%/sp\n\t" /* set stack pointer */
404 /* move switch_stack and pt_regs */
405 "1: movel %0@+,%/a0@+\n\t"
407 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
410 "2: movesl %4@+,%2\n\t"
411 "3: movel %2,%/a0@+\n\t"
413 " bral " SYMBOL_NAME_STR(ret_from_signal
) "\n"
415 ".section __ex_table,\"a\"\n"
420 : /* no outputs, it doesn't ever return */
421 : "a" (sw
), "d" (fsize
), "d" (frame_offset
/4-1),
422 "n" (frame_offset
), "a" (fp
)
426 * If we ever get here an exception occurred while
427 * building the above stack-frame.
432 *pd0
= context
.sc_d0
;
440 rt_restore_ucontext(struct pt_regs
*regs
, struct switch_stack
*sw
,
441 struct ucontext
*uc
, int *pd0
)
444 greg_t
*gregs
= uc
->uc_mcontext
.gregs
;
448 err
= __get_user(temp
, &uc
->uc_mcontext
.version
);
449 if (temp
!= MCONTEXT_VERSION
)
451 /* restore passed registers */
452 err
|= __get_user(regs
->d0
, &gregs
[0]);
453 err
|= __get_user(regs
->d1
, &gregs
[1]);
454 err
|= __get_user(regs
->d2
, &gregs
[2]);
455 err
|= __get_user(regs
->d3
, &gregs
[3]);
456 err
|= __get_user(regs
->d4
, &gregs
[4]);
457 err
|= __get_user(regs
->d5
, &gregs
[5]);
458 err
|= __get_user(sw
->d6
, &gregs
[6]);
459 err
|= __get_user(sw
->d7
, &gregs
[7]);
460 err
|= __get_user(regs
->a0
, &gregs
[8]);
461 err
|= __get_user(regs
->a1
, &gregs
[9]);
462 err
|= __get_user(regs
->a2
, &gregs
[10]);
463 err
|= __get_user(sw
->a3
, &gregs
[11]);
464 err
|= __get_user(sw
->a4
, &gregs
[12]);
465 err
|= __get_user(sw
->a5
, &gregs
[13]);
466 err
|= __get_user(sw
->a6
, &gregs
[14]);
467 err
|= __get_user(usp
, &gregs
[15]);
469 err
|= __get_user(regs
->pc
, &gregs
[16]);
470 err
|= __get_user(temp
, &gregs
[17]);
471 regs
->sr
= (regs
->sr
& 0xff00) | (temp
& 0xff);
472 regs
->orig_d0
= -1; /* disable syscall checks */
473 err
|= __get_user(temp
, &uc
->uc_formatvec
);
474 regs
->format
= temp
>> 12;
475 regs
->vector
= temp
& 0xfff;
477 err
|= rt_restore_fpu_state(uc
);
479 if (do_sigaltstack(&uc
->uc_stack
, NULL
, usp
) == -EFAULT
)
482 fsize
= frame_extra_sizes
[regs
->format
];
485 * user process trying to return with weird frame format
488 printk("user process returning with weird frame format\n");
493 /* OK. Make room on the supervisor stack for the extra junk,
498 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
500 (" movel %0,%/a0\n\t"
501 " subl %1,%/a0\n\t" /* make room on stack */
502 " movel %/a0,%/sp\n\t" /* set stack pointer */
503 /* move switch_stack and pt_regs */
504 "1: movel %0@+,%/a0@+\n\t"
506 " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
509 "2: movesl %4@+,%2\n\t"
510 "3: movel %2,%/a0@+\n\t"
512 " bral " SYMBOL_NAME_STR(ret_from_signal
) "\n"
514 ".section __ex_table,\"a\"\n"
519 : /* no outputs, it doesn't ever return */
520 : "a" (sw
), "d" (fsize
), "d" (frame_offset
/4-1),
521 "n" (frame_offset
), "a" (&uc
->uc_extra
)
525 * If we ever get here an exception occurred while
526 * building the above stack-frame.
538 asmlinkage
int do_sigreturn(unsigned long __unused
)
540 struct switch_stack
*sw
= (struct switch_stack
*) &__unused
;
541 struct pt_regs
*regs
= (struct pt_regs
*) (sw
+ 1);
542 unsigned long usp
= rdusp();
543 struct sigframe
*frame
= (struct sigframe
*)(usp
- 4);
547 if (verify_area(VERIFY_READ
, frame
, sizeof(*frame
)))
549 if (__get_user(set
.sig
[0], &frame
->sc
.sc_mask
) ||
551 __copy_from_user(&set
.sig
[1], &frame
->extramask
,
552 sizeof(frame
->extramask
))))
555 sigdelsetmask(&set
, ~_BLOCKABLE
);
556 current
->blocked
= set
;
557 recalc_sigpending(current
);
559 if (restore_sigcontext(regs
, &frame
->sc
, frame
+ 1, &d0
))
564 force_sig(SIGSEGV
, current
);
568 asmlinkage
int do_rt_sigreturn(unsigned long __unused
)
570 struct switch_stack
*sw
= (struct switch_stack
*) &__unused
;
571 struct pt_regs
*regs
= (struct pt_regs
*) (sw
+ 1);
572 unsigned long usp
= rdusp();
573 struct rt_sigframe
*frame
= (struct rt_sigframe
*)(usp
- 4);
577 if (verify_area(VERIFY_READ
, frame
, sizeof(*frame
)))
579 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
582 sigdelsetmask(&set
, ~_BLOCKABLE
);
583 current
->blocked
= set
;
584 recalc_sigpending(current
);
586 if (rt_restore_ucontext(regs
, sw
, &frame
->uc
, &d0
))
591 force_sig(SIGSEGV
, current
);
596 * Set up a signal frame.
599 static inline void save_fpu_state(struct sigcontext
*sc
, struct pt_regs
*regs
)
603 memcpy(sc
->sc_fpcntl
, current
->thread
.fpcntl
, 12);
604 memcpy(sc
->sc_fpregs
, current
->thread
.fp
, 24);
608 __asm__
volatile (".chip 68k/68881\n\t"
611 : : "m" (*sc
->sc_fpstate
) : "memory");
613 if (CPU_IS_060
? sc
->sc_fpstate
[2] : sc
->sc_fpstate
[0]) {
614 fpu_version
= sc
->sc_fpstate
[0];
615 if (CPU_IS_020_OR_030
&&
616 regs
->vector
>= (VEC_FPBRUC
* 4) &&
617 regs
->vector
<= (VEC_FPNAN
* 4)) {
618 /* Clear pending exception in 68882 idle frame */
619 if (*(unsigned short *) sc
->sc_fpstate
== 0x1f38)
620 sc
->sc_fpstate
[0x38] |= 1 << 3;
622 __asm__
volatile (".chip 68k/68881\n\t"
623 "fmovemx %/fp0-%/fp1,%0\n\t"
624 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
627 : "m" (*sc
->sc_fpregs
),
633 static inline int rt_save_fpu_state(struct ucontext
*uc
, struct pt_regs
*regs
)
635 unsigned char fpstate
[FPCONTEXT_SIZE
];
636 int context_size
= CPU_IS_060
? 8 : 0;
640 /* save fpu control register */
641 err
|= copy_to_user(&uc
->uc_mcontext
.fpregs
.f_pcr
,
642 current
->thread
.fpcntl
, 12);
643 /* save all other fpu register */
644 err
|= copy_to_user(uc
->uc_mcontext
.fpregs
.f_fpregs
,
645 current
->thread
.fp
, 96);
649 __asm__
volatile (".chip 68k/68881\n\t"
652 : : "m" (*fpstate
) : "memory");
654 err
|= __put_user(*(long *)fpstate
, (long *)&uc
->uc_fpstate
);
655 if (CPU_IS_060
? fpstate
[2] : fpstate
[0]) {
658 context_size
= fpstate
[1];
659 fpu_version
= fpstate
[0];
660 if (CPU_IS_020_OR_030
&&
661 regs
->vector
>= (VEC_FPBRUC
* 4) &&
662 regs
->vector
<= (VEC_FPNAN
* 4)) {
663 /* Clear pending exception in 68882 idle frame */
664 if (*(unsigned short *) fpstate
== 0x1f38)
665 fpstate
[0x38] |= 1 << 3;
667 __asm__
volatile (".chip 68k/68881\n\t"
668 "fmovemx %/fp0-%/fp7,%0\n\t"
669 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
672 : "m" (*fpregs
.f_fpregs
),
675 err
|= copy_to_user(&uc
->uc_mcontext
.fpregs
, &fpregs
,
679 err
|= copy_to_user((long *)&uc
->uc_fpstate
+ 1, fpstate
+ 4,
684 static void setup_sigcontext(struct sigcontext
*sc
, struct pt_regs
*regs
,
688 sc
->sc_usp
= rdusp();
689 sc
->sc_d0
= regs
->d0
;
690 sc
->sc_d1
= regs
->d1
;
691 sc
->sc_a0
= regs
->a0
;
692 sc
->sc_a1
= regs
->a1
;
693 sc
->sc_sr
= regs
->sr
;
694 sc
->sc_pc
= regs
->pc
;
695 sc
->sc_formatvec
= regs
->format
<< 12 | regs
->vector
;
696 save_fpu_state(sc
, regs
);
699 static inline int rt_setup_ucontext(struct ucontext
*uc
, struct pt_regs
*regs
)
701 struct switch_stack
*sw
= (struct switch_stack
*)regs
- 1;
702 greg_t
*gregs
= uc
->uc_mcontext
.gregs
;
705 err
|= __put_user(MCONTEXT_VERSION
, &uc
->uc_mcontext
.version
);
706 err
|= __put_user(regs
->d0
, &gregs
[0]);
707 err
|= __put_user(regs
->d1
, &gregs
[1]);
708 err
|= __put_user(regs
->d2
, &gregs
[2]);
709 err
|= __put_user(regs
->d3
, &gregs
[3]);
710 err
|= __put_user(regs
->d4
, &gregs
[4]);
711 err
|= __put_user(regs
->d5
, &gregs
[5]);
712 err
|= __put_user(sw
->d6
, &gregs
[6]);
713 err
|= __put_user(sw
->d7
, &gregs
[7]);
714 err
|= __put_user(regs
->a0
, &gregs
[8]);
715 err
|= __put_user(regs
->a1
, &gregs
[9]);
716 err
|= __put_user(regs
->a2
, &gregs
[10]);
717 err
|= __put_user(sw
->a3
, &gregs
[11]);
718 err
|= __put_user(sw
->a4
, &gregs
[12]);
719 err
|= __put_user(sw
->a5
, &gregs
[13]);
720 err
|= __put_user(sw
->a6
, &gregs
[14]);
721 err
|= __put_user(rdusp(), &gregs
[15]);
722 err
|= __put_user(regs
->pc
, &gregs
[16]);
723 err
|= __put_user(regs
->sr
, &gregs
[17]);
724 err
|= __put_user((regs
->format
<< 12) | regs
->vector
, &uc
->uc_formatvec
);
725 err
|= rt_save_fpu_state(uc
, regs
);
729 static inline void push_cache (unsigned long vaddr
)
732 * Using the old cache_push_v() was really a big waste.
734 * What we are trying to do is to flush 8 bytes to ram.
735 * Flushing 2 cache lines of 16 bytes is much cheaper than
736 * flushing 1 or 2 pages, as previously done in
743 __asm__
__volatile__ (".chip 68040\n\t"
746 "movec %%mmusr,%0\n\t"
752 temp
|= vaddr
& ~PAGE_MASK
;
754 __asm__
__volatile__ (".chip 68040\n\t"
756 "cpushl %%bc,(%0)\n\t"
760 else if (CPU_IS_060
) {
762 __asm__
__volatile__ (".chip 68060\n\t"
767 __asm__
__volatile__ (".chip 68060\n\t"
768 "cpushl %%bc,(%0)\n\t"
774 * 68030/68020 have no writeback cache;
775 * still need to clear icache.
776 * Note that vaddr is guaranteed to be long word aligned.
779 asm volatile ("movec %%cacr,%0" : "=r" (temp
));
781 asm volatile ("movec %0,%%caar\n\t"
783 : : "r" (vaddr
), "r" (temp
));
784 asm volatile ("movec %0,%%caar\n\t"
786 : : "r" (vaddr
+ 4), "r" (temp
));
791 get_sigframe(struct k_sigaction
*ka
, struct pt_regs
*regs
, size_t frame_size
)
795 /* Default to using normal stack. */
798 /* This is the X/Open sanctioned signal stack switching. */
799 if (ka
->sa
.sa_flags
& SA_ONSTACK
) {
800 if (!on_sig_stack(usp
))
801 usp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
803 return (void *)((usp
- frame_size
) & -8UL);
806 static void setup_frame (int sig
, struct k_sigaction
*ka
,
807 sigset_t
*set
, struct pt_regs
*regs
)
809 struct sigframe
*frame
;
810 int fsize
= frame_extra_sizes
[regs
->format
];
811 struct sigcontext context
;
816 printk ("setup_frame: Unknown frame format %#x\n",
822 frame
= get_sigframe(ka
, regs
, sizeof(*frame
) + fsize
);
825 err
|= copy_to_user (frame
+ 1, regs
+ 1, fsize
);
826 regs
->stkadj
= fsize
;
829 err
|= __put_user((current
->exec_domain
830 && current
->exec_domain
->signal_invmap
832 ? current
->exec_domain
->signal_invmap
[sig
]
836 err
|= __put_user(regs
->vector
, &frame
->code
);
837 err
|= __put_user(&frame
->sc
, &frame
->psc
);
840 err
|= copy_to_user(frame
->extramask
, &set
->sig
[1],
841 sizeof(frame
->extramask
));
843 setup_sigcontext(&context
, regs
, set
->sig
[0]);
844 err
|= copy_to_user (&frame
->sc
, &context
, sizeof(context
));
846 /* Set up to return from userspace. */
847 err
|= __put_user(frame
->retcode
, &frame
->pretcode
);
848 /* moveq #,d0; trap #0 */
849 err
|= __put_user(0x70004e40 + (__NR_sigreturn
<< 16),
850 (long *)(frame
->retcode
));
855 push_cache ((unsigned long) &frame
->retcode
);
857 /* Set up registers for signal handler */
858 wrusp ((unsigned long) frame
);
859 regs
->pc
= (unsigned long) ka
->sa
.sa_handler
;
862 /* Prepare to skip over the extra stuff in the exception frame. */
864 struct pt_regs
*tregs
=
865 (struct pt_regs
*)((ulong
)regs
+ regs
->stkadj
);
867 printk("Performing stackadjust=%04x\n", regs
->stkadj
);
869 /* This must be copied with decreasing addresses to
873 tregs
->pc
= regs
->pc
;
874 tregs
->sr
= regs
->sr
;
880 ka
->sa
.sa_handler
= SIG_DFL
;
881 force_sig(SIGSEGV
, current
);
885 static void setup_rt_frame (int sig
, struct k_sigaction
*ka
, siginfo_t
*info
,
886 sigset_t
*set
, struct pt_regs
*regs
)
888 struct rt_sigframe
*frame
;
889 int fsize
= frame_extra_sizes
[regs
->format
];
894 printk ("setup_frame: Unknown frame format %#x\n",
900 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
903 err
|= copy_to_user (&frame
->uc
.uc_extra
, regs
+ 1, fsize
);
904 regs
->stkadj
= fsize
;
907 err
|= __put_user((current
->exec_domain
908 && current
->exec_domain
->signal_invmap
910 ? current
->exec_domain
->signal_invmap
[sig
]
913 err
|= __put_user(&frame
->info
, &frame
->pinfo
);
914 err
|= __put_user(&frame
->uc
, &frame
->puc
);
915 err
|= copy_siginfo_to_user(&frame
->info
, info
);
917 /* Create the ucontext. */
918 err
|= __put_user(0, &frame
->uc
.uc_flags
);
919 err
|= __put_user(0, &frame
->uc
.uc_link
);
920 err
|= __put_user((void *)current
->sas_ss_sp
,
921 &frame
->uc
.uc_stack
.ss_sp
);
922 err
|= __put_user(sas_ss_flags(rdusp()),
923 &frame
->uc
.uc_stack
.ss_flags
);
924 err
|= __put_user(current
->sas_ss_size
, &frame
->uc
.uc_stack
.ss_size
);
925 err
|= rt_setup_ucontext(&frame
->uc
, regs
);
926 err
|= copy_to_user (&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
928 /* Set up to return from userspace. */
929 err
|= __put_user(frame
->retcode
, &frame
->pretcode
);
930 /* moveq #,d0; notb d0; trap #0 */
931 err
|= __put_user(0x70004600 + ((__NR_rt_sigreturn
^ 0xff) << 16),
932 (long *)(frame
->retcode
+ 0));
933 err
|= __put_user(0x4e40, (short *)(frame
->retcode
+ 4));
938 push_cache ((unsigned long) &frame
->retcode
);
940 /* Set up registers for signal handler */
941 wrusp ((unsigned long) frame
);
942 regs
->pc
= (unsigned long) ka
->sa
.sa_handler
;
945 /* Prepare to skip over the extra stuff in the exception frame. */
947 struct pt_regs
*tregs
=
948 (struct pt_regs
*)((ulong
)regs
+ regs
->stkadj
);
950 printk("Performing stackadjust=%04x\n", regs
->stkadj
);
952 /* This must be copied with decreasing addresses to
956 tregs
->pc
= regs
->pc
;
957 tregs
->sr
= regs
->sr
;
963 ka
->sa
.sa_handler
= SIG_DFL
;
964 force_sig(SIGSEGV
, current
);
969 handle_restart(struct pt_regs
*regs
, struct k_sigaction
*ka
, int has_handler
)
972 case -ERESTARTNOHAND
:
979 if (has_handler
&& !(ka
->sa
.sa_flags
& SA_RESTART
)) {
984 case -ERESTARTNOINTR
:
986 regs
->d0
= regs
->orig_d0
;
993 * OK, we're invoking a handler
996 handle_signal(int sig
, struct k_sigaction
*ka
, siginfo_t
*info
,
997 sigset_t
*oldset
, struct pt_regs
*regs
)
999 /* are we from a system call? */
1000 if (regs
->orig_d0
>= 0)
1001 /* If so, check system call restarting.. */
1002 handle_restart(regs
, ka
, 1);
1004 /* set up the stack frame */
1005 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
1006 setup_rt_frame(sig
, ka
, info
, oldset
, regs
);
1008 setup_frame(sig
, ka
, oldset
, regs
);
1010 if (ka
->sa
.sa_flags
& SA_ONESHOT
)
1011 ka
->sa
.sa_handler
= SIG_DFL
;
1013 sigorsets(¤t
->blocked
,¤t
->blocked
,&ka
->sa
.sa_mask
);
1014 if (!(ka
->sa
.sa_flags
& SA_NODEFER
))
1015 sigaddset(¤t
->blocked
,sig
);
1016 recalc_sigpending(current
);
1020 * Note that 'init' is a special process: it doesn't get signals it doesn't
1021 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1024 * Note that we go through the signals twice: once to check the signals
1025 * that the kernel can handle, and then we build all the user-level signal
1026 * handling stack-frames in one go after that.
1028 asmlinkage
int do_signal(sigset_t
*oldset
, struct pt_regs
*regs
)
1031 struct k_sigaction
*ka
;
1033 current
->thread
.esp0
= (unsigned long) regs
;
1036 oldset
= ¤t
->blocked
;
1041 signr
= dequeue_signal(¤t
->blocked
, &info
);
1046 if ((current
->flags
& PF_PTRACED
) && signr
!= SIGKILL
) {
1047 current
->exit_code
= signr
;
1048 current
->state
= TASK_STOPPED
;
1051 /* Did we come from a system call? */
1052 if (regs
->orig_d0
>= 0) {
1053 /* Restart the system call the same way as
1054 if the process were not traced. */
1055 struct k_sigaction
*ka
=
1056 ¤t
->sig
->action
[signr
-1];
1058 (ka
->sa
.sa_handler
!= SIG_IGN
&&
1059 ka
->sa
.sa_handler
!= SIG_DFL
);
1060 handle_restart(regs
, ka
, has_handler
);
1062 notify_parent(current
, SIGCHLD
);
1065 /* We're back. Did the debugger cancel the sig? */
1066 if (!(signr
= current
->exit_code
)) {
1068 /* Make sure that a faulted bus cycle isn't
1069 restarted (only needed on the 680[23]0). */
1070 if (regs
->format
== 10 || regs
->format
== 11)
1071 regs
->stkadj
= frame_extra_sizes
[regs
->format
];
1074 current
->exit_code
= 0;
1076 /* The debugger continued. Ignore SIGSTOP. */
1077 if (signr
== SIGSTOP
)
1080 /* Update the siginfo structure. Is this good? */
1081 if (signr
!= info
.si_signo
) {
1082 info
.si_signo
= signr
;
1084 info
.si_code
= SI_USER
;
1085 info
.si_pid
= current
->p_pptr
->pid
;
1086 info
.si_uid
= current
->p_pptr
->uid
;
1087 info
.si_uid16
= high2lowuid(current
->p_pptr
->uid
);
1090 /* If the (new) signal is now blocked, requeue it. */
1091 if (sigismember(¤t
->blocked
, signr
)) {
1092 send_sig_info(signr
, &info
, current
);
1097 ka
= ¤t
->sig
->action
[signr
-1];
1098 if (ka
->sa
.sa_handler
== SIG_IGN
) {
1099 if (signr
!= SIGCHLD
)
1101 /* Check for SIGCHLD: it's special. */
1102 while (sys_wait4(-1, NULL
, WNOHANG
, NULL
) > 0)
1107 if (ka
->sa
.sa_handler
== SIG_DFL
) {
1108 int exit_code
= signr
;
1110 if (current
->pid
== 1)
1114 case SIGCONT
: case SIGCHLD
:
1115 case SIGWINCH
: case SIGURG
:
1118 case SIGTSTP
: case SIGTTIN
: case SIGTTOU
:
1119 if (is_orphaned_pgrp(current
->pgrp
))
1124 current
->state
= TASK_STOPPED
;
1125 current
->exit_code
= signr
;
1126 if (!(current
->p_pptr
->sig
->action
[SIGCHLD
-1]
1127 .sa
.sa_flags
& SA_NOCLDSTOP
))
1128 notify_parent(current
, SIGCHLD
);
1132 case SIGQUIT
: case SIGILL
: case SIGTRAP
:
1133 case SIGIOT
: case SIGFPE
: case SIGSEGV
:
1134 case SIGBUS
: case SIGSYS
: case SIGXCPU
: case SIGXFSZ
:
1135 if (do_coredump(signr
, regs
))
1140 sigaddset(¤t
->pending
.signal
, signr
);
1141 recalc_sigpending(current
);
1142 current
->flags
|= PF_SIGNALED
;
1148 /* Whee! Actually deliver the signal. */
1149 handle_signal(signr
, ka
, &info
, oldset
, regs
);
1153 /* Did we come from a system call? */
1154 if (regs
->orig_d0
>= 0)
1155 /* Restart the system call - no handlers present */
1156 handle_restart(regs
, NULL
, 0);
1158 /* If we are about to discard some frame stuff we must copy
1159 over the remaining frame. */
1161 struct pt_regs
*tregs
=
1162 (struct pt_regs
*) ((ulong
) regs
+ regs
->stkadj
);
1164 /* This must be copied with decreasing addresses to
1168 tregs
->pc
= regs
->pc
;
1169 tregs
->sr
= regs
->sr
;