Commit ca981c9f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Signal fixes for x86-64

From: Andi Kleen <ak@muc.de>

Merge signal race fixes from i386 to x86-64.

Fix a bug in system call restart, noted by John Blackwood.
parent 2988d8dd
...@@ -173,6 +173,9 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsign ...@@ -173,6 +173,9 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsign
{ {
unsigned int err = 0; unsigned int err = 0;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
#if DEBUG_SIG #if DEBUG_SIG
printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n", printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
sc, sc->err, sc->eip, sc->cs, sc->eflags); sc, sc->err, sc->eip, sc->cs, sc->eflags);
......
...@@ -93,6 +93,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *p ...@@ -93,6 +93,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *p
{ {
unsigned int err = 0; unsigned int err = 0;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
#define COPY(x) err |= __get_user(regs->x, &sc->x) #define COPY(x) err |= __get_user(regs->x, &sc->x)
...@@ -355,8 +357,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -355,8 +357,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
/* If so, check system call restarting.. */ /* If so, check system call restarting.. */
switch (regs->rax) { switch (regs->rax) {
case -ERESTART_RESTARTBLOCK: case -ERESTART_RESTARTBLOCK:
current_thread_info()->restart_block.fn = do_no_restart_syscall;
/* FALL THROUGH */
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
regs->rax = -EINTR; regs->rax = -EINTR;
break; break;
...@@ -371,10 +371,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -371,10 +371,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
regs->rax = regs->orig_rax; regs->rax = regs->orig_rax;
regs->rip -= 2; regs->rip -= 2;
} }
if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK){
regs->rax = __NR_restart_syscall;
regs->rip -= 2;
}
} }
#ifdef CONFIG_IA32_EMULATION #ifdef CONFIG_IA32_EMULATION
...@@ -453,6 +449,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -453,6 +449,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
regs->rax = regs->orig_rax; regs->rax = regs->orig_rax;
regs->rip -= 2; regs->rip -= 2;
} }
if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) {
regs->rax = __NR_restart_syscall;
regs->rip -= 2;
}
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment