]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/s390/kernel/process.c
Merge tag 'firewire-update' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[karo-tx-linux.git] / arch / s390 / kernel / process.c
index f2dac9f0799dc04a5bb07c4529bf617e84e82d0c..688a3aad9c79d02a49702f729c3b418065c982e3 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kprobes.h>
 #include <linux/random.h>
 #include <linux/module.h>
+#include <linux/init_task.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/vtimer.h>
@@ -36,6 +37,9 @@
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
 
+/* FPU save area for the init task */
+__vector128 init_task_fpu_regs[__NUM_VXRS] __init_task_data;
+
 /*
  * Return saved PC of a blocked thread. used in kernel/sched.
  * resume in entry.S does not create a new stack frame, it
@@ -87,31 +91,29 @@ void arch_release_task_struct(struct task_struct *tsk)
 
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
+       size_t fpu_regs_size;
+
        *dst = *src;
 
-       /* Set up a new floating-point register save area */
-       dst->thread.fpu.fpc = 0;
-       dst->thread.fpu.flags = 0;      /* Always start with VX disabled */
-       dst->thread.fpu.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS,
-                                      GFP_KERNEL|__GFP_REPEAT);
-       if (!dst->thread.fpu.fprs)
+       /*
+        * If the vector extension is available, it is enabled for all tasks,
+        * and, thus, the FPU register save area must be allocated accordingly.
+        */
+       fpu_regs_size = MACHINE_HAS_VX ? sizeof(__vector128) * __NUM_VXRS
+                                      : sizeof(freg_t) * __NUM_FPRS;
+       dst->thread.fpu.regs = kzalloc(fpu_regs_size, GFP_KERNEL|__GFP_REPEAT);
+       if (!dst->thread.fpu.regs)
                return -ENOMEM;
 
        /*
         * Save the floating-point or vector register state of the current
-        * task.  The state is not saved for early kernel threads, for example,
-        * the init_task, which do not have an allocated save area.
-        * The CIF_FPU flag is set in any case to lazy clear or restore a saved
-        * state when switching to a different task or returning to user space.
+        * task and set the CIF_FPU flag to lazy restore the FPU register
+        * state when returning to user space.
         */
        save_fpu_regs();
        dst->thread.fpu.fpc = current->thread.fpu.fpc;
-       if (is_vx_task(current))
-               convert_vx_to_fp(dst->thread.fpu.fprs,
-                                current->thread.fpu.vxrs);
-       else
-               memcpy(dst->thread.fpu.fprs, current->thread.fpu.fprs,
-                      sizeof(freg_t) * __NUM_FPRS);
+       memcpy(dst->thread.fpu.regs, current->thread.fpu.regs, fpu_regs_size);
+
        return 0;
 }
 
@@ -169,7 +171,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
 
        /* Don't copy runtime instrumentation info */
        p->thread.ri_cb = NULL;
-       p->thread.ri_signum = 0;
        frame->childregs.psw.mask &= ~PSW_MASK_RI;
 
        /* Set a new TLS ?  */
@@ -199,7 +200,7 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
        save_fpu_regs();
        fpregs->fpc = current->thread.fpu.fpc;
        fpregs->pad = 0;
-       if (is_vx_task(current))
+       if (MACHINE_HAS_VX)
                convert_vx_to_fp((freg_t *)&fpregs->fprs,
                                 current->thread.fpu.vxrs);
        else