aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/signal.c')
-rw-r--r--arch/blackfin/kernel/signal.c20
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
162static inline void push_cache(unsigned long vaddr, unsigned int len)
163{
164 flush_icache_range(vaddr, vaddr + len);
165}
166
167static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 165static 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);