diff options
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/signal.c | 67 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 2 |
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 | ||
217 | static inline void | 215 | static 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 | */ |
250 | static int | 248 | static void |
251 | handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | 249 | handle_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 = ¤t->saved_sigmask; | ||
293 | else | ||
294 | oldset = ¤t->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, ¤t->saved_sigmask, NULL); | ||
325 | } | ||
326 | } | 297 | } |
327 | 298 | ||
328 | /* | 299 | /* |
@@ -330,7 +301,7 @@ asmlinkage void do_signal(struct pt_regs *regs) | |||
330 | */ | 301 | */ |
331 | asmlinkage void do_notify_resume(struct pt_regs *regs) | 302 | asmlinkage 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); |