diff options
author | Bernd Schmidt <bernds_cb1@t-online.de> | 2008-04-23 14:51:36 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-04-23 14:51:36 -0400 |
commit | 697a9d65aa799940da1c9145944c6b9bd0f442c5 (patch) | |
tree | c92b8e314e3bcc5ccaca4cfa26b00648230abe9e /arch | |
parent | 5af29f595813cce3c125d01d2500be483732ef4f (diff) |
[Blackfin] arch: a rather old performance improvement for the signal handling code
This is a rather old performance improvement for the signal handling
code, which was originally only committed on the 2007R1 branch as a
workaround for what we suspected to be a hardware bug.
There's no point in constructing a sigreturn stub on the stack and
flushing caches; we can just make signal handlers return to a known
location in the fixed code area.
Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/kernel/signal.c | 20 |
1 files changed, 4 insertions, 16 deletions
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 71cfcd28b39f..d1fa24401dc6 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
40 | #include <asm/ucontext.h> | 40 | #include <asm/ucontext.h> |
41 | #include <asm/fixed_code.h> | ||
41 | 42 | ||
42 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
43 | 44 | ||
@@ -50,6 +51,8 @@ struct rt_sigframe { | |||
50 | int sig; | 51 | int sig; |
51 | struct siginfo *pinfo; | 52 | struct siginfo *pinfo; |
52 | void *puc; | 53 | void *puc; |
54 | /* This is no longer needed by the kernel, but unfortunately userspace | ||
55 | * code expects it to be there. */ | ||
53 | char retcode[8]; | 56 | char retcode[8]; |
54 | struct siginfo info; | 57 | struct siginfo info; |
55 | struct ucontext uc; | 58 | struct ucontext uc; |
@@ -159,11 +162,6 @@ static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *reg | |||
159 | return err; | 162 | return err; |
160 | } | 163 | } |
161 | 164 | ||
162 | static inline void push_cache(unsigned long vaddr, unsigned int len) | ||
163 | { | ||
164 | flush_icache_range(vaddr, vaddr + len); | ||
165 | } | ||
166 | |||
167 | static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 165 | static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
168 | size_t frame_size) | 166 | size_t frame_size) |
169 | { | 167 | { |
@@ -209,19 +207,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, | |||
209 | err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs); | 207 | err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs); |
210 | err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 208 | err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
211 | 209 | ||
212 | /* Set up to return from userspace. */ | ||
213 | err |= __put_user(0x28, &(frame->retcode[0])); | ||
214 | err |= __put_user(0xe1, &(frame->retcode[1])); | ||
215 | err |= __put_user(0xad, &(frame->retcode[2])); | ||
216 | err |= __put_user(0x00, &(frame->retcode[3])); | ||
217 | err |= __put_user(0xa0, &(frame->retcode[4])); | ||
218 | err |= __put_user(0x00, &(frame->retcode[5])); | ||
219 | |||
220 | if (err) | 210 | if (err) |
221 | goto give_sigsegv; | 211 | goto give_sigsegv; |
222 | 212 | ||
223 | push_cache((unsigned long)&frame->retcode, sizeof(frame->retcode)); | ||
224 | |||
225 | /* Set up registers for signal handler */ | 213 | /* Set up registers for signal handler */ |
226 | wrusp((unsigned long)frame); | 214 | wrusp((unsigned long)frame); |
227 | if (get_personality & FDPIC_FUNCPTRS) { | 215 | if (get_personality & FDPIC_FUNCPTRS) { |
@@ -231,7 +219,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, | |||
231 | __get_user(regs->p3, &funcptr->GOT); | 219 | __get_user(regs->p3, &funcptr->GOT); |
232 | } else | 220 | } else |
233 | regs->pc = (unsigned long)ka->sa.sa_handler; | 221 | regs->pc = (unsigned long)ka->sa.sa_handler; |
234 | regs->rets = (unsigned long)(frame->retcode); | 222 | regs->rets = SIGRETURN_STUB; |
235 | 223 | ||
236 | regs->r0 = frame->sig; | 224 | regs->r0 = frame->sig; |
237 | regs->r1 = (unsigned long)(&frame->info); | 225 | regs->r1 = (unsigned long)(&frame->info); |