aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/compat_signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/compat_signal.c')
-rw-r--r--arch/tile/kernel/compat_signal.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 19c04b5ce408..8c5abf2e4794 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -190,18 +190,18 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
190 return (void __user *) sp; 190 return (void __user *) sp;
191} 191}
192 192
193int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 193int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
194 sigset_t *set, struct pt_regs *regs) 194 struct pt_regs *regs)
195{ 195{
196 unsigned long restorer; 196 unsigned long restorer;
197 struct compat_rt_sigframe __user *frame; 197 struct compat_rt_sigframe __user *frame;
198 int err = 0; 198 int err = 0, sig = ksig->sig;
199 int usig; 199 int usig;
200 200
201 frame = compat_get_sigframe(ka, regs, sizeof(*frame)); 201 frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
202 202
203 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 203 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
204 goto give_sigsegv; 204 goto err;
205 205
206 usig = current_thread_info()->exec_domain 206 usig = current_thread_info()->exec_domain
207 && current_thread_info()->exec_domain->signal_invmap 207 && current_thread_info()->exec_domain->signal_invmap
@@ -210,12 +210,12 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
210 : sig; 210 : sig;
211 211
212 /* Always write at least the signal number for the stack backtracer. */ 212 /* Always write at least the signal number for the stack backtracer. */
213 if (ka->sa.sa_flags & SA_SIGINFO) { 213 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
214 /* At sigreturn time, restore the callee-save registers too. */ 214 /* At sigreturn time, restore the callee-save registers too. */
215 err |= copy_siginfo_to_user32(&frame->info, info); 215 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
216 regs->flags |= PT_FLAGS_RESTORE_REGS; 216 regs->flags |= PT_FLAGS_RESTORE_REGS;
217 } else { 217 } else {
218 err |= __put_user(info->si_signo, &frame->info.si_signo); 218 err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
219 } 219 }
220 220
221 /* Create the ucontext. */ 221 /* Create the ucontext. */
@@ -226,11 +226,11 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
226 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 226 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
227 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 227 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
228 if (err) 228 if (err)
229 goto give_sigsegv; 229 goto err;
230 230
231 restorer = VDSO_SYM(&__vdso_rt_sigreturn); 231 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
232 if (ka->sa.sa_flags & SA_RESTORER) 232 if (ksig->ka.sa.sa_flags & SA_RESTORER)
233 restorer = ptr_to_compat_reg(ka->sa.sa_restorer); 233 restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
234 234
235 /* 235 /*
236 * Set up registers for signal handler. 236 * Set up registers for signal handler.
@@ -239,7 +239,7 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
239 * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 239 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
240 * since some things rely on this (e.g. glibc's debug/segfault.c). 240 * since some things rely on this (e.g. glibc's debug/segfault.c).
241 */ 241 */
242 regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); 242 regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
243 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 243 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
244 regs->sp = ptr_to_compat_reg(frame); 244 regs->sp = ptr_to_compat_reg(frame);
245 regs->lr = restorer; 245 regs->lr = restorer;
@@ -249,7 +249,8 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
249 regs->flags |= PT_FLAGS_CALLER_SAVES; 249 regs->flags |= PT_FLAGS_CALLER_SAVES;
250 return 0; 250 return 0;
251 251
252give_sigsegv: 252err:
253 signal_fault("bad setup frame", regs, frame, sig); 253 trace_unhandled_signal("bad sigreturn frame", regs,
254 (unsigned long)frame, SIGSEGV);
254 return -EFAULT; 255 return -EFAULT;
255} 256}