diff options
Diffstat (limited to 'arch/tile/kernel/compat_signal.c')
-rw-r--r-- | arch/tile/kernel/compat_signal.c | 29 |
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 | ||
193 | int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 193 | int 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 | ||
252 | give_sigsegv: | 252 | err: |
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 | } |