aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/signal.c')
-rw-r--r--arch/sparc/kernel/signal.c307
1 files changed, 10 insertions, 297 deletions
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 9994cac95078..1f730619a24a 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -22,7 +22,6 @@
22 22
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/ptrace.h> 24#include <asm/ptrace.h>
25#include <asm/svr4.h>
26#include <asm/pgalloc.h> 25#include <asm/pgalloc.h>
27#include <asm/pgtable.h> 26#include <asm/pgtable.h>
28#include <asm/cacheflush.h> /* flush_sig_insns */ 27#include <asm/cacheflush.h> /* flush_sig_insns */
@@ -454,7 +453,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
454 break; 453 break;
455 case SIGSYS: 454 case SIGSYS:
456 if (info->si_code == (__SI_FAULT|0x100)) { 455 if (info->si_code == (__SI_FAULT|0x100)) {
457 /* See sys_sunos.c */
458 sig_code = info->si_trapno; 456 sig_code = info->si_trapno;
459 break; 457 break;
460 } 458 }
@@ -676,291 +674,17 @@ sigsegv:
676 force_sigsegv(signo, current); 674 force_sigsegv(signo, current);
677} 675}
678 676
679/* Setup a Solaris stack frame */
680static inline void
681setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
682 struct pt_regs *regs, int signr, sigset_t *oldset)
683{
684 svr4_signal_frame_t __user *sfp;
685 svr4_gregset_t __user *gr;
686 svr4_siginfo_t __user *si;
687 svr4_mcontext_t __user *mc;
688 svr4_gwindows_t __user *gw;
689 svr4_ucontext_t __user *uc;
690 svr4_sigset_t setv;
691 struct thread_info *tp = current_thread_info();
692 int window = 0, err;
693
694 synchronize_user_stack();
695 sfp = (svr4_signal_frame_t __user *)
696 get_sigframe(sa, regs, SVR4_SF_ALIGNED + sizeof(struct reg_window));
697
698 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
699 goto sigill_and_return;
700
701 /* Start with a clean frame pointer and fill it */
702 err = __clear_user(sfp, sizeof(*sfp));
703
704 /* Setup convenience variables */
705 si = &sfp->si;
706 uc = &sfp->uc;
707 gw = &sfp->gw;
708 mc = &uc->mcontext;
709 gr = &mc->greg;
710
711 /* FIXME: where am I supposed to put this?
712 * sc->sigc_onstack = old_status;
713 * anyways, it does not look like it is used for anything at all.
714 */
715 setv.sigbits[0] = oldset->sig[0];
716 setv.sigbits[1] = oldset->sig[1];
717 if (_NSIG_WORDS >= 4) {
718 setv.sigbits[2] = oldset->sig[2];
719 setv.sigbits[3] = oldset->sig[3];
720 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
721 } else
722 err |= __copy_to_user(&uc->sigmask, &setv,
723 2 * sizeof(unsigned int));
724
725 /* Store registers */
726 err |= __put_user(regs->pc, &((*gr)[SVR4_PC]));
727 err |= __put_user(regs->npc, &((*gr)[SVR4_NPC]));
728 err |= __put_user(regs->psr, &((*gr)[SVR4_PSR]));
729 err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
730
731 /* Copy g[1..7] and o[0..7] registers */
732 err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs[UREG_G1],
733 sizeof(long) * 7);
734 err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs[UREG_I0],
735 sizeof(long) * 8);
736
737 /* Setup sigaltstack */
738 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
739 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
740 err |= __put_user(current->sas_ss_size, &uc->stack.size);
741
742 /* Save the currently window file: */
743
744 /* 1. Link sfp->uc->gwins to our windows */
745 err |= __put_user(gw, &mc->gwin);
746
747 /* 2. Number of windows to restore at setcontext(): */
748 err |= __put_user(tp->w_saved, &gw->count);
749
750 /* 3. Save each valid window
751 * Currently, it makes a copy of the windows from the kernel copy.
752 * David's code for SunOS, makes the copy but keeps the pointer to
753 * the kernel. My version makes the pointer point to a userland
754 * copy of those. Mhm, I wonder if I shouldn't just ignore those
755 * on setcontext and use those that are on the kernel, the signal
756 * handler should not be modyfing those, mhm.
757 *
758 * These windows are just used in case synchronize_user_stack failed
759 * to flush the user windows.
760 */
761 for (window = 0; window < tp->w_saved; window++) {
762 err |= __put_user((int __user *) &(gw->win[window]), &gw->winptr[window]);
763 err |= __copy_to_user(&gw->win[window],
764 &tp->reg_window[window],
765 sizeof(svr4_rwindow_t));
766 err |= __put_user(0, gw->winptr[window]);
767 }
768
769 /* 4. We just pay attention to the gw->count field on setcontext */
770 tp->w_saved = 0; /* So process is allowed to execute. */
771
772 /* Setup the signal information. Solaris expects a bunch of
773 * information to be passed to the signal handler, we don't provide
774 * that much currently, should use siginfo.
775 */
776 err |= __put_user(signr, &si->siginfo.signo);
777 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
778 if (err)
779 goto sigsegv;
780
781 regs->u_regs[UREG_FP] = (unsigned long) sfp;
782 regs->pc = (unsigned long) sa->sa_handler;
783 regs->npc = (regs->pc + 4);
784
785 /* Arguments passed to signal handler */
786 if (regs->u_regs[14]){
787 struct reg_window __user *rw = (struct reg_window __user *)
788 regs->u_regs[14];
789
790 err |= __put_user(signr, &rw->ins[0]);
791 err |= __put_user(si, &rw->ins[1]);
792 err |= __put_user(uc, &rw->ins[2]);
793 err |= __put_user(sfp, &rw->ins[6]); /* frame pointer */
794 if (err)
795 goto sigsegv;
796
797 regs->u_regs[UREG_I0] = signr;
798 regs->u_regs[UREG_I1] = (unsigned long) si;
799 regs->u_regs[UREG_I2] = (unsigned long) uc;
800 }
801 return;
802
803sigill_and_return:
804 do_exit(SIGILL);
805sigsegv:
806 force_sigsegv(signr, current);
807}
808
809asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
810{
811 svr4_gregset_t __user *gr;
812 svr4_mcontext_t __user *mc;
813 svr4_sigset_t setv;
814 int err = 0;
815
816 synchronize_user_stack();
817
818 if (current_thread_info()->w_saved)
819 return -EFAULT;
820
821 err = clear_user(uc, sizeof(*uc));
822 if (err)
823 return -EFAULT;
824
825 /* Setup convenience variables */
826 mc = &uc->mcontext;
827 gr = &mc->greg;
828
829 setv.sigbits[0] = current->blocked.sig[0];
830 setv.sigbits[1] = current->blocked.sig[1];
831 if (_NSIG_WORDS >= 4) {
832 setv.sigbits[2] = current->blocked.sig[2];
833 setv.sigbits[3] = current->blocked.sig[3];
834 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
835 } else
836 err |= __copy_to_user(&uc->sigmask, &setv,
837 2 * sizeof(unsigned int));
838
839 /* Store registers */
840 err |= __put_user(regs->pc, &uc->mcontext.greg[SVR4_PC]);
841 err |= __put_user(regs->npc, &uc->mcontext.greg[SVR4_NPC]);
842 err |= __put_user(regs->psr, &uc->mcontext.greg[SVR4_PSR]);
843 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
844
845 /* Copy g[1..7] and o[0..7] registers */
846 err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs[UREG_G1],
847 sizeof(uint) * 7);
848 err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs[UREG_I0],
849 sizeof(uint) * 8);
850
851 /* Setup sigaltstack */
852 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
853 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
854 err |= __put_user(current->sas_ss_size, &uc->stack.size);
855
856 /* The register file is not saved
857 * we have already stuffed all of it with sync_user_stack
858 */
859 return (err ? -EFAULT : 0);
860}
861
862/* Set the context for a svr4 application, this is Solaris way to sigreturn */
863asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
864{
865 svr4_gregset_t __user *gr;
866 unsigned long pc, npc, psr;
867 mm_segment_t old_fs;
868 sigset_t set;
869 svr4_sigset_t setv;
870 int err;
871 stack_t st;
872
873 /* Fixme: restore windows, or is this already taken care of in
874 * svr4_setup_frame when sync_user_windows is done?
875 */
876 flush_user_windows();
877
878 if (current_thread_info()->w_saved)
879 goto sigsegv_and_return;
880
881 if (((unsigned long) c) & 3)
882 goto sigsegv_and_return;
883
884 if (!__access_ok((unsigned long)c, sizeof(*c)))
885 goto sigsegv_and_return;
886
887 /* Check for valid PC and nPC */
888 gr = &c->mcontext.greg;
889 err = __get_user(pc, &((*gr)[SVR4_PC]));
890 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
891
892 if ((pc | npc) & 3)
893 goto sigsegv_and_return;
894
895 /* Retrieve information from passed ucontext */
896 /* note that nPC is ored a 1, this is used to inform entry.S */
897 /* that we don't want it to mess with our PC and nPC */
898
899 /* This is pretty much atomic, no amount locking would prevent
900 * the races which exist anyways.
901 */
902 err |= __copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
903
904 err |= __get_user(st.ss_sp, &c->stack.sp);
905 err |= __get_user(st.ss_flags, &c->stack.flags);
906 err |= __get_user(st.ss_size, &c->stack.size);
907
908 if (err)
909 goto sigsegv_and_return;
910
911 /* It is more difficult to avoid calling this function than to
912 call it and ignore errors. */
913 old_fs = get_fs();
914 set_fs(KERNEL_DS);
915 do_sigaltstack((const stack_t __user *) &st, NULL,
916 regs->u_regs[UREG_I6]);
917 set_fs(old_fs);
918
919 set.sig[0] = setv.sigbits[0];
920 set.sig[1] = setv.sigbits[1];
921 if (_NSIG_WORDS >= 4) {
922 set.sig[2] = setv.sigbits[2];
923 set.sig[3] = setv.sigbits[3];
924 }
925 sigdelsetmask(&set, ~_BLOCKABLE);
926 spin_lock_irq(&current->sighand->siglock);
927 current->blocked = set;
928 recalc_sigpending();
929 spin_unlock_irq(&current->sighand->siglock);
930 regs->pc = pc;
931 regs->npc = npc | 1;
932 err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
933 err |= __get_user(psr, &((*gr)[SVR4_PSR]));
934 regs->psr &= ~(PSR_ICC);
935 regs->psr |= (psr & PSR_ICC);
936
937 /* Restore g[1..7] and o[0..7] registers */
938 err |= __copy_from_user(&regs->u_regs[UREG_G1], &(*gr)[SVR4_G1],
939 sizeof(long) * 7);
940 err |= __copy_from_user(&regs->u_regs[UREG_I0], &(*gr)[SVR4_O0],
941 sizeof(long) * 8);
942 return (err ? -EFAULT : 0);
943
944sigsegv_and_return:
945 force_sig(SIGSEGV, current);
946 return -EFAULT;
947}
948
949static inline void 677static inline void
950handle_signal(unsigned long signr, struct k_sigaction *ka, 678handle_signal(unsigned long signr, struct k_sigaction *ka,
951 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, 679 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
952 int svr4_signal)
953{ 680{
954 if (svr4_signal) 681 if (ka->sa.sa_flags & SA_SIGINFO)
955 setup_svr4_frame(&ka->sa, regs->pc, regs->npc, regs, signr, oldset); 682 new_setup_rt_frame(ka, regs, signr, oldset, info);
956 else { 683 else if (current->thread.new_signal)
957 if (ka->sa.sa_flags & SA_SIGINFO) 684 new_setup_frame(ka, regs, signr, oldset);
958 new_setup_rt_frame(ka, regs, signr, oldset, info); 685 else
959 else if (current->thread.new_signal) 686 setup_frame(&ka->sa, regs, signr, oldset, info);
960 new_setup_frame(ka, regs, signr, oldset); 687
961 else
962 setup_frame(&ka->sa, regs, signr, oldset, info);
963 }
964 spin_lock_irq(&current->sighand->siglock); 688 spin_lock_irq(&current->sighand->siglock);
965 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 689 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
966 if (!(ka->sa.sa_flags & SA_NOMASK)) 690 if (!(ka->sa.sa_flags & SA_NOMASK))
@@ -1002,17 +726,6 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
1002 int signr; 726 int signr;
1003 sigset_t *oldset; 727 sigset_t *oldset;
1004 728
1005 /*
1006 * XXX Disable svr4 signal handling until solaris emulation works.
1007 * It is buggy - Anton
1008 */
1009#define SVR4_SIGNAL_BROKEN 1
1010#ifdef SVR4_SIGNAL_BROKEN
1011 int svr4_signal = 0;
1012#else
1013 int svr4_signal = current->personality == PER_SVR4;
1014#endif
1015
1016 cookie.restart_syscall = restart_syscall; 729 cookie.restart_syscall = restart_syscall;
1017 cookie.orig_i0 = orig_i0; 730 cookie.orig_i0 = orig_i0;
1018 731
@@ -1025,8 +738,8 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
1025 if (signr > 0) { 738 if (signr > 0) {
1026 if (cookie.restart_syscall) 739 if (cookie.restart_syscall)
1027 syscall_restart(cookie.orig_i0, regs, &ka.sa); 740 syscall_restart(cookie.orig_i0, regs, &ka.sa);
1028 handle_signal(signr, &ka, &info, oldset, 741 handle_signal(signr, &ka, &info, oldset, regs);
1029 regs, svr4_signal); 742
1030 /* a signal was successfully delivered; the saved 743 /* a signal was successfully delivered; the saved
1031 * sigmask will have been stored in the signal frame, 744 * sigmask will have been stored in the signal frame,
1032 * and will be restored by sigreturn, so we can simply 745 * and will be restored by sigreturn, so we can simply