aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/signal.c')
-rw-r--r--arch/sparc/kernel/signal.c84
1 files changed, 45 insertions, 39 deletions
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 3c312290c3c2..3fd1df9f9ba7 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -145,6 +145,9 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
145 regs->psr = (up_psr & ~(PSR_ICC | PSR_EF)) 145 regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
146 | (regs->psr & (PSR_ICC | PSR_EF)); 146 | (regs->psr & (PSR_ICC | PSR_EF));
147 147
148 /* Prevent syscall restart. */
149 pt_regs_clear_syscall(regs);
150
148 err |= __get_user(fpu_save, &sf->fpu_save); 151 err |= __get_user(fpu_save, &sf->fpu_save);
149 152
150 if (fpu_save) 153 if (fpu_save)
@@ -199,6 +202,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
199 202
200 regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC); 203 regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
201 204
205 /* Prevent syscall restart. */
206 pt_regs_clear_syscall(regs);
207
202 err |= __get_user(fpu_save, &sf->fpu_save); 208 err |= __get_user(fpu_save, &sf->fpu_save);
203 209
204 if (fpu_save) 210 if (fpu_save)
@@ -245,15 +251,29 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen)
245 251
246static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) 252static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
247{ 253{
248 unsigned long sp; 254 unsigned long sp = regs->u_regs[UREG_FP];
249 255
250 sp = regs->u_regs[UREG_FP]; 256 /*
257 * If we are on the alternate signal stack and would overflow it, don't.
258 * Return an always-bogus address instead so we will die with SIGSEGV.
259 */
260 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
261 return (void __user *) -1L;
251 262
252 /* This is the X/Open sanctioned signal stack switching. */ 263 /* This is the X/Open sanctioned signal stack switching. */
253 if (sa->sa_flags & SA_ONSTACK) { 264 if (sa->sa_flags & SA_ONSTACK) {
254 if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) 265 if (sas_ss_flags(sp) == 0)
255 sp = current->sas_ss_sp + current->sas_ss_size; 266 sp = current->sas_ss_sp + current->sas_ss_size;
256 } 267 }
268
269 /* Always align the stack frame. This handles two cases. First,
270 * sigaltstack need not be mindful of platform specific stack
271 * alignment. Second, if we took this signal because the stack
272 * is not aligned properly, we'd like to take the signal cleanly
273 * and report that.
274 */
275 sp &= ~7UL;
276
257 return (void __user *)(sp - framesize); 277 return (void __user *)(sp - framesize);
258} 278}
259 279
@@ -493,26 +513,36 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
493 * want to handle. Thus you cannot kill init even with a SIGKILL even by 513 * want to handle. Thus you cannot kill init even with a SIGKILL even by
494 * mistake. 514 * mistake.
495 */ 515 */
496asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall) 516asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0)
497{ 517{
498 siginfo_t info;
499 struct sparc_deliver_cookie cookie;
500 struct k_sigaction ka; 518 struct k_sigaction ka;
501 int signr; 519 int restart_syscall;
502 sigset_t *oldset; 520 sigset_t *oldset;
521 siginfo_t info;
522 int signr;
503 523
504 cookie.restart_syscall = restart_syscall; 524 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
505 cookie.orig_i0 = orig_i0; 525 restart_syscall = 1;
526 else
527 restart_syscall = 0;
506 528
507 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 529 if (test_thread_flag(TIF_RESTORE_SIGMASK))
508 oldset = &current->saved_sigmask; 530 oldset = &current->saved_sigmask;
509 else 531 else
510 oldset = &current->blocked; 532 oldset = &current->blocked;
511 533
512 signr = get_signal_to_deliver(&info, &ka, regs, &cookie); 534 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
535
536 /* If the debugger messes with the program counter, it clears
537 * the software "in syscall" bit, directing us to not perform
538 * a syscall restart.
539 */
540 if (restart_syscall && !pt_regs_is_syscall(regs))
541 restart_syscall = 0;
542
513 if (signr > 0) { 543 if (signr > 0) {
514 if (cookie.restart_syscall) 544 if (restart_syscall)
515 syscall_restart(cookie.orig_i0, regs, &ka.sa); 545 syscall_restart(orig_i0, regs, &ka.sa);
516 handle_signal(signr, &ka, &info, oldset, regs); 546 handle_signal(signr, &ka, &info, oldset, regs);
517 547
518 /* a signal was successfully delivered; the saved 548 /* a signal was successfully delivered; the saved
@@ -524,16 +554,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
524 clear_thread_flag(TIF_RESTORE_SIGMASK); 554 clear_thread_flag(TIF_RESTORE_SIGMASK);
525 return; 555 return;
526 } 556 }
527 if (cookie.restart_syscall && 557 if (restart_syscall &&
528 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 558 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
529 regs->u_regs[UREG_I0] == ERESTARTSYS || 559 regs->u_regs[UREG_I0] == ERESTARTSYS ||
530 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { 560 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
531 /* replay the system call when we are done */ 561 /* replay the system call when we are done */
532 regs->u_regs[UREG_I0] = cookie.orig_i0; 562 regs->u_regs[UREG_I0] = orig_i0;
533 regs->pc -= 4; 563 regs->pc -= 4;
534 regs->npc -= 4; 564 regs->npc -= 4;
535 } 565 }
536 if (cookie.restart_syscall && 566 if (restart_syscall &&
537 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { 567 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
538 regs->u_regs[UREG_G1] = __NR_restart_syscall; 568 regs->u_regs[UREG_G1] = __NR_restart_syscall;
539 regs->pc -= 4; 569 regs->pc -= 4;
@@ -585,27 +615,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
585out: 615out:
586 return ret; 616 return ret;
587} 617}
588
589void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
590{
591 struct sparc_deliver_cookie *cp = cookie;
592
593 if (cp->restart_syscall &&
594 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
595 regs->u_regs[UREG_I0] == ERESTARTSYS ||
596 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
597 /* replay the system call when we are done */
598 regs->u_regs[UREG_I0] = cp->orig_i0;
599 regs->pc -= 4;
600 regs->npc -= 4;
601 cp->restart_syscall = 0;
602 }
603
604 if (cp->restart_syscall &&
605 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
606 regs->u_regs[UREG_G1] = __NR_restart_syscall;
607 regs->pc -= 4;
608 regs->npc -= 4;
609 cp->restart_syscall = 0;
610 }
611}