]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/kernel/misc_64.S
Merge branch 'linus' into core/urgent
[linux-2.6-omap-h63xx.git] / arch / powerpc / kernel / misc_64.S
index 942951e7658643f7d8a1bd33ebcad449d4f6d5de..3053fe5c62f2a67694d430187df900495c19531b 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
@@ -506,6 +508,39 @@ _GLOBAL(giveup_altivec)
 
 #endif /* CONFIG_ALTIVEC */
 
+#ifdef CONFIG_VSX
+/*
+ * __giveup_vsx(tsk)
+ * Disable VSX for the task given as the argument.
+ * Does NOT save vsx registers.
+ * Enables the VSX for use in the kernel on return.
+ */
+_GLOBAL(__giveup_vsx)
+       mfmsr   r5
+       oris    r5,r5,MSR_VSX@h
+       mtmsrd  r5                      /* enable use of VSX now */
+       isync
+
+       cmpdi   0,r3,0
+       beqlr-                          /* if no previous owner, done */
+       addi    r3,r3,THREAD            /* want THREAD of task */
+       ld      r5,PT_REGS(r3)
+       cmpdi   0,r5,0
+       beq     1f
+       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r3,MSR_VSX@h
+       andc    r4,r4,r3                /* disable VSX for previous task */
+       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+       li      r5,0
+       ld      r4,last_task_used_vsx@got(r2)
+       std     r5,0(r4)
+#endif /* CONFIG_SMP */
+       blr
+
+#endif /* CONFIG_VSX */
+
 /* kexec_wait(phys_cpu)
  *
  * wait for the flag to change, indicating this kernel is going away but