aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/process.c')
-rw-r--r--arch/sh/kernel/process.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 077e06e1a88..81add9b9ea6 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -2,6 +2,32 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/sched.h> 3#include <linux/sched.h>
4 4
5struct kmem_cache *task_xstate_cachep = NULL;
6unsigned int xstate_size;
7
8int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
9{
10 *dst = *src;
11
12 if (src->thread.xstate) {
13 dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
14 GFP_KERNEL);
15 if (!dst->thread.xstate)
16 return -ENOMEM;
17 memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
18 }
19
20 return 0;
21}
22
23void free_thread_xstate(struct task_struct *tsk)
24{
25 if (tsk->thread.xstate) {
26 kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
27 tsk->thread.xstate = NULL;
28 }
29}
30
5#if THREAD_SHIFT < PAGE_SHIFT 31#if THREAD_SHIFT < PAGE_SHIFT
6static struct kmem_cache *thread_info_cache; 32static struct kmem_cache *thread_info_cache;
7 33
@@ -20,6 +46,7 @@ struct thread_info *alloc_thread_info(struct task_struct *tsk)
20 46
21void free_thread_info(struct thread_info *ti) 47void free_thread_info(struct thread_info *ti)
22{ 48{
49 free_thread_xstate(ti->task);
23 kmem_cache_free(thread_info_cache, ti); 50 kmem_cache_free(thread_info_cache, ti);
24} 51}
25 52
@@ -41,6 +68,33 @@ struct thread_info *alloc_thread_info(struct task_struct *tsk)
41 68
42void free_thread_info(struct thread_info *ti) 69void free_thread_info(struct thread_info *ti)
43{ 70{
71 free_thread_xstate(ti->task);
44 free_pages((unsigned long)ti, THREAD_SIZE_ORDER); 72 free_pages((unsigned long)ti, THREAD_SIZE_ORDER);
45} 73}
46#endif /* THREAD_SHIFT < PAGE_SHIFT */ 74#endif /* THREAD_SHIFT < PAGE_SHIFT */
75
76void arch_task_cache_init(void)
77{
78 if (!xstate_size)
79 return;
80
81 task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size,
82 __alignof__(union thread_xstate),
83 SLAB_PANIC | SLAB_NOTRACK, NULL);
84}
85
86#ifdef CONFIG_SH_FPU_EMU
87# define HAVE_SOFTFP 1
88#else
89# define HAVE_SOFTFP 0
90#endif
91
92void init_thread_xstate(void)
93{
94 if (boot_cpu_data.flags & CPU_HAS_FPU)
95 xstate_size = sizeof(struct sh_fpu_hard_struct);
96 else if (HAVE_SOFTFP)
97 xstate_size = sizeof(struct sh_fpu_soft_struct);
98 else
99 xstate_size = 0;
100}