aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-26 12:30:13 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-06 17:14:05 -0500
commit2a89fc8b91abf1ba56daa23b05e6572b30331837 (patch)
tree39bb67a7a1075e7f8032b76c1295880a48382d06
parentd4afed4d20e91a12de7cd1c64bb3451ee2236d19 (diff)
sparc: Fix handling of orig_i0 wrt. debugging when restarting syscalls.
[ A combination of upstream commits 1d299bc7732c34d85bd43ac1a8745f5a2fed2078 and e88d2468718b0789b4c33da2f7e1cef2a1eee279 ] Although we provide a proper way for a debugger to control whether syscall restart occurs, we run into problems because orig_i0 is not saved and restored properly. Luckily we can solve this problem without having to make debuggers aware of the issue. Across system calls, several registers are considered volatile and can be safely clobbered. Therefore we use the pt_regs save area of one of those registers, %g6, as a place to save and restore orig_i0. Debuggers transparently will do the right thing because they save and restore this register already. Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/sparc/kernel/signal32.c18
-rw-r--r--arch/sparc/kernel/signal_32.c30
-rw-r--r--arch/sparc/kernel/signal_64.c42
3 files changed, 63 insertions, 27 deletions
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 5d92488fc16..2e58328c30e 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -829,21 +829,23 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
829 * want to handle. Thus you cannot kill init even with a SIGKILL even by 829 * want to handle. Thus you cannot kill init even with a SIGKILL even by
830 * mistake. 830 * mistake.
831 */ 831 */
832void do_signal32(sigset_t *oldset, struct pt_regs * regs, 832void do_signal32(sigset_t *oldset, struct pt_regs * regs)
833 int restart_syscall, unsigned long orig_i0)
834{ 833{
835 struct k_sigaction ka; 834 struct k_sigaction ka;
835 unsigned long orig_i0;
836 int restart_syscall;
836 siginfo_t info; 837 siginfo_t info;
837 int signr; 838 int signr;
838 839
839 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 840 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
840 841
841 /* If the debugger messes with the program counter, it clears 842 restart_syscall = 0;
842 * the "in syscall" bit, directing us to not perform a syscall 843 orig_i0 = 0;
843 * restart. 844 if (pt_regs_is_syscall(regs) &&
844 */ 845 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
845 if (restart_syscall && !pt_regs_is_syscall(regs)) 846 restart_syscall = 1;
846 restart_syscall = 0; 847 orig_i0 = regs->u_regs[UREG_G6];
848 }
847 849
848 if (signr > 0) { 850 if (signr > 0) {
849 if (restart_syscall) 851 if (restart_syscall)
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 04ede8f04ad..2302567578b 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -525,10 +525,26 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
525 siginfo_t info; 525 siginfo_t info;
526 int signr; 526 int signr;
527 527
528 /* It's a lot of work and synchronization to add a new ptrace
529 * register for GDB to save and restore in order to get
530 * orig_i0 correct for syscall restarts when debugging.
531 *
532 * Although it should be the case that most of the global
533 * registers are volatile across a system call, glibc already
534 * depends upon that fact that we preserve them. So we can't
535 * just use any global register to save away the orig_i0 value.
536 *
537 * In particular %g2, %g3, %g4, and %g5 are all assumed to be
538 * preserved across a system call trap by various pieces of
539 * code in glibc.
540 *
541 * %g7 is used as the "thread register". %g6 is not used in
542 * any fixed manner. %g6 is used as a scratch register and
543 * a compiler temporary, but it's value is never used across
544 * a system call. Therefore %g6 is usable for orig_i0 storage.
545 */
528 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) 546 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
529 restart_syscall = 1; 547 regs->u_regs[UREG_G6] = orig_i0;
530 else
531 restart_syscall = 0;
532 548
533 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 549 if (test_thread_flag(TIF_RESTORE_SIGMASK))
534 oldset = &current->saved_sigmask; 550 oldset = &current->saved_sigmask;
@@ -541,8 +557,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
541 * the software "in syscall" bit, directing us to not perform 557 * the software "in syscall" bit, directing us to not perform
542 * a syscall restart. 558 * a syscall restart.
543 */ 559 */
544 if (restart_syscall && !pt_regs_is_syscall(regs)) 560 restart_syscall = 0;
545 restart_syscall = 0; 561 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
562 restart_syscall = 1;
563 orig_i0 = regs->u_regs[UREG_G6];
564 }
565
546 566
547 if (signr > 0) { 567 if (signr > 0) {
548 if (restart_syscall) 568 if (restart_syscall)
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 47509df3b89..d58260bff2d 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -535,11 +535,27 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
535 siginfo_t info; 535 siginfo_t info;
536 int signr; 536 int signr;
537 537
538 /* It's a lot of work and synchronization to add a new ptrace
539 * register for GDB to save and restore in order to get
540 * orig_i0 correct for syscall restarts when debugging.
541 *
542 * Although it should be the case that most of the global
543 * registers are volatile across a system call, glibc already
544 * depends upon that fact that we preserve them. So we can't
545 * just use any global register to save away the orig_i0 value.
546 *
547 * In particular %g2, %g3, %g4, and %g5 are all assumed to be
548 * preserved across a system call trap by various pieces of
549 * code in glibc.
550 *
551 * %g7 is used as the "thread register". %g6 is not used in
552 * any fixed manner. %g6 is used as a scratch register and
553 * a compiler temporary, but it's value is never used across
554 * a system call. Therefore %g6 is usable for orig_i0 storage.
555 */
538 if (pt_regs_is_syscall(regs) && 556 if (pt_regs_is_syscall(regs) &&
539 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { 557 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
540 restart_syscall = 1; 558 regs->u_regs[UREG_G6] = orig_i0;
541 } else
542 restart_syscall = 0;
543 559
544 if (current_thread_info()->status & TS_RESTORE_SIGMASK) 560 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
545 oldset = &current->saved_sigmask; 561 oldset = &current->saved_sigmask;
@@ -548,22 +564,20 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
548 564
549#ifdef CONFIG_COMPAT 565#ifdef CONFIG_COMPAT
550 if (test_thread_flag(TIF_32BIT)) { 566 if (test_thread_flag(TIF_32BIT)) {
551 extern void do_signal32(sigset_t *, struct pt_regs *, 567 extern void do_signal32(sigset_t *, struct pt_regs *);
552 int restart_syscall, 568 do_signal32(oldset, regs);
553 unsigned long orig_i0);
554 do_signal32(oldset, regs, restart_syscall, orig_i0);
555 return; 569 return;
556 } 570 }
557#endif 571#endif
558 572
559 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 573 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
560 574
561 /* If the debugger messes with the program counter, it clears 575 restart_syscall = 0;
562 * the software "in syscall" bit, directing us to not perform 576 if (pt_regs_is_syscall(regs) &&
563 * a syscall restart. 577 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
564 */ 578 restart_syscall = 1;
565 if (restart_syscall && !pt_regs_is_syscall(regs)) 579 orig_i0 = regs->u_regs[UREG_G6];
566 restart_syscall = 0; 580 }
567 581
568 if (signr > 0) { 582 if (signr > 0) {
569 if (restart_syscall) 583 if (restart_syscall)