diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-11 23:35:08 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2011-01-07 08:06:59 -0500 |
commit | 089e449a82cd5ba8a858dfea88e754afb9341037 (patch) | |
tree | c95c95611e7e75c9dafd4cb6a8dfe633b1047fab /arch/m68knommu | |
parent | d1574df7e01d427c2ed80ada11433a72907ca472 (diff) |
m68knommu: Don't lose state if sigframe setup fails
exact parallel to m68k analog
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68knommu')
-rw-r--r-- | arch/m68knommu/kernel/signal.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c index c070f3f64255..e00f1bb12b8a 100644 --- a/arch/m68knommu/kernel/signal.c +++ b/arch/m68knommu/kernel/signal.c | |||
@@ -528,7 +528,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | |||
528 | return (void *)((usp - frame_size) & -8UL); | 528 | return (void *)((usp - frame_size) & -8UL); |
529 | } | 529 | } |
530 | 530 | ||
531 | static void setup_frame (int sig, struct k_sigaction *ka, | 531 | static int setup_frame (int sig, struct k_sigaction *ka, |
532 | sigset_t *set, struct pt_regs *regs) | 532 | sigset_t *set, struct pt_regs *regs) |
533 | { | 533 | { |
534 | struct sigframe *frame; | 534 | struct sigframe *frame; |
@@ -582,14 +582,14 @@ adjust_stack: | |||
582 | tregs->pc = regs->pc; | 582 | tregs->pc = regs->pc; |
583 | tregs->sr = regs->sr; | 583 | tregs->sr = regs->sr; |
584 | } | 584 | } |
585 | return; | 585 | return err; |
586 | 586 | ||
587 | give_sigsegv: | 587 | give_sigsegv: |
588 | force_sigsegv(sig, current); | 588 | force_sigsegv(sig, current); |
589 | goto adjust_stack; | 589 | goto adjust_stack; |
590 | } | 590 | } |
591 | 591 | ||
592 | static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | 592 | static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, |
593 | sigset_t *set, struct pt_regs *regs) | 593 | sigset_t *set, struct pt_regs *regs) |
594 | { | 594 | { |
595 | struct rt_sigframe *frame; | 595 | struct rt_sigframe *frame; |
@@ -646,7 +646,7 @@ adjust_stack: | |||
646 | tregs->pc = regs->pc; | 646 | tregs->pc = regs->pc; |
647 | tregs->sr = regs->sr; | 647 | tregs->sr = regs->sr; |
648 | } | 648 | } |
649 | return; | 649 | return err; |
650 | 650 | ||
651 | give_sigsegv: | 651 | give_sigsegv: |
652 | force_sigsegv(sig, current); | 652 | force_sigsegv(sig, current); |
@@ -693,6 +693,7 @@ static void | |||
693 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | 693 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, |
694 | sigset_t *oldset, struct pt_regs *regs) | 694 | sigset_t *oldset, struct pt_regs *regs) |
695 | { | 695 | { |
696 | int err; | ||
696 | /* are we from a system call? */ | 697 | /* are we from a system call? */ |
697 | if (regs->orig_d0 >= 0) | 698 | if (regs->orig_d0 >= 0) |
698 | /* If so, check system call restarting.. */ | 699 | /* If so, check system call restarting.. */ |
@@ -700,9 +701,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
700 | 701 | ||
701 | /* set up the stack frame */ | 702 | /* set up the stack frame */ |
702 | if (ka->sa.sa_flags & SA_SIGINFO) | 703 | if (ka->sa.sa_flags & SA_SIGINFO) |
703 | setup_rt_frame(sig, ka, info, oldset, regs); | 704 | err = setup_rt_frame(sig, ka, info, oldset, regs); |
704 | else | 705 | else |
705 | setup_frame(sig, ka, oldset, regs); | 706 | err = setup_frame(sig, ka, oldset, regs); |
707 | |||
708 | if (err) | ||
709 | return; | ||
706 | 710 | ||
707 | spin_lock_irq(¤t->sighand->siglock); | 711 | spin_lock_irq(¤t->sighand->siglock); |
708 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 712 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -710,6 +714,8 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
710 | sigaddset(¤t->blocked,sig); | 714 | sigaddset(¤t->blocked,sig); |
711 | recalc_sigpending(); | 715 | recalc_sigpending(); |
712 | spin_unlock_irq(¤t->sighand->siglock); | 716 | spin_unlock_irq(¤t->sighand->siglock); |
717 | |||
718 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
713 | } | 719 | } |
714 | 720 | ||
715 | /* | 721 | /* |
@@ -742,7 +748,6 @@ asmlinkage void do_signal(struct pt_regs *regs) | |||
742 | if (signr > 0) { | 748 | if (signr > 0) { |
743 | /* Whee! Actually deliver the signal. */ | 749 | /* Whee! Actually deliver the signal. */ |
744 | handle_signal(signr, &ka, &info, oldset, regs); | 750 | handle_signal(signr, &ka, &info, oldset, regs); |
745 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
746 | return; | 751 | return; |
747 | } | 752 | } |
748 | 753 | ||