diff options
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 28ad9f4d8b94..f18fd9c15247 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -32,25 +32,22 @@ struct kmem_cache *task_xstate_cachep; | |||
32 | 32 | ||
33 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | 33 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
34 | { | 34 | { |
35 | int ret; | ||
36 | |||
35 | *dst = *src; | 37 | *dst = *src; |
36 | if (src->thread.xstate) { | 38 | if (fpu_allocated(&src->thread.fpu)) { |
37 | dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, | 39 | memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu)); |
38 | GFP_KERNEL); | 40 | ret = fpu_alloc(&dst->thread.fpu); |
39 | if (!dst->thread.xstate) | 41 | if (ret) |
40 | return -ENOMEM; | 42 | return ret; |
41 | WARN_ON((unsigned long)dst->thread.xstate & 15); | 43 | fpu_copy(&dst->thread.fpu, &src->thread.fpu); |
42 | memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); | ||
43 | } | 44 | } |
44 | return 0; | 45 | return 0; |
45 | } | 46 | } |
46 | 47 | ||
47 | void free_thread_xstate(struct task_struct *tsk) | 48 | void free_thread_xstate(struct task_struct *tsk) |
48 | { | 49 | { |
49 | if (tsk->thread.xstate) { | 50 | fpu_free(&tsk->thread.fpu); |
50 | kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); | ||
51 | tsk->thread.xstate = NULL; | ||
52 | } | ||
53 | |||
54 | WARN(tsk->thread.ds_ctx, "leaking DS context\n"); | 51 | WARN(tsk->thread.ds_ctx, "leaking DS context\n"); |
55 | } | 52 | } |
56 | 53 | ||