aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-10-03 01:36:58 -0400
committerGeert Uytterhoeven <geert@linux-m68k.org>2011-01-07 08:01:34 -0500
commit90731d7537317ad5d9672187f7a1dff90b29bb12 (patch)
tree8d089b54e65358190f47011a122779d996b9ae90 /arch/m68k
parentf85741eb5fb2653fd9138b4bef68396615c720f7 (diff)
m68k: If we fail to set sigframe up, just leave regs alone...
Same principle as with the previous patch - do not destroy the state if sigframe setup fails. Incidentally, it's actually _less_ work - we don't need to go through adjust_stack dance on failure if we don't touch regs->stkadj until we know we'd written sigframe out. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/kernel/signal.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index a6dd61418e76..16ea319d1ed5 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -761,10 +761,8 @@ static int setup_frame (int sig, struct k_sigaction *ka,
761 761
762 frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); 762 frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
763 763
764 if (fsize) { 764 if (fsize)
765 err |= copy_to_user (frame + 1, regs + 1, fsize); 765 err |= copy_to_user (frame + 1, regs + 1, fsize);
766 regs->stkadj = fsize;
767 }
768 766
769 err |= __put_user((current_thread_info()->exec_domain 767 err |= __put_user((current_thread_info()->exec_domain
770 && current_thread_info()->exec_domain->signal_invmap 768 && current_thread_info()->exec_domain->signal_invmap
@@ -794,11 +792,21 @@ static int setup_frame (int sig, struct k_sigaction *ka,
794 792
795 push_cache ((unsigned long) &frame->retcode); 793 push_cache ((unsigned long) &frame->retcode);
796 794
797 /* Set up registers for signal handler */ 795 /*
796 * Set up registers for signal handler. All the state we are about
797 * to destroy is successfully copied to sigframe.
798 */
798 wrusp ((unsigned long) frame); 799 wrusp ((unsigned long) frame);
799 regs->pc = (unsigned long) ka->sa.sa_handler; 800 regs->pc = (unsigned long) ka->sa.sa_handler;
800 801
801adjust_stack: 802 /*
803 * This is subtle; if we build more than one sigframe, all but the
804 * first one will see frame format 0 and have fsize == 0, so we won't
805 * screw stkadj.
806 */
807 if (fsize)
808 regs->stkadj = fsize;
809
802 /* Prepare to skip over the extra stuff in the exception frame. */ 810 /* Prepare to skip over the extra stuff in the exception frame. */
803 if (regs->stkadj) { 811 if (regs->stkadj) {
804 struct pt_regs *tregs = 812 struct pt_regs *tregs =
@@ -813,11 +821,11 @@ adjust_stack:
813 tregs->pc = regs->pc; 821 tregs->pc = regs->pc;
814 tregs->sr = regs->sr; 822 tregs->sr = regs->sr;
815 } 823 }
816 return err; 824 return 0;
817 825
818give_sigsegv: 826give_sigsegv:
819 force_sigsegv(sig, current); 827 force_sigsegv(sig, current);
820 goto adjust_stack; 828 return err;
821} 829}
822 830
823static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 831static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -837,10 +845,8 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
837 845
838 frame = get_sigframe(ka, regs, sizeof(*frame)); 846 frame = get_sigframe(ka, regs, sizeof(*frame));
839 847
840 if (fsize) { 848 if (fsize)
841 err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); 849 err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
842 regs->stkadj = fsize;
843 }
844 850
845 err |= __put_user((current_thread_info()->exec_domain 851 err |= __put_user((current_thread_info()->exec_domain
846 && current_thread_info()->exec_domain->signal_invmap 852 && current_thread_info()->exec_domain->signal_invmap
@@ -882,11 +888,21 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
882 888
883 push_cache ((unsigned long) &frame->retcode); 889 push_cache ((unsigned long) &frame->retcode);
884 890
885 /* Set up registers for signal handler */ 891 /*
892 * Set up registers for signal handler. All the state we are about
893 * to destroy is successfully copied to sigframe.
894 */
886 wrusp ((unsigned long) frame); 895 wrusp ((unsigned long) frame);
887 regs->pc = (unsigned long) ka->sa.sa_handler; 896 regs->pc = (unsigned long) ka->sa.sa_handler;
888 897
889adjust_stack: 898 /*
899 * This is subtle; if we build more than one sigframe, all but the
900 * first one will see frame format 0 and have fsize == 0, so we won't
901 * screw stkadj.
902 */
903 if (fsize)
904 regs->stkadj = fsize;
905
890 /* Prepare to skip over the extra stuff in the exception frame. */ 906 /* Prepare to skip over the extra stuff in the exception frame. */
891 if (regs->stkadj) { 907 if (regs->stkadj) {
892 struct pt_regs *tregs = 908 struct pt_regs *tregs =
@@ -901,11 +917,11 @@ adjust_stack:
901 tregs->pc = regs->pc; 917 tregs->pc = regs->pc;
902 tregs->sr = regs->sr; 918 tregs->sr = regs->sr;
903 } 919 }
904 return err; 920 return 0;
905 921
906give_sigsegv: 922give_sigsegv:
907 force_sigsegv(sig, current); 923 force_sigsegv(sig, current);
908 goto adjust_stack; 924 return err;
909} 925}
910 926
911static inline void 927static inline void