aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWilson Callan <wcallan@savantav.com>2008-04-30 22:16:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-05-01 11:08:35 -0400
commit2d7f16d6d12682c41fb287ea8261df8e4679f638 (patch)
treec9e8bce26b85ec9f4790e0f18baaa24c8f6d8f38 /arch
parent10ed2195bb8aef4358223f07bb00e8cf9b278bf2 (diff)
m68knommu: fix signal handling return path
The return from software signal handling pushes code on the stack that system calls to the kernels cleanup code. This is borrowed directly from the m68k linux signal handler. The rt signal case is not quite right for the restricted instruction set of the ColdFire parts. And neither the normal signal case or rt signal case properly flushes/pushes the appropriate cache lines. Rework the return path to just call back through some code fragments in the kernel proper (with no MMU in the way we can do this). No cache problems, and less code overall. Original patch submitted by Wilson Callan <wcallan@savantav.com> Greg fixed the rt signal return path to use the proper system call Signed-off-by: Greg Ungerer <gerg@uclinux.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/m68knommu/kernel/entry.S9
-rw-r--r--arch/m68knommu/kernel/signal.c21
2 files changed, 13 insertions, 17 deletions
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index 1e7ea6a3e1a1..f4782d2dce8f 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -32,6 +32,7 @@
32#include <asm/segment.h> 32#include <asm/segment.h>
33#include <asm/asm-offsets.h> 33#include <asm/asm-offsets.h>
34#include <asm/entry.h> 34#include <asm/entry.h>
35#include <asm/unistd.h>
35 36
36.text 37.text
37 38
@@ -140,3 +141,11 @@ ENTRY(sys_rt_sigreturn)
140 RESTORE_SWITCH_STACK 141 RESTORE_SWITCH_STACK
141 rts 142 rts
142 143
144ENTRY(ret_from_user_signal)
145 moveq #__NR_sigreturn,%d0
146 trap #0
147
148ENTRY(ret_from_user_rt_signal)
149 move #__NR_rt_sigreturn,%d0
150 trap #0
151
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
index 70371378db86..bbfcae9e52b4 100644
--- a/arch/m68knommu/kernel/signal.c
+++ b/arch/m68knommu/kernel/signal.c
@@ -51,6 +51,8 @@
51 51
52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53 53
54void ret_from_user_signal(void);
55void ret_from_user_rt_signal(void);
54asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); 56asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
55 57
56/* 58/*
@@ -539,10 +541,6 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
539 return err; 541 return err;
540} 542}
541 543
542static inline void push_cache (unsigned long vaddr)
543{
544}
545
546static inline void * 544static inline void *
547get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 545get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
548{ 546{
@@ -586,16 +584,11 @@ static void setup_frame (int sig, struct k_sigaction *ka,
586 err |= copy_to_user (&frame->sc, &context, sizeof(context)); 584 err |= copy_to_user (&frame->sc, &context, sizeof(context));
587 585
588 /* Set up to return from userspace. */ 586 /* Set up to return from userspace. */
589 err |= __put_user(frame->retcode, &frame->pretcode); 587 err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
590 /* moveq #,d0; trap #0 */
591 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
592 (long *)(frame->retcode));
593 588
594 if (err) 589 if (err)
595 goto give_sigsegv; 590 goto give_sigsegv;
596 591
597 push_cache ((unsigned long) &frame->retcode);
598
599 /* Set up registers for signal handler */ 592 /* Set up registers for signal handler */
600 wrusp ((unsigned long) frame); 593 wrusp ((unsigned long) frame);
601 regs->pc = (unsigned long) ka->sa.sa_handler; 594 regs->pc = (unsigned long) ka->sa.sa_handler;
@@ -655,17 +648,11 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
655 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 648 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
656 649
657 /* Set up to return from userspace. */ 650 /* Set up to return from userspace. */
658 err |= __put_user(frame->retcode, &frame->pretcode); 651 err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
659 /* moveq #,d0; notb d0; trap #0 */
660 err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
661 (long *)(frame->retcode + 0));
662 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
663 652
664 if (err) 653 if (err)
665 goto give_sigsegv; 654 goto give_sigsegv;
666 655
667 push_cache ((unsigned long) &frame->retcode);
668
669 /* Set up registers for signal handler */ 656 /* Set up registers for signal handler */
670 wrusp ((unsigned long) frame); 657 wrusp ((unsigned long) frame);
671 regs->pc = (unsigned long) ka->sa.sa_handler; 658 regs->pc = (unsigned long) ka->sa.sa_handler;