powerpc: Fix error path in kernel_thread function
authorJosh Poimboeuf <jpoimboe@us.ibm.com>
Tue, 7 Oct 2008 06:10:03 +0000 (06:10 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 10 Oct 2008 04:55:18 +0000 (15:55 +1100)
The powerpc 32-bit and 64-bit kernel_thread functions don't properly
propagate errors being returned by the clone syscall.  (In the case of
error, the syscall exit code returns a positive errno in r3 and sets
the CR0[SO] bit.)

This patch fixes that by negating r3 if CR0[SO] is set after the syscall.

Signed-off-by: Josh Poimboeuf <jpoimboe@us.ibm.com>
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S

index e9c8ab6..6a9b4bf 100644 (file)
@@ -900,8 +900,10 @@ _GLOBAL(kernel_thread)
        li      r4,0            /* new sp (unused) */
        li      r0,__NR_clone
        sc
-       cmpwi   0,r3,0          /* parent or child? */
-       bne     1f              /* return if parent */
+       bns+    1f              /* did system call indicate error? */
+       neg     r3,r3           /* if so, make return code negative */
+1:     cmpwi   0,r3,0          /* parent or child? */
+       bne     2f              /* return if parent */
        li      r0,0            /* make top-level stack frame */
        stwu    r0,-16(r1)
        mtlr    r30             /* fn addr in lr */
@@ -911,7 +913,7 @@ _GLOBAL(kernel_thread)
        li      r0,__NR_exit    /* exit if function returns */
        li      r3,0
        sc
-1:     lwz     r30,8(r1)
+2:     lwz     r30,8(r1)
        lwz     r31,12(r1)
        addi    r1,r1,16
        blr
index 4dd70cf..3053fe5 100644 (file)
@@ -426,8 +426,10 @@ _GLOBAL(kernel_thread)
        li      r4,0            /* new sp (unused) */
        li      r0,__NR_clone
        sc
-       cmpdi   0,r3,0          /* parent or child? */
-       bne     1f              /* return if parent */
+       bns+    1f              /* did system call indicate error? */
+       neg     r3,r3           /* if so, make return code negative */
+1:     cmpdi   0,r3,0          /* parent or child? */
+       bne     2f              /* return if parent */
        li      r0,0
        stdu    r0,-STACK_FRAME_OVERHEAD(r1)
        ld      r2,8(r29)
@@ -438,7 +440,7 @@ _GLOBAL(kernel_thread)
        li      r0,__NR_exit    /* exit after child exits */
         li     r3,0
        sc
-1:     addi    r1,r1,STACK_FRAME_OVERHEAD      
+2:     addi    r1,r1,STACK_FRAME_OVERHEAD
        ld      r29,-24(r1)
        ld      r30,-16(r1)
        blr