aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal_n32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/signal_n32.c')
-rw-r--r--arch/mips/kernel/signal_n32.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index ec61b2670ba6..3e168c08a3a8 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -48,6 +48,8 @@
48#define __NR_N32_rt_sigreturn 6211 48#define __NR_N32_rt_sigreturn 6211
49#define __NR_N32_restart_syscall 6214 49#define __NR_N32_restart_syscall 6214
50 50
51#define DEBUG_SIG 0
52
51#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 53#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
52 54
53/* IRIX compatible stack_t */ 55/* IRIX compatible stack_t */
@@ -79,16 +81,49 @@ struct rt_sigframe_n32 {
79#endif 81#endif
80}; 82};
81 83
84extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
85
86save_static_function(sysn32_rt_sigsuspend);
87__attribute_used__ noinline static int
88_sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
89{
90 compat_sigset_t __user *unewset, uset;
91 size_t sigsetsize;
92 sigset_t newset;
93
94 /* XXX Don't preclude handling different sized sigset_t's. */
95 sigsetsize = regs.regs[5];
96 if (sigsetsize != sizeof(sigset_t))
97 return -EINVAL;
98
99 unewset = (compat_sigset_t __user *) regs.regs[4];
100 if (copy_from_user(&uset, unewset, sizeof(uset)))
101 return -EFAULT;
102 sigset_from_compat (&newset, &uset);
103 sigdelsetmask(&newset, ~_BLOCKABLE);
104
105 spin_lock_irq(&current->sighand->siglock);
106 current->saved_sigmask = current->blocked;
107 current->blocked = newset;
108 recalc_sigpending();
109 spin_unlock_irq(&current->sighand->siglock);
110
111 current->state = TASK_INTERRUPTIBLE;
112 schedule();
113 set_thread_flag(TIF_RESTORE_SIGMASK);
114 return -ERESTARTNOHAND;
115}
116
82save_static_function(sysn32_rt_sigreturn); 117save_static_function(sysn32_rt_sigreturn);
83__attribute_used__ noinline static void 118__attribute_used__ noinline static void
84_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 119_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
85{ 120{
86 struct rt_sigframe_n32 *frame; 121 struct rt_sigframe_n32 __user *frame;
87 sigset_t set; 122 sigset_t set;
88 stack_t st; 123 stack_t st;
89 s32 sp; 124 s32 sp;
90 125
91 frame = (struct rt_sigframe_n32 *) regs.regs[29]; 126 frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
92 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 127 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
93 goto badframe; 128 goto badframe;
94 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) 129 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -106,7 +141,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
106 /* The ucontext contains a stack32_t, so we must convert! */ 141 /* The ucontext contains a stack32_t, so we must convert! */
107 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) 142 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
108 goto badframe; 143 goto badframe;
109 st.ss_size = (long) sp; 144 st.ss_sp = (void *)(long) sp;
110 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) 145 if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
111 goto badframe; 146 goto badframe;
112 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) 147 if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
@@ -114,7 +149,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
114 149
115 /* It is more difficult to avoid calling this function than to 150 /* It is more difficult to avoid calling this function than to
116 call it and ignore errors. */ 151 call it and ignore errors. */
117 do_sigaltstack(&st, NULL, regs.regs[29]); 152 do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
118 153
119 /* 154 /*
120 * Don't let your children do this ... 155 * Don't let your children do this ...
@@ -133,7 +168,7 @@ badframe:
133int setup_rt_frame_n32(struct k_sigaction * ka, 168int setup_rt_frame_n32(struct k_sigaction * ka,
134 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) 169 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
135{ 170{
136 struct rt_sigframe_n32 *frame; 171 struct rt_sigframe_n32 __user *frame;
137 int err = 0; 172 int err = 0;
138 s32 sp; 173 s32 sp;
139 174
@@ -184,9 +219,9 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
184 current->comm, current->pid, 219 current->comm, current->pid,
185 frame, regs->cp0_epc, regs->regs[31]); 220 frame, regs->cp0_epc, regs->regs[31]);
186#endif 221#endif
187 return 1; 222 return 0;
188 223
189give_sigsegv: 224give_sigsegv:
190 force_sigsegv(signr, current); 225 force_sigsegv(signr, current);
191 return 0; 226 return -EFAULT;
192} 227}