aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/signal_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/signal_32.c')
-rw-r--r--arch/sh/kernel/signal_32.c79
1 files changed, 32 insertions, 47 deletions
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 594cd371aa28..2f002b24fb92 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -262,17 +262,17 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
262extern void __kernel_sigreturn(void); 262extern void __kernel_sigreturn(void);
263extern void __kernel_rt_sigreturn(void); 263extern void __kernel_rt_sigreturn(void);
264 264
265static int setup_frame(int sig, struct k_sigaction *ka, 265static int setup_frame(struct ksignal *ksig, sigset_t *set,
266 sigset_t *set, struct pt_regs *regs) 266 struct pt_regs *regs)
267{ 267{
268 struct sigframe __user *frame; 268 struct sigframe __user *frame;
269 int err = 0; 269 int err = 0, sig = ksig->sig;
270 int signal; 270 int signal;
271 271
272 frame = get_sigframe(ka, regs->regs[15], sizeof(*frame)); 272 frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
273 273
274 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 274 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
275 goto give_sigsegv; 275 return -EFAULT;
276 276
277 signal = current_thread_info()->exec_domain 277 signal = current_thread_info()->exec_domain
278 && current_thread_info()->exec_domain->signal_invmap 278 && current_thread_info()->exec_domain->signal_invmap
@@ -288,8 +288,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,
288 288
289 /* Set up to return from userspace. If provided, use a stub 289 /* Set up to return from userspace. If provided, use a stub
290 already in userspace. */ 290 already in userspace. */
291 if (ka->sa.sa_flags & SA_RESTORER) { 291 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
292 regs->pr = (unsigned long) ka->sa.sa_restorer; 292 regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
293#ifdef CONFIG_VSYSCALL 293#ifdef CONFIG_VSYSCALL
294 } else if (likely(current->mm->context.vdso)) { 294 } else if (likely(current->mm->context.vdso)) {
295 regs->pr = VDSO_SYM(&__kernel_sigreturn); 295 regs->pr = VDSO_SYM(&__kernel_sigreturn);
@@ -309,7 +309,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
309 } 309 }
310 310
311 if (err) 311 if (err)
312 goto give_sigsegv; 312 return -EFAULT;
313 313
314 /* Set up registers for signal handler */ 314 /* Set up registers for signal handler */
315 regs->regs[15] = (unsigned long) frame; 315 regs->regs[15] = (unsigned long) frame;
@@ -319,15 +319,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
319 319
320 if (current->personality & FDPIC_FUNCPTRS) { 320 if (current->personality & FDPIC_FUNCPTRS) {
321 struct fdpic_func_descriptor __user *funcptr = 321 struct fdpic_func_descriptor __user *funcptr =
322 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; 322 (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
323 323
324 err |= __get_user(regs->pc, &funcptr->text); 324 err |= __get_user(regs->pc, &funcptr->text);
325 err |= __get_user(regs->regs[12], &funcptr->GOT); 325 err |= __get_user(regs->regs[12], &funcptr->GOT);
326 } else 326 } else
327 regs->pc = (unsigned long)ka->sa.sa_handler; 327 regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
328 328
329 if (err) 329 if (err)
330 goto give_sigsegv; 330 return -EFAULT;
331 331
332 set_fs(USER_DS); 332 set_fs(USER_DS);
333 333
@@ -335,23 +335,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
335 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); 335 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
336 336
337 return 0; 337 return 0;
338
339give_sigsegv:
340 force_sigsegv(sig, current);
341 return -EFAULT;
342} 338}
343 339
344static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 340static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
345 sigset_t *set, struct pt_regs *regs) 341 struct pt_regs *regs)
346{ 342{
347 struct rt_sigframe __user *frame; 343 struct rt_sigframe __user *frame;
348 int err = 0; 344 int err = 0, sig = ksig->sig;
349 int signal; 345 int signal;
350 346
351 frame = get_sigframe(ka, regs->regs[15], sizeof(*frame)); 347 frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
352 348
353 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 349 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
354 goto give_sigsegv; 350 return -EFAULT;
355 351
356 signal = current_thread_info()->exec_domain 352 signal = current_thread_info()->exec_domain
357 && current_thread_info()->exec_domain->signal_invmap 353 && current_thread_info()->exec_domain->signal_invmap
@@ -359,7 +355,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
359 ? current_thread_info()->exec_domain->signal_invmap[sig] 355 ? current_thread_info()->exec_domain->signal_invmap[sig]
360 : sig; 356 : sig;
361 357
362 err |= copy_siginfo_to_user(&frame->info, info); 358 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
363 359
364 /* Create the ucontext. */ 360 /* Create the ucontext. */
365 err |= __put_user(0, &frame->uc.uc_flags); 361 err |= __put_user(0, &frame->uc.uc_flags);
@@ -371,8 +367,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
371 367
372 /* Set up to return from userspace. If provided, use a stub 368 /* Set up to return from userspace. If provided, use a stub
373 already in userspace. */ 369 already in userspace. */
374 if (ka->sa.sa_flags & SA_RESTORER) { 370 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
375 regs->pr = (unsigned long) ka->sa.sa_restorer; 371 regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
376#ifdef CONFIG_VSYSCALL 372#ifdef CONFIG_VSYSCALL
377 } else if (likely(current->mm->context.vdso)) { 373 } else if (likely(current->mm->context.vdso)) {
378 regs->pr = VDSO_SYM(&__kernel_rt_sigreturn); 374 regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
@@ -392,7 +388,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
392 } 388 }
393 389
394 if (err) 390 if (err)
395 goto give_sigsegv; 391 return -EFAULT;
396 392
397 /* Set up registers for signal handler */ 393 /* Set up registers for signal handler */
398 regs->regs[15] = (unsigned long) frame; 394 regs->regs[15] = (unsigned long) frame;
@@ -402,15 +398,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
402 398
403 if (current->personality & FDPIC_FUNCPTRS) { 399 if (current->personality & FDPIC_FUNCPTRS) {
404 struct fdpic_func_descriptor __user *funcptr = 400 struct fdpic_func_descriptor __user *funcptr =
405 (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; 401 (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
406 402
407 err |= __get_user(regs->pc, &funcptr->text); 403 err |= __get_user(regs->pc, &funcptr->text);
408 err |= __get_user(regs->regs[12], &funcptr->GOT); 404 err |= __get_user(regs->regs[12], &funcptr->GOT);
409 } else 405 } else
410 regs->pc = (unsigned long)ka->sa.sa_handler; 406 regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
411 407
412 if (err) 408 if (err)
413 goto give_sigsegv; 409 return -EFAULT;
414 410
415 set_fs(USER_DS); 411 set_fs(USER_DS);
416 412
@@ -418,10 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
418 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); 414 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
419 415
420 return 0; 416 return 0;
421
422give_sigsegv:
423 force_sigsegv(sig, current);
424 return -EFAULT;
425} 417}
426 418
427static inline void 419static inline void
@@ -455,22 +447,18 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
455 * OK, we're invoking a handler 447 * OK, we're invoking a handler
456 */ 448 */
457static void 449static void
458handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 450handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0)
459 struct pt_regs *regs, unsigned int save_r0)
460{ 451{
461 sigset_t *oldset = sigmask_to_save(); 452 sigset_t *oldset = sigmask_to_save();
462 int ret; 453 int ret;
463 454
464 /* Set up the stack frame */ 455 /* Set up the stack frame */
465 if (ka->sa.sa_flags & SA_SIGINFO) 456 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
466 ret = setup_rt_frame(sig, ka, info, oldset, regs); 457 ret = setup_rt_frame(ksig, oldset, regs);
467 else 458 else
468 ret = setup_frame(sig, ka, oldset, regs); 459 ret = setup_frame(ksig, oldset, regs);
469 460
470 if (ret) 461 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
471 return;
472 signal_delivered(sig, info, ka, regs,
473 test_thread_flag(TIF_SINGLESTEP));
474} 462}
475 463
476/* 464/*
@@ -484,9 +472,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
484 */ 472 */
485static void do_signal(struct pt_regs *regs, unsigned int save_r0) 473static void do_signal(struct pt_regs *regs, unsigned int save_r0)
486{ 474{
487 siginfo_t info; 475 struct ksignal ksig;
488 int signr;
489 struct k_sigaction ka;
490 476
491 /* 477 /*
492 * We want the common case to go fast, which 478 * We want the common case to go fast, which
@@ -497,12 +483,11 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
497 if (!user_mode(regs)) 483 if (!user_mode(regs))
498 return; 484 return;
499 485
500 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 486 if (get_signal(&ksig)) {
501 if (signr > 0) { 487 handle_syscall_restart(save_r0, regs, &ksig.ka.sa);
502 handle_syscall_restart(save_r0, regs, &ka.sa);
503 488
504 /* Whee! Actually deliver the signal. */ 489 /* Whee! Actually deliver the signal. */
505 handle_signal(signr, &ka, &info, regs, save_r0); 490 handle_signal(&ksig, regs, save_r0);
506 return; 491 return;
507 } 492 }
508 493