aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/signal_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/signal_64.c')
-rw-r--r--arch/sh/kernel/signal_64.c82
1 files changed, 32 insertions, 50 deletions
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 23d4c71c91af..897abe7b871e 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -41,8 +41,7 @@
41#define DEBUG_SIG 0 41#define DEBUG_SIG 0
42 42
43static void 43static void
44handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 44handle_signal(struct ksignal *ksig, struct pt_regs *regs);
45 struct pt_regs * regs);
46 45
47static inline void 46static inline void
48handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) 47handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
@@ -82,9 +81,7 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
82 */ 81 */
83static void do_signal(struct pt_regs *regs) 82static void do_signal(struct pt_regs *regs)
84{ 83{
85 siginfo_t info; 84 struct ksignal ksig;
86 int signr;
87 struct k_sigaction ka;
88 85
89 /* 86 /*
90 * We want the common case to go fast, which 87 * We want the common case to go fast, which
@@ -95,12 +92,11 @@ static void do_signal(struct pt_regs *regs)
95 if (!user_mode(regs)) 92 if (!user_mode(regs))
96 return; 93 return;
97 94
98 signr = get_signal_to_deliver(&info, &ka, regs, 0); 95 if (get_signal(&ksig)) {
99 if (signr > 0) { 96 handle_syscall_restart(regs, &ksig.ka.sa);
100 handle_syscall_restart(regs, &ka.sa);
101 97
102 /* Whee! Actually deliver the signal. */ 98 /* Whee! Actually deliver the signal. */
103 handle_signal(signr, &info, &ka, regs); 99 handle_signal(&ksig, regs);
104 return; 100 return;
105 } 101 }
106 102
@@ -378,17 +374,16 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
378void sa_default_restorer(void); /* See comments below */ 374void sa_default_restorer(void); /* See comments below */
379void sa_default_rt_restorer(void); /* See comments below */ 375void sa_default_rt_restorer(void); /* See comments below */
380 376
381static int setup_frame(int sig, struct k_sigaction *ka, 377static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
382 sigset_t *set, struct pt_regs *regs)
383{ 378{
384 struct sigframe __user *frame; 379 struct sigframe __user *frame;
385 int err = 0; 380 int err = 0, sig = ksig->sig;
386 int signal; 381 int signal;
387 382
388 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame)); 383 frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
389 384
390 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 385 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
391 goto give_sigsegv; 386 return -EFAULT;
392 387
393 signal = current_thread_info()->exec_domain 388 signal = current_thread_info()->exec_domain
394 && current_thread_info()->exec_domain->signal_invmap 389 && current_thread_info()->exec_domain->signal_invmap
@@ -400,7 +395,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
400 395
401 /* Give up earlier as i386, in case */ 396 /* Give up earlier as i386, in case */
402 if (err) 397 if (err)
403 goto give_sigsegv; 398 return -EFAULT;
404 399
405 if (_NSIG_WORDS > 1) { 400 if (_NSIG_WORDS > 1) {
406 err |= __copy_to_user(frame->extramask, &set->sig[1], 401 err |= __copy_to_user(frame->extramask, &set->sig[1],
@@ -408,16 +403,16 @@ static int setup_frame(int sig, struct k_sigaction *ka,
408 403
409 /* Give up earlier as i386, in case */ 404 /* Give up earlier as i386, in case */
410 if (err) 405 if (err)
411 goto give_sigsegv; 406 return -EFAULT;
412 407
413 /* Set up to return from userspace. If provided, use a stub 408 /* Set up to return from userspace. If provided, use a stub
414 already in userspace. */ 409 already in userspace. */
415 if (ka->sa.sa_flags & SA_RESTORER) { 410 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
416 /* 411 /*
417 * On SH5 all edited pointers are subject to NEFF 412 * On SH5 all edited pointers are subject to NEFF
418 */ 413 */
419 DEREF_REG_PR = neff_sign_extend((unsigned long) 414 DEREF_REG_PR = neff_sign_extend((unsigned long)
420 ka->sa.sa_restorer | 0x1); 415 ksig->ka->sa.sa_restorer | 0x1);
421 } else { 416 } else {
422 /* 417 /*
423 * Different approach on SH5. 418 * Different approach on SH5.
@@ -435,7 +430,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
435 430
436 if (__copy_to_user(frame->retcode, 431 if (__copy_to_user(frame->retcode,
437 (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0) 432 (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
438 goto give_sigsegv; 433 return -EFAULT;
439 434
440 /* Cohere the trampoline with the I-cache. */ 435 /* Cohere the trampoline with the I-cache. */
441 flush_cache_sigtramp(DEREF_REG_PR-1); 436 flush_cache_sigtramp(DEREF_REG_PR-1);
@@ -460,7 +455,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
460 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc; 455 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
461 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc; 456 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
462 457
463 regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler); 458 regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
464 459
465 set_fs(USER_DS); 460 set_fs(USER_DS);
466 461
@@ -471,23 +466,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
471 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff); 466 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
472 467
473 return 0; 468 return 0;
474
475give_sigsegv:
476 force_sigsegv(sig, current);
477 return -EFAULT;
478} 469}
479 470
480static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 471static int setup_rt_frame(struct ksignal *kig, sigset_t *set,
481 sigset_t *set, struct pt_regs *regs) 472 struct pt_regs *regs)
482{ 473{
483 struct rt_sigframe __user *frame; 474 struct rt_sigframe __user *frame;
484 int err = 0; 475 int err = 0, sig = ksig->sig;
485 int signal; 476 int signal;
486 477
487 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame)); 478 frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
488 479
489 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 480 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
490 goto give_sigsegv; 481 return -EFAULT;
491 482
492 signal = current_thread_info()->exec_domain 483 signal = current_thread_info()->exec_domain
493 && current_thread_info()->exec_domain->signal_invmap 484 && current_thread_info()->exec_domain->signal_invmap
@@ -497,11 +488,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
497 488
498 err |= __put_user(&frame->info, &frame->pinfo); 489 err |= __put_user(&frame->info, &frame->pinfo);
499 err |= __put_user(&frame->uc, &frame->puc); 490 err |= __put_user(&frame->uc, &frame->puc);
500 err |= copy_siginfo_to_user(&frame->info, info); 491 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
501 492
502 /* Give up earlier as i386, in case */ 493 /* Give up earlier as i386, in case */
503 if (err) 494 if (err)
504 goto give_sigsegv; 495 return -EFAULT;
505 496
506 /* Create the ucontext. */ 497 /* Create the ucontext. */
507 err |= __put_user(0, &frame->uc.uc_flags); 498 err |= __put_user(0, &frame->uc.uc_flags);
@@ -513,16 +504,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
513 504
514 /* Give up earlier as i386, in case */ 505 /* Give up earlier as i386, in case */
515 if (err) 506 if (err)
516 goto give_sigsegv; 507 return -EFAULT;
517 508
518 /* Set up to return from userspace. If provided, use a stub 509 /* Set up to return from userspace. If provided, use a stub
519 already in userspace. */ 510 already in userspace. */
520 if (ka->sa.sa_flags & SA_RESTORER) { 511 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
521 /* 512 /*
522 * On SH5 all edited pointers are subject to NEFF 513 * On SH5 all edited pointers are subject to NEFF
523 */ 514 */
524 DEREF_REG_PR = neff_sign_extend((unsigned long) 515 DEREF_REG_PR = neff_sign_extend((unsigned long)
525 ka->sa.sa_restorer | 0x1); 516 ksig->ka.sa.sa_restorer | 0x1);
526 } else { 517 } else {
527 /* 518 /*
528 * Different approach on SH5. 519 * Different approach on SH5.
@@ -540,7 +531,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
540 531
541 if (__copy_to_user(frame->retcode, 532 if (__copy_to_user(frame->retcode,
542 (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0) 533 (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
543 goto give_sigsegv; 534 return -EFAULT;
544 535
545 /* Cohere the trampoline with the I-cache. */ 536 /* Cohere the trampoline with the I-cache. */
546 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15); 537 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
@@ -554,7 +545,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
554 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */ 545 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
555 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info; 546 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
556 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext; 547 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
557 regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler); 548 regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
558 549
559 set_fs(USER_DS); 550 set_fs(USER_DS);
560 551
@@ -564,33 +555,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
564 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff); 555 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
565 556
566 return 0; 557 return 0;
567
568give_sigsegv:
569 force_sigsegv(sig, current);
570 return -EFAULT;
571} 558}
572 559
573/* 560/*
574 * OK, we're invoking a handler 561 * OK, we're invoking a handler
575 */ 562 */
576static void 563static void
577handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 564handle_signal(struct ksignal *ksig, struct pt_regs *regs)
578 struct pt_regs * regs)
579{ 565{
580 sigset_t *oldset = sigmask_to_save(); 566 sigset_t *oldset = sigmask_to_save();
581 int ret; 567 int ret;
582 568
583 /* Set up the stack frame */ 569 /* Set up the stack frame */
584 if (ka->sa.sa_flags & SA_SIGINFO) 570 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
585 ret = setup_rt_frame(sig, ka, info, oldset, regs); 571 ret = setup_rt_frame(ksig, oldset, regs);
586 else 572 else
587 ret = setup_frame(sig, ka, oldset, regs); 573 ret = setup_frame(ksig, oldset, regs);
588
589 if (ret)
590 return;
591 574
592 signal_delivered(sig, info, ka, regs, 575 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
593 test_thread_flag(TIF_SINGLESTEP));
594} 576}
595 577
596asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 578asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)