diff options
author | Brian Gerst <brgerst@gmail.com> | 2009-12-09 12:34:40 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-12-10 18:55:26 -0500 |
commit | 3bd95dfb182969dc6d2a317c150e0df7107608d3 (patch) | |
tree | 8624969693d1bb51f06f85c35b7ac84ef41b9aeb /arch/x86/kernel/process_64.c | |
parent | fc380ceed7fe469728ea4acdbda4495ea943ee1c (diff) |
x86, 64-bit: Move kernel_thread to C
Prepare for merging with 32-bit.
Signed-off-by: Brian Gerst <brgerst@gmail.com>
LKML-Reference: <1260380084-3707-2-git-send-email-brgerst@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 83019f94b83d..92484c2130c6 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -59,8 +59,6 @@ asmlinkage extern void ret_from_fork(void); | |||
59 | DEFINE_PER_CPU(unsigned long, old_rsp); | 59 | DEFINE_PER_CPU(unsigned long, old_rsp); |
60 | static DEFINE_PER_CPU(unsigned char, is_idle); | 60 | static DEFINE_PER_CPU(unsigned char, is_idle); |
61 | 61 | ||
62 | unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; | ||
63 | |||
64 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); | 62 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); |
65 | 63 | ||
66 | void idle_notifier_register(struct notifier_block *n) | 64 | void idle_notifier_register(struct notifier_block *n) |
@@ -231,6 +229,35 @@ void show_regs(struct pt_regs *regs) | |||
231 | show_trace(NULL, regs, (void *)(regs + 1), regs->bp); | 229 | show_trace(NULL, regs, (void *)(regs + 1), regs->bp); |
232 | } | 230 | } |
233 | 231 | ||
232 | /* | ||
233 | * This gets run with %si containing the | ||
234 | * function to call, and %di containing | ||
235 | * the "args". | ||
236 | */ | ||
237 | extern void kernel_thread_helper(void); | ||
238 | |||
239 | /* | ||
240 | * Create a kernel thread | ||
241 | */ | ||
242 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
243 | { | ||
244 | struct pt_regs regs; | ||
245 | |||
246 | memset(®s, 0, sizeof(regs)); | ||
247 | |||
248 | regs.si = (unsigned long) fn; | ||
249 | regs.di = (unsigned long) arg; | ||
250 | |||
251 | regs.orig_ax = -1; | ||
252 | regs.ip = (unsigned long) kernel_thread_helper; | ||
253 | regs.cs = __KERNEL_CS; | ||
254 | regs.flags = X86_EFLAGS_IF; | ||
255 | |||
256 | /* Ok, create the new process.. */ | ||
257 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, ~0UL, ®s, 0, NULL, NULL); | ||
258 | } | ||
259 | EXPORT_SYMBOL(kernel_thread); | ||
260 | |||
234 | void release_thread(struct task_struct *dead_task) | 261 | void release_thread(struct task_struct *dead_task) |
235 | { | 262 | { |
236 | if (dead_task->mm) { | 263 | if (dead_task->mm) { |