diff options
Diffstat (limited to 'arch/alpha/kernel/signal.c')
| -rw-r--r-- | arch/alpha/kernel/signal.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index a8c97d42ec8e..32575f85507d 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
| @@ -298,8 +298,9 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) | |||
| 298 | 298 | ||
| 299 | static long | 299 | static long |
| 300 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | 300 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, |
| 301 | struct switch_stack *sw, unsigned long mask, unsigned long sp) | 301 | unsigned long mask, unsigned long sp) |
| 302 | { | 302 | { |
| 303 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | ||
| 303 | long i, err = 0; | 304 | long i, err = 0; |
| 304 | 305 | ||
| 305 | err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); | 306 | err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); |
| @@ -354,7 +355,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
| 354 | 355 | ||
| 355 | static int | 356 | static int |
| 356 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 357 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, |
| 357 | struct pt_regs *regs, struct switch_stack * sw) | 358 | struct pt_regs *regs) |
| 358 | { | 359 | { |
| 359 | unsigned long oldsp, r26, err = 0; | 360 | unsigned long oldsp, r26, err = 0; |
| 360 | struct sigframe __user *frame; | 361 | struct sigframe __user *frame; |
| @@ -364,7 +365,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
| 364 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 365 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
| 365 | return -EFAULT; | 366 | return -EFAULT; |
| 366 | 367 | ||
| 367 | err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); | 368 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0], oldsp); |
| 368 | if (err) | 369 | if (err) |
| 369 | return -EFAULT; | 370 | return -EFAULT; |
| 370 | 371 | ||
| @@ -401,7 +402,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
| 401 | 402 | ||
| 402 | static int | 403 | static int |
| 403 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 404 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
| 404 | sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) | 405 | sigset_t *set, struct pt_regs *regs) |
| 405 | { | 406 | { |
| 406 | unsigned long oldsp, r26, err = 0; | 407 | unsigned long oldsp, r26, err = 0; |
| 407 | struct rt_sigframe __user *frame; | 408 | struct rt_sigframe __user *frame; |
| @@ -420,7 +421,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 420 | err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); | 421 | err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); |
| 421 | err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags); | 422 | err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags); |
| 422 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | 423 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); |
| 423 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, | 424 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, |
| 424 | set->sig[0], oldsp); | 425 | set->sig[0], oldsp); |
| 425 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 426 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
| 426 | if (err) | 427 | if (err) |
| @@ -464,15 +465,15 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 464 | */ | 465 | */ |
| 465 | static inline void | 466 | static inline void |
| 466 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | 467 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, |
| 467 | struct pt_regs * regs, struct switch_stack *sw) | 468 | struct pt_regs * regs) |
| 468 | { | 469 | { |
| 469 | sigset_t *oldset = sigmask_to_save(); | 470 | sigset_t *oldset = sigmask_to_save(); |
| 470 | int ret; | 471 | int ret; |
| 471 | 472 | ||
| 472 | if (ka->sa.sa_flags & SA_SIGINFO) | 473 | if (ka->sa.sa_flags & SA_SIGINFO) |
| 473 | ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); | 474 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
| 474 | else | 475 | else |
| 475 | ret = setup_frame(sig, ka, oldset, regs, sw); | 476 | ret = setup_frame(sig, ka, oldset, regs); |
| 476 | 477 | ||
| 477 | if (ret) { | 478 | if (ret) { |
| 478 | force_sigsegv(sig, current); | 479 | force_sigsegv(sig, current); |
| @@ -519,8 +520,7 @@ syscall_restart(unsigned long r0, unsigned long r19, | |||
| 519 | * all (if we get here from anything but a syscall return, it will be 0) | 520 | * all (if we get here from anything but a syscall return, it will be 0) |
| 520 | */ | 521 | */ |
| 521 | static void | 522 | static void |
| 522 | do_signal(struct pt_regs * regs, struct switch_stack * sw, | 523 | do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19) |
| 523 | unsigned long r0, unsigned long r19) | ||
| 524 | { | 524 | { |
| 525 | siginfo_t info; | 525 | siginfo_t info; |
| 526 | int signr; | 526 | int signr; |
| @@ -537,7 +537,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw, | |||
| 537 | /* Whee! Actually deliver the signal. */ | 537 | /* Whee! Actually deliver the signal. */ |
| 538 | if (r0) | 538 | if (r0) |
| 539 | syscall_restart(r0, r19, regs, &ka); | 539 | syscall_restart(r0, r19, regs, &ka); |
| 540 | handle_signal(signr, &ka, &info, regs, sw); | 540 | handle_signal(signr, &ka, &info, regs); |
| 541 | if (single_stepping) | 541 | if (single_stepping) |
| 542 | ptrace_set_bpt(current); /* re-set bpt */ | 542 | ptrace_set_bpt(current); /* re-set bpt */ |
| 543 | return; | 543 | return; |
| @@ -568,15 +568,23 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw, | |||
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | void | 570 | void |
| 571 | do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, | 571 | do_work_pending(struct pt_regs *regs, unsigned long thread_flags, |
| 572 | unsigned long thread_info_flags, | ||
| 573 | unsigned long r0, unsigned long r19) | 572 | unsigned long r0, unsigned long r19) |
| 574 | { | 573 | { |
| 575 | if (thread_info_flags & _TIF_SIGPENDING) | 574 | do { |
| 576 | do_signal(regs, sw, r0, r19); | 575 | if (thread_flags & _TIF_NEED_RESCHED) { |
| 577 | 576 | schedule(); | |
| 578 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 577 | } else { |
| 579 | clear_thread_flag(TIF_NOTIFY_RESUME); | 578 | local_irq_enable(); |
| 580 | tracehook_notify_resume(regs); | 579 | if (thread_flags & _TIF_SIGPENDING) { |
| 581 | } | 580 | do_signal(regs, r0, r19); |
| 581 | r0 = 0; | ||
| 582 | } else { | ||
| 583 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 584 | tracehook_notify_resume(regs); | ||
| 585 | } | ||
| 586 | } | ||
| 587 | local_irq_disable(); | ||
| 588 | thread_flags = current_thread_info()->flags; | ||
| 589 | } while (thread_flags & _TIF_WORK_MASK); | ||
| 582 | } | 590 | } |
