aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r--arch/avr32/kernel/entry-avr32b.S4
-rw-r--r--arch/avr32/kernel/signal.c41
2 files changed, 15 insertions, 30 deletions
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index 5e6beb2597a..df288418131 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -281,7 +281,7 @@ syscall_exit_work:
281 ld.w r1, r0[TI_flags] 281 ld.w r1, r0[TI_flags]
282 rjmp 1b 282 rjmp 1b
283 283
2842: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME 2842: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
285 tst r1, r2 285 tst r1, r2
286 breq 3f 286 breq 3f
287 unmask_interrupts 287 unmask_interrupts
@@ -587,7 +587,7 @@ fault_exit_work:
587 ld.w r1, r0[TI_flags] 587 ld.w r1, r0[TI_flags]
588 rjmp fault_exit_work 588 rjmp fault_exit_work
589 589
5901: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME 5901: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
591 tst r1, r2 591 tst r1, r2
592 breq 2f 592 breq 2f
593 unmask_interrupts 593 unmask_interrupts
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index e7595ef74f5..c140f9b41dc 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -22,8 +22,6 @@
22#include <asm/ucontext.h> 22#include <asm/ucontext.h>
23#include <asm/syscalls.h> 23#include <asm/syscalls.h>
24 24
25#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
26
27asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 25asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
28 struct pt_regs *regs) 26 struct pt_regs *regs)
29{ 27{
@@ -89,7 +87,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
89 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 87 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
90 goto badframe; 88 goto badframe;
91 89
92 sigdelsetmask(&set, ~_BLOCKABLE);
93 set_current_blocked(&set); 90 set_current_blocked(&set);
94 91
95 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 92 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
@@ -224,30 +221,27 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
224 221
225static inline void 222static inline void
226handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 223handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
227 sigset_t *oldset, struct pt_regs *regs, int syscall) 224 struct pt_regs *regs, int syscall)
228{ 225{
229 int ret; 226 int ret;
230 227
231 /* 228 /*
232 * Set up the stack frame 229 * Set up the stack frame
233 */ 230 */
234 ret = setup_rt_frame(sig, ka, info, oldset, regs); 231 ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
235 232
236 /* 233 /*
237 * Check that the resulting registers are sane 234 * Check that the resulting registers are sane
238 */ 235 */
239 ret |= !valid_user_regs(regs); 236 ret |= !valid_user_regs(regs);
240 237
241 if (ret != 0) {
242 force_sigsegv(sig, current);
243 return;
244 }
245
246 /* 238 /*
247 * Block the signal if we were successful. 239 * Block the signal if we were successful.
248 */ 240 */
249 block_sigmask(ka, sig); 241 if (ret != 0)
250 clear_thread_flag(TIF_RESTORE_SIGMASK); 242 force_sigsegv(sig, current);
243 else
244 signal_delivered(sig, info, ka, regs, 0);
251} 245}
252 246
253/* 247/*
@@ -255,7 +249,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
255 * doesn't want to handle. Thus you cannot kill init even with a 249 * doesn't want to handle. Thus you cannot kill init even with a
256 * SIGKILL even by mistake. 250 * SIGKILL even by mistake.
257 */ 251 */
258int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall) 252static void do_signal(struct pt_regs *regs, int syscall)
259{ 253{
260 siginfo_t info; 254 siginfo_t info;
261 int signr; 255 int signr;
@@ -267,12 +261,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
267 * without doing anything if so. 261 * without doing anything if so.
268 */ 262 */
269 if (!user_mode(regs)) 263 if (!user_mode(regs))
270 return 0; 264 return;
271
272 if (test_thread_flag(TIF_RESTORE_SIGMASK))
273 oldset = &current->saved_sigmask;
274 else if (!oldset)
275 oldset = &current->blocked;
276 265
277 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 266 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
278 if (syscall) { 267 if (syscall) {
@@ -297,15 +286,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
297 286
298 if (signr == 0) { 287 if (signr == 0) {
299 /* No signal to deliver -- put the saved sigmask back */ 288 /* No signal to deliver -- put the saved sigmask back */
300 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 289 restore_saved_sigmask();
301 clear_thread_flag(TIF_RESTORE_SIGMASK); 290 return;
302 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
303 }
304 return 0;
305 } 291 }
306 292
307 handle_signal(signr, &ka, &info, oldset, regs, syscall); 293 handle_signal(signr, &ka, &info, regs, syscall);
308 return 1;
309} 294}
310 295
311asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) 296asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
@@ -315,8 +300,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
315 if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) 300 if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR)
316 syscall = 1; 301 syscall = 1;
317 302
318 if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 303 if (ti->flags & _TIF_SIGPENDING))
319 do_signal(regs, &current->blocked, syscall); 304 do_signal(regs, syscall);
320 305
321 if (ti->flags & _TIF_NOTIFY_RESUME) { 306 if (ti->flags & _TIF_NOTIFY_RESUME) {
322 clear_thread_flag(TIF_NOTIFY_RESUME); 307 clear_thread_flag(TIF_NOTIFY_RESUME);