aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/signal32.c2
-rw-r--r--arch/sparc/kernel/signal_32.c20
-rw-r--r--arch/sparc/kernel/signal_64.c20
3 files changed, 31 insertions, 11 deletions
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 2e86fd1ddc7..023b8860dc9 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -837,7 +837,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs)
837 if (pt_regs_is_syscall(regs) && 837 if (pt_regs_is_syscall(regs) &&
838 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { 838 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
839 restart_syscall = 1; 839 restart_syscall = 1;
840 orig_i0 = regs->u_regs[UREG_G2]; 840 orig_i0 = regs->u_regs[UREG_G6];
841 } 841 }
842 842
843 if (signr > 0) { 843 if (signr > 0) {
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 7dfaff64cd6..d54c6e53aba 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -523,12 +523,22 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
523 * register for GDB to save and restore in order to get 523 * register for GDB to save and restore in order to get
524 * orig_i0 correct for syscall restarts when debugging. 524 * orig_i0 correct for syscall restarts when debugging.
525 * 525 *
526 * However, we luckily can use the fact that several registers 526 * Although it should be the case that most of the global
527 * are volatile across system calls. One such register is 527 * registers are volatile across a system call, glibc already
528 * %g2, so use that as a place to save away orig_i0. 528 * depends upon that fact that we preserve them. So we can't
529 * just use any global register to save away the orig_i0 value.
530 *
531 * In particular %g2, %g3, %g4, and %g5 are all assumed to be
532 * preserved across a system call trap by various pieces of
533 * code in glibc.
534 *
535 * %g7 is used as the "thread register". %g6 is not used in
536 * any fixed manner. %g6 is used as a scratch register and
537 * a compiler temporary, but it's value is never used across
538 * a system call. Therefore %g6 is usable for orig_i0 storage.
529 */ 539 */
530 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) 540 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
531 regs->u_regs[UREG_G2] = orig_i0; 541 regs->u_regs[UREG_G6] = orig_i0;
532 542
533 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 543 if (test_thread_flag(TIF_RESTORE_SIGMASK))
534 oldset = &current->saved_sigmask; 544 oldset = &current->saved_sigmask;
@@ -544,7 +554,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
544 restart_syscall = 0; 554 restart_syscall = 0;
545 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) { 555 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
546 restart_syscall = 1; 556 restart_syscall = 1;
547 orig_i0 = regs->u_regs[UREG_G2]; 557 orig_i0 = regs->u_regs[UREG_G6];
548 } 558 }
549 559
550 560
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 1ddf0dedb92..f0836cd0e2f 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -533,13 +533,23 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
533 * register for GDB to save and restore in order to get 533 * register for GDB to save and restore in order to get
534 * orig_i0 correct for syscall restarts when debugging. 534 * orig_i0 correct for syscall restarts when debugging.
535 * 535 *
536 * However, we luckily can use the fact that several registers 536 * Although it should be the case that most of the global
537 * are volatile across system calls. One such register is 537 * registers are volatile across a system call, glibc already
538 * %g2, so use that as a place to save away orig_i0. 538 * depends upon that fact that we preserve them. So we can't
539 * just use any global register to save away the orig_i0 value.
540 *
541 * In particular %g2, %g3, %g4, and %g5 are all assumed to be
542 * preserved across a system call trap by various pieces of
543 * code in glibc.
544 *
545 * %g7 is used as the "thread register". %g6 is not used in
546 * any fixed manner. %g6 is used as a scratch register and
547 * a compiler temporary, but it's value is never used across
548 * a system call. Therefore %g6 is usable for orig_i0 storage.
539 */ 549 */
540 if (pt_regs_is_syscall(regs) && 550 if (pt_regs_is_syscall(regs) &&
541 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) 551 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
542 regs->u_regs[UREG_G2] = orig_i0; 552 regs->u_regs[UREG_G6] = orig_i0;
543 553
544 if (current_thread_info()->status & TS_RESTORE_SIGMASK) 554 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
545 oldset = &current->saved_sigmask; 555 oldset = &current->saved_sigmask;
@@ -560,7 +570,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
560 if (pt_regs_is_syscall(regs) && 570 if (pt_regs_is_syscall(regs) &&
561 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { 571 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
562 restart_syscall = 1; 572 restart_syscall = 1;
563 orig_i0 = regs->u_regs[UREG_G2]; 573 orig_i0 = regs->u_regs[UREG_G6];
564 } 574 }
565 575
566 if (signr > 0) { 576 if (signr > 0) {