aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/kernel/signal.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 35459e681483..6682b73a8523 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -187,17 +187,22 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
187 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 187 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
188 188
189 if (err) 189 if (err)
190 goto give_sigsegv; 190 return -EFAULT;
191 191
192 /* Set up registers for signal handler */ 192 /* Set up registers for signal handler */
193 wrusp((unsigned long)frame);
194 if (current->personality & FDPIC_FUNCPTRS) { 193 if (current->personality & FDPIC_FUNCPTRS) {
195 struct fdpic_func_descriptor __user *funcptr = 194 struct fdpic_func_descriptor __user *funcptr =
196 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 195 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
197 __get_user(regs->pc, &funcptr->text); 196 u32 pc, p3;
198 __get_user(regs->p3, &funcptr->GOT); 197 err |= __get_user(pc, &funcptr->text);
198 err |= __get_user(p3, &funcptr->GOT);
199 if (err)
200 return -EFAULT;
201 regs->pc = pc;
202 regs->p3 = p3;
199 } else 203 } else
200 regs->pc = (unsigned long)ka->sa.sa_handler; 204 regs->pc = (unsigned long)ka->sa.sa_handler;
205 wrusp((unsigned long)frame);
201 regs->rets = SIGRETURN_STUB; 206 regs->rets = SIGRETURN_STUB;
202 207
203 regs->r0 = frame->sig; 208 regs->r0 = frame->sig;
@@ -205,10 +210,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
205 regs->r2 = (unsigned long)(&frame->uc); 210 regs->r2 = (unsigned long)(&frame->uc);
206 211
207 return 0; 212 return 0;
208
209 give_sigsegv:
210 force_sigsegv(sig, current);
211 return -EFAULT;
212} 213}
213 214
214static inline void 215static inline void
@@ -248,20 +249,17 @@ static void
248handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, 249handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
249 struct pt_regs *regs) 250 struct pt_regs *regs)
250{ 251{
251 int ret;
252
253 /* are we from a system call? to see pt_regs->orig_p0 */ 252 /* are we from a system call? to see pt_regs->orig_p0 */
254 if (regs->orig_p0 >= 0) 253 if (regs->orig_p0 >= 0)
255 /* If so, check system call restarting.. */ 254 /* If so, check system call restarting.. */
256 handle_restart(regs, ka, 1); 255 handle_restart(regs, ka, 1);
257 256
258 /* set up the stack frame */ 257 /* set up the stack frame */
259 ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); 258 if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
260 if (ret) 259 force_sigsegv(sig, current);
261 return; 260 else
262 261 signal_delivered(sig, info, ka, regs,
263 signal_delivered(sig, info, ka, regs, 262 test_thread_flag(TIF_SINGLESTEP));
264 test_thread_flag(TIF_SINGLESTEP));
265} 263}
266 264
267/* 265/*