aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/kernel/signal_64.c93
1 files changed, 48 insertions, 45 deletions
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index ce3e851dffcb..08828ddd97ff 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -2,7 +2,7 @@
2 * arch/sh/kernel/signal_64.c 2 * arch/sh/kernel/signal_64.c
3 * 3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2008 Paul Mundt
6 * Copyright (C) 2004 Richard Curnow 6 * Copyright (C) 2004 Richard Curnow
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
@@ -43,7 +43,7 @@
43 43
44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
45 45
46static void 46static int
47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
48 sigset_t *oldset, struct pt_regs * regs); 48 sigset_t *oldset, struct pt_regs * regs);
49 49
@@ -80,21 +80,20 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
80 oldset = &current->blocked; 80 oldset = &current->blocked;
81 81
82 signr = get_signal_to_deliver(&info, &ka, regs, 0); 82 signr = get_signal_to_deliver(&info, &ka, regs, 0);
83
84 if (signr > 0) { 83 if (signr > 0) {
85 /* Whee! Actually deliver the signal. */ 84 /* Whee! Actually deliver the signal. */
86 handle_signal(signr, &info, &ka, oldset, regs); 85 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
87 86 /*
88 /* 87 * If a signal was successfully delivered, the
89 * If a signal was successfully delivered, the saved sigmask 88 * saved sigmask is in its frame, and we can
90 * is in its frame, and we can clear the TIF_RESTORE_SIGMASK 89 * clear the TIF_RESTORE_SIGMASK flag.
91 * flag. 90 */
92 */ 91 if (test_thread_flag(TIF_RESTORE_SIGMASK))
93 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 92 clear_thread_flag(TIF_RESTORE_SIGMASK);
94 clear_thread_flag(TIF_RESTORE_SIGMASK); 93
95 94 tracehook_signal_handler(signr, &info, &ka, regs, 0);
96 tracehook_signal_handler(signr, &info, &ka, regs, 0); 95 return 1;
97 return 1; 96 }
98 } 97 }
99 98
100no_signal: 99no_signal:
@@ -504,8 +503,8 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
504void sa_default_restorer(void); /* See comments below */ 503void sa_default_restorer(void); /* See comments below */
505void sa_default_rt_restorer(void); /* See comments below */ 504void sa_default_rt_restorer(void); /* See comments below */
506 505
507static void setup_frame(int sig, struct k_sigaction *ka, 506static int setup_frame(int sig, struct k_sigaction *ka,
508 sigset_t *set, struct pt_regs *regs) 507 sigset_t *set, struct pt_regs *regs)
509{ 508{
510 struct sigframe __user *frame; 509 struct sigframe __user *frame;
511 int err = 0; 510 int err = 0;
@@ -596,23 +595,21 @@ static void setup_frame(int sig, struct k_sigaction *ka,
596 595
597 set_fs(USER_DS); 596 set_fs(USER_DS);
598 597
599#if DEBUG_SIG
600 /* Broken %016Lx */ 598 /* Broken %016Lx */
601 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 599 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
602 signal, 600 signal, current->comm, current->pid, frame,
603 current->comm, current->pid, frame, 601 regs->pc >> 32, regs->pc & 0xffffffff,
604 regs->pc >> 32, regs->pc & 0xffffffff, 602 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
605 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
606#endif
607 603
608 return; 604 return 0;
609 605
610give_sigsegv: 606give_sigsegv:
611 force_sigsegv(sig, current); 607 force_sigsegv(sig, current);
608 return -EFAULT;
612} 609}
613 610
614static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 611static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
615 sigset_t *set, struct pt_regs *regs) 612 sigset_t *set, struct pt_regs *regs)
616{ 613{
617 struct rt_sigframe __user *frame; 614 struct rt_sigframe __user *frame;
618 int err = 0; 615 int err = 0;
@@ -702,29 +699,28 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
702 699
703 set_fs(USER_DS); 700 set_fs(USER_DS);
704 701
705#if DEBUG_SIG 702 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
706 /* Broken %016Lx */ 703 signal, current->comm, current->pid, frame,
707 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 704 regs->pc >> 32, regs->pc & 0xffffffff,
708 signal, 705 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
709 current->comm, current->pid, frame,
710 regs->pc >> 32, regs->pc & 0xffffffff,
711 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
712#endif
713 706
714 return; 707 return 0;
715 708
716give_sigsegv: 709give_sigsegv:
717 force_sigsegv(sig, current); 710 force_sigsegv(sig, current);
711 return -EFAULT;
718} 712}
719 713
720/* 714/*
721 * OK, we're invoking a handler 715 * OK, we're invoking a handler
722 */ 716 */
723 717
724static void 718static int
725handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 719handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
726 sigset_t *oldset, struct pt_regs * regs) 720 sigset_t *oldset, struct pt_regs * regs)
727{ 721{
722 int ret;
723
728 /* Are we from a system call? */ 724 /* Are we from a system call? */
729 if (regs->syscall_nr >= 0) { 725 if (regs->syscall_nr >= 0) {
730 /* If so, check system call restarting.. */ 726 /* If so, check system call restarting.. */
@@ -748,16 +744,23 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
748 744
749 /* Set up the stack frame */ 745 /* Set up the stack frame */
750 if (ka->sa.sa_flags & SA_SIGINFO) 746 if (ka->sa.sa_flags & SA_SIGINFO)
751 setup_rt_frame(sig, ka, info, oldset, regs); 747 ret = setup_rt_frame(sig, ka, info, oldset, regs);
752 else 748 else
753 setup_frame(sig, ka, oldset, regs); 749 ret = setup_frame(sig, ka, oldset, regs);
750
751 if (ka->sa.sa_flags & SA_ONESHOT)
752 ka->sa.sa_handler = SIG_DFL;
753
754 if (ret == 0) {
755 spin_lock_irq(&current->sighand->siglock);
756 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
757 if (!(ka->sa.sa_flags & SA_NODEFER))
758 sigaddset(&current->blocked,sig);
759 recalc_sigpending();
760 spin_unlock_irq(&current->sighand->siglock);
761 }
754 762
755 spin_lock_irq(&current->sighand->siglock); 763 return ret;
756 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
757 if (!(ka->sa.sa_flags & SA_NODEFER))
758 sigaddset(&current->blocked,sig);
759 recalc_sigpending();
760 spin_unlock_irq(&current->sighand->siglock);
761} 764}
762 765
763asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 766asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)