aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 14:53:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 14:53:44 -0400
commit86c47b70f62a7072d441ba212aab33c2f82627c2 (patch)
treed03988bd2226966352bb7f3c2e82ff545353d2c4 /arch/cris
parent1193755ac6328ad240ba987e6ec41d5e8baf0680 (diff)
parent44fbbb3dc687c9709a6f2236197316e5c79ab1eb (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull third pile of signal handling patches from Al Viro: "This time it's mostly helpers and conversions to them; there's a lot of stuff remaining in the tree, but that'll either go in -rc2 (isolated bug fixes, ideally via arch maintainers' trees) or will sit there until the next cycle." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: x86: get rid of calling do_notify_resume() when returning to kernel mode blackfin: check __get_user() return value whack-a-mole with TIF_FREEZE FRV: Optimise the system call exit path in entry.S [ver #2] FRV: Shrink TIF_WORK_MASK [ver #2] FRV: Prevent syscall exit tracing and notify_resume at end of kernel exceptions new helper: signal_delivered() powerpc: get rid of restore_sigmask() most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set set_restore_sigmask() is never called without SIGPENDING (and never should be) TIF_RESTORE_SIGMASK can be set only when TIF_SIGPENDING is set don't call try_to_freeze() from do_signal() pull clearing RESTORE_SIGMASK into block_sigmask() sh64: failure to build sigframe != signal without handler openrisc: tracehook_signal_handler() is supposed to be called on success new helper: sigmask_to_save() new helper: restore_saved_sigmask() new helpers: {clear,test,test_and_clear}_restore_sigmask() HAVE_RESTORE_SIGMASK is defined on all architectures now
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v10/kernel/signal.c34
-rw-r--r--arch/cris/arch-v32/kernel/signal.c36
2 files changed, 12 insertions, 58 deletions
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index e16f8f297f61..0bb477c13a4e 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -31,8 +31,6 @@
31 31
32#define DEBUG_SIG 0 32#define DEBUG_SIG 0
33 33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36/* a syscall in Linux/CRIS is a break 13 instruction which is 2 bytes */ 34/* a syscall in Linux/CRIS is a break 13 instruction which is 2 bytes */
37/* manipulate regs so that upon return, it will be re-executed */ 35/* manipulate regs so that upon return, it will be re-executed */
38 36
@@ -176,7 +174,6 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
176 sizeof(frame->extramask)))) 174 sizeof(frame->extramask))))
177 goto badframe; 175 goto badframe;
178 176
179 sigdelsetmask(&set, ~_BLOCKABLE);
180 set_current_blocked(&set); 177 set_current_blocked(&set);
181 178
182 if (restore_sigcontext(regs, &frame->sc)) 179 if (restore_sigcontext(regs, &frame->sc))
@@ -212,7 +209,6 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
212 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 209 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
213 goto badframe; 210 goto badframe;
214 211
215 sigdelsetmask(&set, ~_BLOCKABLE);
216 set_current_blocked(&set); 212 set_current_blocked(&set);
217 213
218 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 214 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
@@ -415,10 +411,11 @@ give_sigsegv:
415 * OK, we're invoking a handler 411 * OK, we're invoking a handler
416 */ 412 */
417 413
418static inline int handle_signal(int canrestart, unsigned long sig, 414static inline void handle_signal(int canrestart, unsigned long sig,
419 siginfo_t *info, struct k_sigaction *ka, 415 siginfo_t *info, struct k_sigaction *ka,
420 sigset_t *oldset, struct pt_regs *regs) 416 struct pt_regs *regs)
421{ 417{
418 sigset_t *oldset = sigmask_to_save();
422 int ret; 419 int ret;
423 420
424 /* Are we from a system call? */ 421 /* Are we from a system call? */
@@ -456,9 +453,7 @@ static inline int handle_signal(int canrestart, unsigned long sig,
456 ret = setup_frame(sig, ka, oldset, regs); 453 ret = setup_frame(sig, ka, oldset, regs);
457 454
458 if (ret == 0) 455 if (ret == 0)
459 block_sigmask(ka, sig); 456 signal_delivered(sig, info, ka, regs, 0);
460
461 return ret;
462} 457}
463 458
464/* 459/*
@@ -478,7 +473,6 @@ void do_signal(int canrestart, struct pt_regs *regs)
478 siginfo_t info; 473 siginfo_t info;
479 int signr; 474 int signr;
480 struct k_sigaction ka; 475 struct k_sigaction ka;
481 sigset_t *oldset;
482 476
483 /* 477 /*
484 * We want the common case to go fast, which 478 * We want the common case to go fast, which
@@ -489,23 +483,10 @@ void do_signal(int canrestart, struct pt_regs *regs)
489 if (!user_mode(regs)) 483 if (!user_mode(regs))
490 return; 484 return;
491 485
492 if (test_thread_flag(TIF_RESTORE_SIGMASK))
493 oldset = &current->saved_sigmask;
494 else
495 oldset = &current->blocked;
496
497 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 486 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
498 if (signr > 0) { 487 if (signr > 0) {
499 /* Whee! Actually deliver the signal. */ 488 /* Whee! Actually deliver the signal. */
500 if (handle_signal(canrestart, signr, &info, &ka, 489 handle_signal(canrestart, signr, &info, &ka, regs);
501 oldset, regs)) {
502 /* a signal was successfully delivered; the saved
503 * sigmask will have been stored in the signal frame,
504 * and will be restored by sigreturn, so we can simply
505 * clear the TIF_RESTORE_SIGMASK flag */
506 if (test_thread_flag(TIF_RESTORE_SIGMASK))
507 clear_thread_flag(TIF_RESTORE_SIGMASK);
508 }
509 return; 490 return;
510 } 491 }
511 492
@@ -525,8 +506,5 @@ void do_signal(int canrestart, struct pt_regs *regs)
525 506
526 /* if there's no signal to deliver, we just put the saved sigmask 507 /* if there's no signal to deliver, we just put the saved sigmask
527 * back */ 508 * back */
528 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 509 restore_saved_sigmask();
529 clear_thread_flag(TIF_RESTORE_SIGMASK);
530 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
531 }
532} 510}
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index b338d8fc0c12..b60d1b65a426 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -24,9 +24,6 @@
24 24
25extern unsigned long cris_signal_return_page; 25extern unsigned long cris_signal_return_page;
26 26
27/* Flag to check if a signal is blockable. */
28#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
29
30/* 27/*
31 * A syscall in CRIS is really a "break 13" instruction, which is 2 28 * A syscall in CRIS is really a "break 13" instruction, which is 2
32 * bytes. The registers is manipulated so upon return the instruction 29 * bytes. The registers is manipulated so upon return the instruction
@@ -167,7 +164,6 @@ sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
167 sizeof(frame->extramask)))) 164 sizeof(frame->extramask))))
168 goto badframe; 165 goto badframe;
169 166
170 sigdelsetmask(&set, ~_BLOCKABLE);
171 set_current_blocked(&set); 167 set_current_blocked(&set);
172 168
173 if (restore_sigcontext(regs, &frame->sc)) 169 if (restore_sigcontext(regs, &frame->sc))
@@ -208,7 +204,6 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
208 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 204 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
209 goto badframe; 205 goto badframe;
210 206
211 sigdelsetmask(&set, ~_BLOCKABLE);
212 set_current_blocked(&set); 207 set_current_blocked(&set);
213 208
214 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 209 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
@@ -434,11 +429,12 @@ give_sigsegv:
434} 429}
435 430
436/* Invoke a signal handler to, well, handle the signal. */ 431/* Invoke a signal handler to, well, handle the signal. */
437static inline int 432static inline void
438handle_signal(int canrestart, unsigned long sig, 433handle_signal(int canrestart, unsigned long sig,
439 siginfo_t *info, struct k_sigaction *ka, 434 siginfo_t *info, struct k_sigaction *ka,
440 sigset_t *oldset, struct pt_regs * regs) 435 struct pt_regs * regs)
441{ 436{
437 sigset_t *oldset = sigmask_to_save();
442 int ret; 438 int ret;
443 439
444 /* Check if this got called from a system call. */ 440 /* Check if this got called from a system call. */
@@ -489,9 +485,7 @@ handle_signal(int canrestart, unsigned long sig,
489 ret = setup_frame(sig, ka, oldset, regs); 485 ret = setup_frame(sig, ka, oldset, regs);
490 486
491 if (ret == 0) 487 if (ret == 0)
492 block_sigmask(ka, sig); 488 signal_delivered(sig, info, ka, regs, 0);
493
494 return ret;
495} 489}
496 490
497/* 491/*
@@ -511,7 +505,6 @@ do_signal(int canrestart, struct pt_regs *regs)
511 int signr; 505 int signr;
512 siginfo_t info; 506 siginfo_t info;
513 struct k_sigaction ka; 507 struct k_sigaction ka;
514 sigset_t *oldset;
515 508
516 /* 509 /*
517 * The common case should go fast, which is why this point is 510 * The common case should go fast, which is why this point is
@@ -521,25 +514,11 @@ do_signal(int canrestart, struct pt_regs *regs)
521 if (!user_mode(regs)) 514 if (!user_mode(regs))
522 return; 515 return;
523 516
524 if (test_thread_flag(TIF_RESTORE_SIGMASK))
525 oldset = &current->saved_sigmask;
526 else
527 oldset = &current->blocked;
528
529 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 517 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
530 518
531 if (signr > 0) { 519 if (signr > 0) {
532 /* Whee! Actually deliver the signal. */ 520 /* Whee! Actually deliver the signal. */
533 if (handle_signal(canrestart, signr, &info, &ka, 521 handle_signal(canrestart, signr, &info, &ka, regs);
534 oldset, regs)) {
535 /* a signal was successfully delivered; the saved
536 * sigmask will have been stored in the signal frame,
537 * and will be restored by sigreturn, so we can simply
538 * clear the TIF_RESTORE_SIGMASK flag */
539 if (test_thread_flag(TIF_RESTORE_SIGMASK))
540 clear_thread_flag(TIF_RESTORE_SIGMASK);
541 }
542
543 return; 522 return;
544 } 523 }
545 524
@@ -560,10 +539,7 @@ do_signal(int canrestart, struct pt_regs *regs)
560 539
561 /* if there's no signal to deliver, we just put the saved sigmask 540 /* if there's no signal to deliver, we just put the saved sigmask
562 * back */ 541 * back */
563 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 542 restore_saved_sigmask();
564 clear_thread_flag(TIF_RESTORE_SIGMASK);
565 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
566 }
567} 543}
568 544
569asmlinkage void 545asmlinkage void