diff options
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 87 |
1 files changed, 8 insertions, 79 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ef6a8456f719..b644e1c765dc 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -66,15 +66,13 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
66 | { | 66 | { |
67 | int ret; | 67 | int ret; |
68 | 68 | ||
69 | unlazy_fpu(src); | ||
70 | |||
71 | *dst = *src; | 69 | *dst = *src; |
72 | if (fpu_allocated(&src->thread.fpu)) { | 70 | if (fpu_allocated(&src->thread.fpu)) { |
73 | memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu)); | 71 | memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu)); |
74 | ret = fpu_alloc(&dst->thread.fpu); | 72 | ret = fpu_alloc(&dst->thread.fpu); |
75 | if (ret) | 73 | if (ret) |
76 | return ret; | 74 | return ret; |
77 | fpu_copy(&dst->thread.fpu, &src->thread.fpu); | 75 | fpu_copy(dst, src); |
78 | } | 76 | } |
79 | return 0; | 77 | return 0; |
80 | } | 78 | } |
@@ -97,16 +95,6 @@ void arch_task_cache_init(void) | |||
97 | SLAB_PANIC | SLAB_NOTRACK, NULL); | 95 | SLAB_PANIC | SLAB_NOTRACK, NULL); |
98 | } | 96 | } |
99 | 97 | ||
100 | static inline void drop_fpu(struct task_struct *tsk) | ||
101 | { | ||
102 | /* | ||
103 | * Forget coprocessor state.. | ||
104 | */ | ||
105 | tsk->fpu_counter = 0; | ||
106 | clear_fpu(tsk); | ||
107 | clear_used_math(); | ||
108 | } | ||
109 | |||
110 | /* | 98 | /* |
111 | * Free current thread data structures etc.. | 99 | * Free current thread data structures etc.. |
112 | */ | 100 | */ |
@@ -163,7 +151,13 @@ void flush_thread(void) | |||
163 | 151 | ||
164 | flush_ptrace_hw_breakpoint(tsk); | 152 | flush_ptrace_hw_breakpoint(tsk); |
165 | memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); | 153 | memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); |
166 | drop_fpu(tsk); | 154 | drop_init_fpu(tsk); |
155 | /* | ||
156 | * Free the FPU state for non xsave platforms. They get reallocated | ||
157 | * lazily at the first use. | ||
158 | */ | ||
159 | if (!use_eager_fpu()) | ||
160 | free_thread_xstate(tsk); | ||
167 | } | 161 | } |
168 | 162 | ||
169 | static void hard_disable_TSC(void) | 163 | static void hard_disable_TSC(void) |
@@ -299,71 +293,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
299 | } | 293 | } |
300 | 294 | ||
301 | /* | 295 | /* |
302 | * This gets run with %si containing the | ||
303 | * function to call, and %di containing | ||
304 | * the "args". | ||
305 | */ | ||
306 | extern void kernel_thread_helper(void); | ||
307 | |||
308 | /* | ||
309 | * Create a kernel thread | ||
310 | */ | ||
311 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
312 | { | ||
313 | struct pt_regs regs; | ||
314 | |||
315 | memset(®s, 0, sizeof(regs)); | ||
316 | |||
317 | regs.si = (unsigned long) fn; | ||
318 | regs.di = (unsigned long) arg; | ||
319 | |||
320 | #ifdef CONFIG_X86_32 | ||
321 | regs.ds = __USER_DS; | ||
322 | regs.es = __USER_DS; | ||
323 | regs.fs = __KERNEL_PERCPU; | ||
324 | regs.gs = __KERNEL_STACK_CANARY; | ||
325 | #else | ||
326 | regs.ss = __KERNEL_DS; | ||
327 | #endif | ||
328 | |||
329 | regs.orig_ax = -1; | ||
330 | regs.ip = (unsigned long) kernel_thread_helper; | ||
331 | regs.cs = __KERNEL_CS | get_kernel_rpl(); | ||
332 | regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1; | ||
333 | |||
334 | /* Ok, create the new process.. */ | ||
335 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
336 | } | ||
337 | EXPORT_SYMBOL(kernel_thread); | ||
338 | |||
339 | /* | ||
340 | * sys_execve() executes a new program. | ||
341 | */ | ||
342 | long sys_execve(const char __user *name, | ||
343 | const char __user *const __user *argv, | ||
344 | const char __user *const __user *envp, struct pt_regs *regs) | ||
345 | { | ||
346 | long error; | ||
347 | char *filename; | ||
348 | |||
349 | filename = getname(name); | ||
350 | error = PTR_ERR(filename); | ||
351 | if (IS_ERR(filename)) | ||
352 | return error; | ||
353 | error = do_execve(filename, argv, envp, regs); | ||
354 | |||
355 | #ifdef CONFIG_X86_32 | ||
356 | if (error == 0) { | ||
357 | /* Make sure we don't return using sysenter.. */ | ||
358 | set_thread_flag(TIF_IRET); | ||
359 | } | ||
360 | #endif | ||
361 | |||
362 | putname(filename); | ||
363 | return error; | ||
364 | } | ||
365 | |||
366 | /* | ||
367 | * Idle related variables and functions | 296 | * Idle related variables and functions |
368 | */ | 297 | */ |
369 | unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; | 298 | unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; |