aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-05-11 12:55:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-05-11 12:55:48 -0400
commit854a989546c12683186c84601d4902591dddd8a9 (patch)
tree143362c88a48958bdf68396379c4401f6caa82ae /arch
parent633331f389c2d9c631371d09a54626a5e4749452 (diff)
parent28e6103665301ce60634e8a77f0b657c6cc099de (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6: sparc: Fix debugger syscall restart interactions. sparc: Fix ptrace() detach. sparc32: Don't twiddle PT_DTRACE in exec. sparc video: remove open boot prom code
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/entry.S2
-rw-r--r--arch/sparc/kernel/process.c5
-rw-r--r--arch/sparc/kernel/ptrace.c6
-rw-r--r--arch/sparc/kernel/rtrap.S11
-rw-r--r--arch/sparc/kernel/signal.c64
-rw-r--r--arch/sparc64/kernel/etrap.S7
-rw-r--r--arch/sparc64/kernel/ptrace.c16
-rw-r--r--arch/sparc64/kernel/rtrap.S1
-rw-r--r--arch/sparc64/kernel/signal.c60
-rw-r--r--arch/sparc64/kernel/signal32.c26
10 files changed, 97 insertions, 101 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 57d1bbdd0bd2..4bcfe54f878d 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1306,6 +1306,8 @@ ret_from_fork:
1306 .align 4 1306 .align 4
1307 .globl linux_sparc_syscall 1307 .globl linux_sparc_syscall
1308linux_sparc_syscall: 1308linux_sparc_syscall:
1309 sethi %hi(PSR_SYSCALL), %l4
1310 or %l0, %l4, %l0
1309 /* Direct access to user regs, must faster. */ 1311 /* Direct access to user regs, must faster. */
1310 cmp %g1, NR_SYSCALLS 1312 cmp %g1, NR_SYSCALLS
1311 bgeu linux_sparc_ni_syscall 1313 bgeu linux_sparc_ni_syscall
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 36431f377dee..da48d248cc17 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -638,11 +638,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
638 (char __user * __user *)regs->u_regs[base + UREG_I2], 638 (char __user * __user *)regs->u_regs[base + UREG_I2],
639 regs); 639 regs);
640 putname(filename); 640 putname(filename);
641 if (error == 0) {
642 task_lock(current);
643 current->ptrace &= ~PT_DTRACE;
644 task_unlock(current);
645 }
646out: 641out:
647 return error; 642 return error;
648} 643}
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 7f44ae69b29e..81f3b929743f 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -170,8 +170,8 @@ static int genregs32_set(struct task_struct *target,
170 switch (pos) { 170 switch (pos) {
171 case 32: /* PSR */ 171 case 32: /* PSR */
172 psr = regs->psr; 172 psr = regs->psr;
173 psr &= ~PSR_ICC; 173 psr &= ~(PSR_ICC | PSR_SYSCALL);
174 psr |= (reg & PSR_ICC); 174 psr |= (reg & (PSR_ICC | PSR_SYSCALL));
175 regs->psr = psr; 175 regs->psr = psr;
176 break; 176 break;
177 case 33: /* PC */ 177 case 33: /* PC */
@@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
441 break; 441 break;
442 442
443 default: 443 default:
444 if (request == PTRACE_SPARC_DETACH)
445 request = PTRACE_DETACH;
444 ret = ptrace_request(child, request, addr, data); 446 ret = ptrace_request(child, request, addr, data);
445 break; 447 break;
446 } 448 }
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
index 77ca6fd81253..b27b5b56f77a 100644
--- a/arch/sparc/kernel/rtrap.S
+++ b/arch/sparc/kernel/rtrap.S
@@ -50,8 +50,9 @@ rtrap_7win_patch5: and %g1, 0x7f, %g1
50ret_trap_entry: 50ret_trap_entry:
51ret_trap_lockless_ipi: 51ret_trap_lockless_ipi:
52 andcc %t_psr, PSR_PS, %g0 52 andcc %t_psr, PSR_PS, %g0
53 sethi %hi(PSR_SYSCALL), %g1
53 be 1f 54 be 1f
54 nop 55 andn %t_psr, %g1, %t_psr
55 56
56 wr %t_psr, 0x0, %psr 57 wr %t_psr, 0x0, %psr
57 b ret_trap_kernel 58 b ret_trap_kernel
@@ -73,7 +74,6 @@ signal_p:
73 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 74 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
74 75
75 mov %l5, %o1 76 mov %l5, %o1
76 mov %l6, %o2
77 call do_signal 77 call do_signal
78 add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr 78 add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
79 79
@@ -81,6 +81,8 @@ signal_p:
81 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 81 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
82 clr %l6 82 clr %l6
83ret_trap_continue: 83ret_trap_continue:
84 sethi %hi(PSR_SYSCALL), %g1
85 andn %t_psr, %g1, %t_psr
84 wr %t_psr, 0x0, %psr 86 wr %t_psr, 0x0, %psr
85 WRITE_PAUSE 87 WRITE_PAUSE
86 88
@@ -137,8 +139,9 @@ ret_trap_userwins_ok:
137 LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc) 139 LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
138 or %t_pc, %t_npc, %g2 140 or %t_pc, %t_npc, %g2
139 andcc %g2, 0x3, %g0 141 andcc %g2, 0x3, %g0
142 sethi %hi(PSR_SYCALL), %g2
140 be 1f 143 be 1f
141 nop 144 andn %t_psr, %g2, %t_psr
142 145
143 b ret_trap_unaligned_pc 146 b ret_trap_unaligned_pc
144 add %sp, STACKFRAME_SZ, %o0 147 add %sp, STACKFRAME_SZ, %o0
@@ -201,6 +204,8 @@ rtrap_patch5: and %g1, 0xff, %g1
2011: 2041:
202 LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1) 205 LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
2032: 2062:
207 sethi %hi(PSR_SYSCALL), %twin_tmp1
208 andn %t_psr, %twin_tmp1, %t_psr
204 wr %t_psr, 0x0, %psr 209 wr %t_psr, 0x0, %psr
205 WRITE_PAUSE 210 WRITE_PAUSE
206 211
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 368157926d24..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)
@@ -507,26 +513,36 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
507 * 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
508 * mistake. 514 * mistake.
509 */ 515 */
510asmlinkage 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)
511{ 517{
512 siginfo_t info;
513 struct sparc_deliver_cookie cookie;
514 struct k_sigaction ka; 518 struct k_sigaction ka;
515 int signr; 519 int restart_syscall;
516 sigset_t *oldset; 520 sigset_t *oldset;
521 siginfo_t info;
522 int signr;
517 523
518 cookie.restart_syscall = restart_syscall; 524 if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
519 cookie.orig_i0 = orig_i0; 525 restart_syscall = 1;
526 else
527 restart_syscall = 0;
520 528
521 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 529 if (test_thread_flag(TIF_RESTORE_SIGMASK))
522 oldset = &current->saved_sigmask; 530 oldset = &current->saved_sigmask;
523 else 531 else
524 oldset = &current->blocked; 532 oldset = &current->blocked;
525 533
526 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
527 if (signr > 0) { 543 if (signr > 0) {
528 if (cookie.restart_syscall) 544 if (restart_syscall)
529 syscall_restart(cookie.orig_i0, regs, &ka.sa); 545 syscall_restart(orig_i0, regs, &ka.sa);
530 handle_signal(signr, &ka, &info, oldset, regs); 546 handle_signal(signr, &ka, &info, oldset, regs);
531 547
532 /* a signal was successfully delivered; the saved 548 /* a signal was successfully delivered; the saved
@@ -538,16 +554,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
538 clear_thread_flag(TIF_RESTORE_SIGMASK); 554 clear_thread_flag(TIF_RESTORE_SIGMASK);
539 return; 555 return;
540 } 556 }
541 if (cookie.restart_syscall && 557 if (restart_syscall &&
542 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 558 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
543 regs->u_regs[UREG_I0] == ERESTARTSYS || 559 regs->u_regs[UREG_I0] == ERESTARTSYS ||
544 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { 560 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
545 /* replay the system call when we are done */ 561 /* replay the system call when we are done */
546 regs->u_regs[UREG_I0] = cookie.orig_i0; 562 regs->u_regs[UREG_I0] = orig_i0;
547 regs->pc -= 4; 563 regs->pc -= 4;
548 regs->npc -= 4; 564 regs->npc -= 4;
549 } 565 }
550 if (cookie.restart_syscall && 566 if (restart_syscall &&
551 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { 567 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
552 regs->u_regs[UREG_G1] = __NR_restart_syscall; 568 regs->u_regs[UREG_G1] = __NR_restart_syscall;
553 regs->pc -= 4; 569 regs->pc -= 4;
@@ -599,27 +615,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
599out: 615out:
600 return ret; 616 return ret;
601} 617}
602
603void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
604{
605 struct sparc_deliver_cookie *cp = cookie;
606
607 if (cp->restart_syscall &&
608 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
609 regs->u_regs[UREG_I0] == ERESTARTSYS ||
610 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
611 /* replay the system call when we are done */
612 regs->u_regs[UREG_I0] = cp->orig_i0;
613 regs->pc -= 4;
614 regs->npc -= 4;
615 cp->restart_syscall = 0;
616 }
617
618 if (cp->restart_syscall &&
619 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
620 regs->u_regs[UREG_G1] = __NR_restart_syscall;
621 regs->pc -= 4;
622 regs->npc -= 4;
623 cp->restart_syscall = 0;
624 }
625}
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index b49d3b60bc0c..f25e1da3fd03 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -27,11 +27,12 @@
27 27
28 .text 28 .text
29 .align 64 29 .align 64
30 .globl etrap, etrap_irq, etraptl1 30 .globl etrap_syscall, etrap, etrap_irq, etraptl1
31etrap: rdpr %pil, %g2 31etrap: rdpr %pil, %g2
32etrap_irq: 32etrap_irq: clr %g3
33 TRAP_LOAD_THREAD_REG(%g6, %g1) 33etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1)
34 rdpr %tstate, %g1 34 rdpr %tstate, %g1
35 or %g1, %g3, %g1
35 sllx %g2, 20, %g3 36 sllx %g2, 20, %g3
36 andcc %g1, TSTATE_PRIV, %g0 37 andcc %g1, TSTATE_PRIV, %g0
37 or %g1, %g3, %g1 38 or %g1, %g3, %g1
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index e9fc0aa2da38..f6c9fc92921d 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target,
287 32 * sizeof(u64), 287 32 * sizeof(u64),
288 33 * sizeof(u64)); 288 33 * sizeof(u64));
289 if (!ret) { 289 if (!ret) {
290 /* Only the condition codes can be modified 290 /* Only the condition codes and the "in syscall"
291 * in the %tstate register. 291 * state can be modified in the %tstate register.
292 */ 292 */
293 tstate &= (TSTATE_ICC | TSTATE_XCC); 293 tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
294 regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); 294 regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
295 regs->tstate |= tstate; 295 regs->tstate |= tstate;
296 } 296 }
297 } 297 }
@@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target,
657 switch (pos) { 657 switch (pos) {
658 case 32: /* PSR */ 658 case 32: /* PSR */
659 tstate = regs->tstate; 659 tstate = regs->tstate;
660 tstate &= ~(TSTATE_ICC | TSTATE_XCC); 660 tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
661 tstate |= psr_to_tstate_icc(reg); 661 tstate |= psr_to_tstate_icc(reg);
662 if (reg & PSR_SYSCALL)
663 tstate |= TSTATE_SYSCALL;
662 regs->tstate = tstate; 664 regs->tstate = tstate;
663 break; 665 break;
664 case 33: /* PC */ 666 case 33: /* PC */
@@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
944 break; 946 break;
945 947
946 default: 948 default:
949 if (request == PTRACE_SPARC_DETACH)
950 request = PTRACE_DETACH;
947 ret = compat_ptrace_request(child, request, addr, data); 951 ret = compat_ptrace_request(child, request, addr, data);
948 break; 952 break;
949 } 953 }
@@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
1036 break; 1040 break;
1037 1041
1038 default: 1042 default:
1043 if (request == PTRACE_SPARC_DETACH)
1044 request = PTRACE_DETACH;
1039 ret = ptrace_request(child, request, addr, data); 1045 ret = ptrace_request(child, request, addr, data);
1040 break; 1046 break;
1041 } 1047 }
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index ecf6753b204a..b9b785fd8b46 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -257,6 +257,7 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
257 wr %o3, %g0, %y 257 wr %o3, %g0, %y
258 wrpr %l4, 0x0, %pil 258 wrpr %l4, 0x0, %pil
259 wrpr %g0, 0x1, %tl 259 wrpr %g0, 0x1, %tl
260 andn %l1, TSTATE_SYSCALL, %l1
260 wrpr %l1, %g0, %tstate 261 wrpr %l1, %g0, %tstate
261 wrpr %l2, %g0, %tpc 262 wrpr %l2, %g0, %tpc
262 wrpr %o2, %g0, %tnpc 263 wrpr %o2, %g0, %tnpc
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 07c0443ea3f5..2378482c2aab 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -333,7 +333,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
333 regs->tnpc = tnpc; 333 regs->tnpc = tnpc;
334 334
335 /* Prevent syscall restart. */ 335 /* Prevent syscall restart. */
336 pt_regs_clear_trap_type(regs); 336 pt_regs_clear_syscall(regs);
337 337
338 sigdelsetmask(&set, ~_BLOCKABLE); 338 sigdelsetmask(&set, ~_BLOCKABLE);
339 spin_lock_irq(&current->sighand->siglock); 339 spin_lock_irq(&current->sighand->siglock);
@@ -499,7 +499,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
499} 499}
500 500
501static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, 501static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
502 struct sigaction *sa) 502 struct sigaction *sa)
503{ 503{
504 switch (regs->u_regs[UREG_I0]) { 504 switch (regs->u_regs[UREG_I0]) {
505 case ERESTART_RESTARTBLOCK: 505 case ERESTART_RESTARTBLOCK:
@@ -525,19 +525,17 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
525 */ 525 */
526static void do_signal(struct pt_regs *regs, unsigned long orig_i0) 526static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
527{ 527{
528 struct signal_deliver_cookie cookie;
529 struct k_sigaction ka; 528 struct k_sigaction ka;
529 int restart_syscall;
530 sigset_t *oldset; 530 sigset_t *oldset;
531 siginfo_t info; 531 siginfo_t info;
532 int signr; 532 int signr;
533 533
534 if (pt_regs_is_syscall(regs) && 534 if (pt_regs_is_syscall(regs) &&
535 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { 535 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
536 pt_regs_clear_trap_type(regs); 536 restart_syscall = 1;
537 cookie.restart_syscall = 1;
538 } else 537 } else
539 cookie.restart_syscall = 0; 538 restart_syscall = 0;
540 cookie.orig_i0 = orig_i0;
541 539
542 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 540 if (test_thread_flag(TIF_RESTORE_SIGMASK))
543 oldset = &current->saved_sigmask; 541 oldset = &current->saved_sigmask;
@@ -547,16 +545,25 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
547#ifdef CONFIG_COMPAT 545#ifdef CONFIG_COMPAT
548 if (test_thread_flag(TIF_32BIT)) { 546 if (test_thread_flag(TIF_32BIT)) {
549 extern void do_signal32(sigset_t *, struct pt_regs *, 547 extern void do_signal32(sigset_t *, struct pt_regs *,
550 struct signal_deliver_cookie *); 548 int restart_syscall,
551 do_signal32(oldset, regs, &cookie); 549 unsigned long orig_i0);
550 do_signal32(oldset, regs, restart_syscall, orig_i0);
552 return; 551 return;
553 } 552 }
554#endif 553#endif
555 554
556 signr = get_signal_to_deliver(&info, &ka, regs, &cookie); 555 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
556
557 /* If the debugger messes with the program counter, it clears
558 * the software "in syscall" bit, directing us to not perform
559 * a syscall restart.
560 */
561 if (restart_syscall && !pt_regs_is_syscall(regs))
562 restart_syscall = 0;
563
557 if (signr > 0) { 564 if (signr > 0) {
558 if (cookie.restart_syscall) 565 if (restart_syscall)
559 syscall_restart(cookie.orig_i0, regs, &ka.sa); 566 syscall_restart(orig_i0, regs, &ka.sa);
560 handle_signal(signr, &ka, &info, oldset, regs); 567 handle_signal(signr, &ka, &info, oldset, regs);
561 568
562 /* a signal was successfully delivered; the saved 569 /* a signal was successfully delivered; the saved
@@ -568,16 +575,16 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
568 clear_thread_flag(TIF_RESTORE_SIGMASK); 575 clear_thread_flag(TIF_RESTORE_SIGMASK);
569 return; 576 return;
570 } 577 }
571 if (cookie.restart_syscall && 578 if (restart_syscall &&
572 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 579 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
573 regs->u_regs[UREG_I0] == ERESTARTSYS || 580 regs->u_regs[UREG_I0] == ERESTARTSYS ||
574 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { 581 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
575 /* replay the system call when we are done */ 582 /* replay the system call when we are done */
576 regs->u_regs[UREG_I0] = cookie.orig_i0; 583 regs->u_regs[UREG_I0] = orig_i0;
577 regs->tpc -= 4; 584 regs->tpc -= 4;
578 regs->tnpc -= 4; 585 regs->tnpc -= 4;
579 } 586 }
580 if (cookie.restart_syscall && 587 if (restart_syscall &&
581 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { 588 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
582 regs->u_regs[UREG_G1] = __NR_restart_syscall; 589 regs->u_regs[UREG_G1] = __NR_restart_syscall;
583 regs->tpc -= 4; 590 regs->tpc -= 4;
@@ -598,26 +605,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
598 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 605 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
599 do_signal(regs, orig_i0); 606 do_signal(regs, orig_i0);
600} 607}
601
602void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
603{
604 struct signal_deliver_cookie *cp = cookie;
605
606 if (cp->restart_syscall &&
607 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
608 regs->u_regs[UREG_I0] == ERESTARTSYS ||
609 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
610 /* replay the system call when we are done */
611 regs->u_regs[UREG_I0] = cp->orig_i0;
612 regs->tpc -= 4;
613 regs->tnpc -= 4;
614 cp->restart_syscall = 0;
615 }
616 if (cp->restart_syscall &&
617 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
618 regs->u_regs[UREG_G1] = __NR_restart_syscall;
619 regs->tpc -= 4;
620 regs->tnpc -= 4;
621 cp->restart_syscall = 0;
622 }
623}
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 0f6b7b156efd..3f19e9af3d1b 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -269,7 +269,7 @@ void do_sigreturn32(struct pt_regs *regs)
269 regs->tstate |= psr_to_tstate_icc(psr); 269 regs->tstate |= psr_to_tstate_icc(psr);
270 270
271 /* Prevent syscall restart. */ 271 /* Prevent syscall restart. */
272 pt_regs_clear_trap_type(regs); 272 pt_regs_clear_syscall(regs);
273 273
274 err |= __get_user(fpu_save, &sf->fpu_save); 274 err |= __get_user(fpu_save, &sf->fpu_save);
275 if (fpu_save) 275 if (fpu_save)
@@ -355,7 +355,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
355 regs->tstate |= psr_to_tstate_icc(psr); 355 regs->tstate |= psr_to_tstate_icc(psr);
356 356
357 /* Prevent syscall restart. */ 357 /* Prevent syscall restart. */
358 pt_regs_clear_trap_type(regs); 358 pt_regs_clear_syscall(regs);
359 359
360 err |= __get_user(fpu_save, &sf->fpu_save); 360 err |= __get_user(fpu_save, &sf->fpu_save);
361 if (fpu_save) 361 if (fpu_save)
@@ -768,16 +768,24 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
768 * mistake. 768 * mistake.
769 */ 769 */
770void do_signal32(sigset_t *oldset, struct pt_regs * regs, 770void do_signal32(sigset_t *oldset, struct pt_regs * regs,
771 struct signal_deliver_cookie *cookie) 771 int restart_syscall, unsigned long orig_i0)
772{ 772{
773 struct k_sigaction ka; 773 struct k_sigaction ka;
774 siginfo_t info; 774 siginfo_t info;
775 int signr; 775 int signr;
776 776
777 signr = get_signal_to_deliver(&info, &ka, regs, cookie); 777 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
778
779 /* If the debugger messes with the program counter, it clears
780 * the "in syscall" bit, directing us to not perform a syscall
781 * restart.
782 */
783 if (restart_syscall && !pt_regs_is_syscall(regs))
784 restart_syscall = 0;
785
778 if (signr > 0) { 786 if (signr > 0) {
779 if (cookie->restart_syscall) 787 if (restart_syscall)
780 syscall_restart32(cookie->orig_i0, regs, &ka.sa); 788 syscall_restart32(orig_i0, regs, &ka.sa);
781 handle_signal32(signr, &ka, &info, oldset, regs); 789 handle_signal32(signr, &ka, &info, oldset, regs);
782 790
783 /* a signal was successfully delivered; the saved 791 /* a signal was successfully delivered; the saved
@@ -789,16 +797,16 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
789 clear_thread_flag(TIF_RESTORE_SIGMASK); 797 clear_thread_flag(TIF_RESTORE_SIGMASK);
790 return; 798 return;
791 } 799 }
792 if (cookie->restart_syscall && 800 if (restart_syscall &&
793 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 801 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
794 regs->u_regs[UREG_I0] == ERESTARTSYS || 802 regs->u_regs[UREG_I0] == ERESTARTSYS ||
795 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { 803 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
796 /* replay the system call when we are done */ 804 /* replay the system call when we are done */
797 regs->u_regs[UREG_I0] = cookie->orig_i0; 805 regs->u_regs[UREG_I0] = orig_i0;
798 regs->tpc -= 4; 806 regs->tpc -= 4;
799 regs->tnpc -= 4; 807 regs->tnpc -= 4;
800 } 808 }
801 if (cookie->restart_syscall && 809 if (restart_syscall &&
802 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { 810 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
803 regs->u_regs[UREG_G1] = __NR_restart_syscall; 811 regs->u_regs[UREG_G1] = __NR_restart_syscall;
804 regs->tpc -= 4; 812 regs->tpc -= 4;