aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/include/asm/thread_info.h2
-rw-r--r--arch/blackfin/kernel/signal.c67
-rw-r--r--arch/blackfin/mach-common/entry.S2
3 files changed, 19 insertions, 52 deletions
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 02560fd8a121..53ad10005ae3 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -100,7 +100,6 @@ static inline struct thread_info *current_thread_info(void)
100 TIF_NEED_RESCHED */ 100 TIF_NEED_RESCHED */
101#define TIF_MEMDIE 4 /* is terminating due to OOM killer */ 101#define TIF_MEMDIE 4 /* is terminating due to OOM killer */
102#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ 102#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
103#define TIF_FREEZE 6 /* is freezing for suspend */
104#define TIF_IRQ_SYNC 7 /* sync pipeline stage */ 103#define TIF_IRQ_SYNC 7 /* sync pipeline stage */
105#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ 104#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
106#define TIF_SINGLESTEP 9 105#define TIF_SINGLESTEP 9
@@ -111,7 +110,6 @@ static inline struct thread_info *current_thread_info(void)
111#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 110#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
112#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 111#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
113#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 112#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
114#define _TIF_FREEZE (1<<TIF_FREEZE)
115#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC) 113#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC)
116#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 114#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
117#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) 115#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index fc9ecce8b6ce..6682b73a8523 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -19,8 +19,6 @@
19#include <asm/fixed_code.h> 19#include <asm/fixed_code.h>
20#include <asm/syscall.h> 20#include <asm/syscall.h>
21 21
22#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
23
24/* Location of the trace bit in SYSCFG. */ 22/* Location of the trace bit in SYSCFG. */
25#define TRACE_BITS 0x0001 23#define TRACE_BITS 0x0001
26 24
@@ -98,7 +96,6 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
98 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 96 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
99 goto badframe; 97 goto badframe;
100 98
101 sigdelsetmask(&set, ~_BLOCKABLE);
102 set_current_blocked(&set); 99 set_current_blocked(&set);
103 100
104 if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 101 if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
@@ -190,17 +187,22 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
190 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 187 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
191 188
192 if (err) 189 if (err)
193 goto give_sigsegv; 190 return -EFAULT;
194 191
195 /* Set up registers for signal handler */ 192 /* Set up registers for signal handler */
196 wrusp((unsigned long)frame);
197 if (current->personality & FDPIC_FUNCPTRS) { 193 if (current->personality & FDPIC_FUNCPTRS) {
198 struct fdpic_func_descriptor __user *funcptr = 194 struct fdpic_func_descriptor __user *funcptr =
199 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 195 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
200 __get_user(regs->pc, &funcptr->text); 196 u32 pc, p3;
201 __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;
202 } else 203 } else
203 regs->pc = (unsigned long)ka->sa.sa_handler; 204 regs->pc = (unsigned long)ka->sa.sa_handler;
205 wrusp((unsigned long)frame);
204 regs->rets = SIGRETURN_STUB; 206 regs->rets = SIGRETURN_STUB;
205 207
206 regs->r0 = frame->sig; 208 regs->r0 = frame->sig;
@@ -208,10 +210,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
208 regs->r2 = (unsigned long)(&frame->uc); 210 regs->r2 = (unsigned long)(&frame->uc);
209 211
210 return 0; 212 return 0;
211
212 give_sigsegv:
213 force_sigsegv(sig, current);
214 return -EFAULT;
215} 213}
216 214
217static inline void 215static inline void
@@ -247,24 +245,21 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
247/* 245/*
248 * OK, we're invoking a handler 246 * OK, we're invoking a handler
249 */ 247 */
250static int 248static void
251handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, 249handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
252 sigset_t *oldset, struct pt_regs *regs) 250 struct pt_regs *regs)
253{ 251{
254 int ret;
255
256 /* 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 */
257 if (regs->orig_p0 >= 0) 253 if (regs->orig_p0 >= 0)
258 /* If so, check system call restarting.. */ 254 /* If so, check system call restarting.. */
259 handle_restart(regs, ka, 1); 255 handle_restart(regs, ka, 1);
260 256
261 /* set up the stack frame */ 257 /* set up the stack frame */
262 ret = setup_rt_frame(sig, ka, info, oldset, regs); 258 if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
263 259 force_sigsegv(sig, current);
264 if (ret == 0) 260 else
265 block_sigmask(ka, sig); 261 signal_delivered(sig, info, ka, regs,
266 262 test_thread_flag(TIF_SINGLESTEP));
267 return ret;
268} 263}
269 264
270/* 265/*
@@ -281,37 +276,16 @@ asmlinkage void do_signal(struct pt_regs *regs)
281 siginfo_t info; 276 siginfo_t info;
282 int signr; 277 int signr;
283 struct k_sigaction ka; 278 struct k_sigaction ka;
284 sigset_t *oldset;
285 279
286 current->thread.esp0 = (unsigned long)regs; 280 current->thread.esp0 = (unsigned long)regs;
287 281
288 if (try_to_freeze())
289 goto no_signal;
290
291 if (test_thread_flag(TIF_RESTORE_SIGMASK))
292 oldset = &current->saved_sigmask;
293 else
294 oldset = &current->blocked;
295
296 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 282 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
297 if (signr > 0) { 283 if (signr > 0) {
298 /* Whee! Actually deliver the signal. */ 284 /* Whee! Actually deliver the signal. */
299 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 285 handle_signal(signr, &info, &ka, regs);
300 /* a signal was successfully delivered; the saved
301 * sigmask will have been stored in the signal frame,
302 * and will be restored by sigreturn, so we can simply
303 * clear the TIF_RESTORE_SIGMASK flag */
304 if (test_thread_flag(TIF_RESTORE_SIGMASK))
305 clear_thread_flag(TIF_RESTORE_SIGMASK);
306
307 tracehook_signal_handler(signr, &info, &ka, regs,
308 test_thread_flag(TIF_SINGLESTEP));
309 }
310
311 return; 286 return;
312 } 287 }
313 288
314 no_signal:
315 /* Did we come from a system call? */ 289 /* Did we come from a system call? */
316 if (regs->orig_p0 >= 0) 290 if (regs->orig_p0 >= 0)
317 /* Restart the system call - no handlers present */ 291 /* Restart the system call - no handlers present */
@@ -319,10 +293,7 @@ asmlinkage void do_signal(struct pt_regs *regs)
319 293
320 /* if there's no signal to deliver, we just put the saved sigmask 294 /* if there's no signal to deliver, we just put the saved sigmask
321 * back */ 295 * back */
322 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 296 restore_saved_sigmask();
323 clear_thread_flag(TIF_RESTORE_SIGMASK);
324 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
325 }
326} 297}
327 298
328/* 299/*
@@ -330,7 +301,7 @@ asmlinkage void do_signal(struct pt_regs *regs)
330 */ 301 */
331asmlinkage void do_notify_resume(struct pt_regs *regs) 302asmlinkage void do_notify_resume(struct pt_regs *regs)
332{ 303{
333 if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK)) 304 if (test_thread_flag(TIF_SIGPENDING))
334 do_signal(regs); 305 do_signal(regs);
335 306
336 if (test_thread_flag(TIF_NOTIFY_RESUME)) { 307 if (test_thread_flag(TIF_NOTIFY_RESUME)) {
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 80aa2535e2c9..04c2fbe41a7f 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -711,8 +711,6 @@ ENTRY(_system_call)
711 jump .Lresume_userspace_1; 711 jump .Lresume_userspace_1;
712 712
713.Lsyscall_sigpending: 713.Lsyscall_sigpending:
714 cc = BITTST(r7, TIF_RESTORE_SIGMASK);
715 if cc jump .Lsyscall_do_signals;
716 cc = BITTST(r7, TIF_SIGPENDING); 714 cc = BITTST(r7, TIF_SIGPENDING);
717 if cc jump .Lsyscall_do_signals; 715 if cc jump .Lsyscall_do_signals;
718 cc = BITTST(r7, TIF_NOTIFY_RESUME); 716 cc = BITTST(r7, TIF_NOTIFY_RESUME);