]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Signal fixes for x86-64
authorAndrew Morton <akpm@osdl.org>
Mon, 29 Dec 2003 13:50:32 +0000 (05:50 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 29 Dec 2003 13:50:32 +0000 (05:50 -0800)
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.

arch/x86_64/ia32/ia32_signal.c
arch/x86_64/kernel/signal.c

index a6642d5a8ddf3d67a601494fe429438ac25db553..ad6c74c98a3e9a6353c8ea43806e1dffbbe929d5 100644 (file)
@@ -173,6 +173,9 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsign
 {
        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
        printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
                sc, sc->err, sc->eip, sc->cs, sc->eflags);
index 6ae0e7077e09b59e01c1fafbd8f8d3636f9e806c..ecf0e46d74c56f25c38a84e8ed6d2351e38f3f54 100644 (file)
@@ -93,6 +93,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *p
 {
        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)
 
@@ -355,8 +357,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
                /* If so, check system call restarting.. */
                switch (regs->rax) {
                        case -ERESTART_RESTARTBLOCK:
-                               current_thread_info()->restart_block.fn = do_no_restart_syscall;
-                               /* FALL THROUGH */
                        case -ERESTARTNOHAND:
                                regs->rax = -EINTR;
                                break;
@@ -371,10 +371,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
                                regs->rax = regs->orig_rax;
                                regs->rip -= 2;
                }
-               if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK){
-                       regs->rax = __NR_restart_syscall;
-                       regs->rip -= 2;
-               }               
        }
 
 #ifdef CONFIG_IA32_EMULATION
@@ -453,6 +449,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                        regs->rax = regs->orig_rax;
                        regs->rip -= 2;
                }
+               if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) {
+                       regs->rax = __NR_restart_syscall;
+                       regs->rip -= 2;
+               }
        }
        return 0;
 }