aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal32.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-02-15 06:40:37 -0500
committerRalf Baechle <ralf@linux-mips.org>2007-02-18 16:31:35 -0500
commit151fd6acd94e12ef3a7d5fa0911a2590690c493f (patch)
tree33623a4cf6c6ce7c134f3cc5624dbcac26817238 /arch/mips/kernel/signal32.c
parent38201fb23cd554f942702cd938c3215a76296c87 (diff)
[MIPS] signals: Share even more code.
native and compat do_signal and handle_signal are identical and can easily be unified. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/signal32.c')
-rw-r--r--arch/mips/kernel/signal32.c118
1 files changed, 11 insertions, 107 deletions
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 9f829f63024b..02062fc59f77 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -104,7 +104,7 @@ typedef struct compat_siginfo {
104 */ 104 */
105#define __NR_O32_sigreturn 4119 105#define __NR_O32_sigreturn 4119
106#define __NR_O32_rt_sigreturn 4193 106#define __NR_O32_rt_sigreturn 4193
107#define __NR_O32_restart_syscall 4253 107#define __NR_O32_restart_syscall 4253
108 108
109/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
110 110
@@ -598,7 +598,7 @@ badframe:
598 force_sig(SIGSEGV, current); 598 force_sig(SIGSEGV, current);
599} 599}
600 600
601int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 601static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
602 int signr, sigset_t *set) 602 int signr, sigset_t *set)
603{ 603{
604 struct sigframe32 __user *frame; 604 struct sigframe32 __user *frame;
@@ -644,7 +644,7 @@ give_sigsegv:
644 return -EFAULT; 644 return -EFAULT;
645} 645}
646 646
647int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 647static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
648 int signr, sigset_t *set, siginfo_t *info) 648 int signr, sigset_t *set, siginfo_t *info)
649{ 649{
650 struct rt_sigframe32 __user *frame; 650 struct rt_sigframe32 __user *frame;
@@ -704,110 +704,14 @@ give_sigsegv:
704 return -EFAULT; 704 return -EFAULT;
705} 705}
706 706
707static inline int handle_signal(unsigned long sig, siginfo_t *info, 707/*
708 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) 708 * o32 compatibility on 64-bit kernels, without DSP ASE
709{ 709 */
710 int ret; 710struct mips_abi mips_abi_32 = {
711 711 .setup_frame = setup_frame_32,
712 switch (regs->regs[0]) { 712 .setup_rt_frame = setup_rt_frame_32,
713 case ERESTART_RESTARTBLOCK: 713 .restart = __NR_O32_restart_syscall
714 case ERESTARTNOHAND: 714};
715 regs->regs[2] = EINTR;
716 break;
717 case ERESTARTSYS:
718 if (!(ka->sa.sa_flags & SA_RESTART)) {
719 regs->regs[2] = EINTR;
720 break;
721 }
722 /* fallthrough */
723 case ERESTARTNOINTR: /* Userland will reload $v0. */
724 regs->regs[7] = regs->regs[26];
725 regs->cp0_epc -= 8;
726 }
727
728 regs->regs[0] = 0; /* Don't deal with this again. */
729
730 if (ka->sa.sa_flags & SA_SIGINFO)
731 ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
732 else
733 ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
734
735 spin_lock_irq(&current->sighand->siglock);
736 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
737 if (!(ka->sa.sa_flags & SA_NODEFER))
738 sigaddset(&current->blocked,sig);
739 recalc_sigpending();
740 spin_unlock_irq(&current->sighand->siglock);
741
742 return ret;
743}
744
745void do_signal32(struct pt_regs *regs)
746{
747 struct k_sigaction ka;
748 sigset_t *oldset;
749 siginfo_t info;
750 int signr;
751
752 /*
753 * We want the common case to go fast, which is why we may in certain
754 * cases get here from kernel mode. Just return without doing anything
755 * if so.
756 */
757 if (!user_mode(regs))
758 return;
759
760 if (test_thread_flag(TIF_RESTORE_SIGMASK))
761 oldset = &current->saved_sigmask;
762 else
763 oldset = &current->blocked;
764
765 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
766 if (signr > 0) {
767 /* Whee! Actually deliver the signal. */
768 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
769 /*
770 * A signal was successfully delivered; the saved
771 * sigmask will have been stored in the signal frame,
772 * and will be restored by sigreturn, so we can simply
773 * clear the TIF_RESTORE_SIGMASK flag.
774 */
775 if (test_thread_flag(TIF_RESTORE_SIGMASK))
776 clear_thread_flag(TIF_RESTORE_SIGMASK);
777 }
778
779 return;
780 }
781
782 /*
783 * Who's code doesn't conform to the restartable syscall convention
784 * dies here!!! The li instruction, a single machine instruction,
785 * must directly be followed by the syscall instruction.
786 */
787 if (regs->regs[0]) {
788 if (regs->regs[2] == ERESTARTNOHAND ||
789 regs->regs[2] == ERESTARTSYS ||
790 regs->regs[2] == ERESTARTNOINTR) {
791 regs->regs[7] = regs->regs[26];
792 regs->cp0_epc -= 8;
793 }
794 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
795 regs->regs[2] = __NR_O32_restart_syscall;
796 regs->regs[7] = regs->regs[26];
797 regs->cp0_epc -= 4;
798 }
799 regs->regs[0] = 0; /* Don't deal with this again. */
800 }
801
802 /*
803 * If there's no signal to deliver, we just put the saved sigmask
804 * back
805 */
806 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
807 clear_thread_flag(TIF_RESTORE_SIGMASK);
808 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
809 }
810}
811 715
812asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, 716asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
813 struct sigaction32 __user *oact, 717 struct sigaction32 __user *oact,