int init_fpu(struct task_struct *tsk) { if (tsk_used_math(tsk)) { if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current) unlazy_fpu(tsk, task_pt_regs(tsk)); return 0; } /* * Memory allocation at the first usage of the FPU and other state. */ if (!tsk->thread.xstate) { tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep, GFP_KERNEL); if (!tsk->thread.xstate) return -ENOMEM; } if (boot_cpu_data.flags & CPU_HAS_FPU) { struct sh_fpu_hard_struct *fp = &tsk->thread.xstate->hardfpu; memset(fp, 0, xstate_size); fp->fpscr = FPSCR_INIT; } else { struct sh_fpu_soft_struct *fp = &tsk->thread.xstate->softfpu; memset(fp, 0, xstate_size); fp->fpscr = FPSCR_INIT; } set_stopped_child_used_math(tsk); return 0; }
static void init_fp_ctx(struct task_struct *target) { /* If FP has been used then the target already has context */ if (tsk_used_math(target)) return; /* Begin with data registers set to all 1s... */ memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr)); /* FCSR has been preset by `mips_set_personality_nan'. */ /* * Record that the target has "used" math, such that the context * just initialised, and any modifications made by the caller, * aren't discarded. */ set_stopped_child_used_math(target); }
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { int ret; *dst = *src; if (fpu_allocated(&src->thread.fpu)) { memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu)); ret = fpu_alloc(&dst->thread.fpu); if (ret) return ret; fpu_copy(&dst->thread.fpu, &src->thread.fpu); } #ifdef CONFIG_X86_EARLYMIC if (dst->thread.fpu.state) { /* * No need to set this flag ? it should be inherited from the * parent thread since the threadinfo is copied from the * parent in setup_thread_stack() */ set_stopped_child_used_math(dst); /* * Simulate FPU DNA * Undo the effects of unlazy_fpu in prepare_to_copy() */ preempt_disable(); clts(); #ifdef CONFIG_ML1OM __math_state_restore(); #else restore_mask_regs(); stts(); #endif preempt_enable(); } #endif return 0; }