1 #include <linux/mm.h> 2 #include <linux/kernel.h> 3 #include <linux/slab.h> 4 #include <linux/sched.h> 5 #include <linux/export.h> 6 #include <linux/stackprotector.h> 7 8 struct kmem_cache *task_xstate_cachep = NULL; 9 unsigned int xstate_size; 10 11 #ifdef CONFIG_CC_STACKPROTECTOR 12 unsigned long __stack_chk_guard __read_mostly; 13 EXPORT_SYMBOL(__stack_chk_guard); 14 #endif 15 16 /* 17 * this gets called so that we can store lazy state into memory and copy the 18 * current task into the new thread. 19 */ 20 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 21 { 22 #ifdef CONFIG_SUPERH32 23 unlazy_fpu(src, task_pt_regs(src)); 24 #endif 25 *dst = *src; 26 27 if (src->thread.xstate) { 28 dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, 29 GFP_KERNEL); 30 if (!dst->thread.xstate) 31 return -ENOMEM; 32 memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); 33 } 34 35 return 0; 36 } 37 38 void free_thread_xstate(struct task_struct *tsk) 39 { 40 if (tsk->thread.xstate) { 41 kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); 42 tsk->thread.xstate = NULL; 43 } 44 } 45 46 void arch_release_task_struct(struct task_struct *tsk) 47 { 48 free_thread_xstate(tsk); 49 } 50 51 void arch_task_cache_init(void) 52 { 53 if (!xstate_size) 54 return; 55 56 task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size, 57 __alignof__(union thread_xstate), 58 SLAB_PANIC | SLAB_NOTRACK, NULL); 59 } 60 61 #ifdef CONFIG_SH_FPU_EMU 62 # define HAVE_SOFTFP 1 63 #else 64 # define HAVE_SOFTFP 0 65 #endif 66 67 void __cpuinit init_thread_xstate(void) 68 { 69 if (boot_cpu_data.flags & CPU_HAS_FPU) 70 xstate_size = sizeof(struct sh_fpu_hard_struct); 71 else if (HAVE_SOFTFP) 72 xstate_size = sizeof(struct sh_fpu_soft_struct); 73 else 74 xstate_size = 0; 75 } 76