diff options
| -rw-r--r-- | arch/sparc64/kernel/process.c | 6 | ||||
| -rw-r--r-- | arch/sparc64/kernel/signal.c | 6 | ||||
| -rw-r--r-- | arch/sparc64/kernel/signal32.c | 6 |
3 files changed, 11 insertions, 7 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 056013749157..500ac6d483a0 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
| @@ -591,12 +591,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
| 591 | if (clone_flags & CLONE_SETTLS) | 591 | if (clone_flags & CLONE_SETTLS) |
| 592 | t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; | 592 | t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; |
| 593 | 593 | ||
| 594 | /* We do not want to accidently trigger system call restart | ||
| 595 | * handling in the new thread. Therefore, clear out the trap | ||
| 596 | * type, which will make pt_regs_regs_is_syscall() return false. | ||
| 597 | */ | ||
| 598 | pt_regs_clear_trap_type(t->kregs); | ||
| 599 | |||
| 600 | return 0; | 594 | return 0; |
| 601 | } | 595 | } |
| 602 | 596 | ||
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index f2d88d8f7a42..45d6bf632daa 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
| @@ -332,6 +332,9 @@ void do_rt_sigreturn(struct pt_regs *regs) | |||
| 332 | regs->tpc = tpc; | 332 | regs->tpc = tpc; |
| 333 | regs->tnpc = tnpc; | 333 | regs->tnpc = tnpc; |
| 334 | 334 | ||
| 335 | /* Prevent syscall restart. */ | ||
| 336 | pt_regs_clear_trap_type(regs); | ||
| 337 | |||
| 335 | sigdelsetmask(&set, ~_BLOCKABLE); | 338 | sigdelsetmask(&set, ~_BLOCKABLE); |
| 336 | spin_lock_irq(¤t->sighand->siglock); | 339 | spin_lock_irq(¤t->sighand->siglock); |
| 337 | current->blocked = set; | 340 | current->blocked = set; |
| @@ -515,7 +518,8 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
| 515 | siginfo_t info; | 518 | siginfo_t info; |
| 516 | int signr; | 519 | int signr; |
| 517 | 520 | ||
| 518 | if (pt_regs_is_syscall(regs)) { | 521 | if (pt_regs_is_syscall(regs) && |
| 522 | (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { | ||
| 519 | pt_regs_clear_trap_type(regs); | 523 | pt_regs_clear_trap_type(regs); |
| 520 | cookie.restart_syscall = 1; | 524 | cookie.restart_syscall = 1; |
| 521 | } else | 525 | } else |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 91f8d0826db1..9415d2c918c5 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
| @@ -268,6 +268,9 @@ void do_sigreturn32(struct pt_regs *regs) | |||
| 268 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); | 268 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); |
| 269 | regs->tstate |= psr_to_tstate_icc(psr); | 269 | regs->tstate |= psr_to_tstate_icc(psr); |
| 270 | 270 | ||
| 271 | /* Prevent syscall restart. */ | ||
| 272 | pt_regs_clear_trap_type(regs); | ||
| 273 | |||
| 271 | err |= __get_user(fpu_save, &sf->fpu_save); | 274 | err |= __get_user(fpu_save, &sf->fpu_save); |
| 272 | if (fpu_save) | 275 | if (fpu_save) |
| 273 | err |= restore_fpu_state32(regs, &sf->fpu_state); | 276 | err |= restore_fpu_state32(regs, &sf->fpu_state); |
| @@ -351,6 +354,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | |||
| 351 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); | 354 | regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); |
| 352 | regs->tstate |= psr_to_tstate_icc(psr); | 355 | regs->tstate |= psr_to_tstate_icc(psr); |
| 353 | 356 | ||
| 357 | /* Prevent syscall restart. */ | ||
| 358 | pt_regs_clear_trap_type(regs); | ||
| 359 | |||
| 354 | err |= __get_user(fpu_save, &sf->fpu_save); | 360 | err |= __get_user(fpu_save, &sf->fpu_save); |
| 355 | if (fpu_save) | 361 | if (fpu_save) |
| 356 | err |= restore_fpu_state32(regs, &sf->fpu_state); | 362 | err |= restore_fpu_state32(regs, &sf->fpu_state); |
