Commit 73b2c325 authored by Linus Torvalds's avatar Linus Torvalds

Do x86 "kernel_thread()" explicitly by hand, instead of

using a system call from kernel space. 

This avoids one level of hidden code, and makes what happens
much more explicit (and speeds it up too, fwiw)
parent 1934cd65
...@@ -475,33 +475,43 @@ void show_regs(struct pt_regs * regs) ...@@ -475,33 +475,43 @@ void show_regs(struct pt_regs * regs)
show_trace(&regs->esp); show_trace(&regs->esp);
} }
/*
* This gets run with %ebx containing the
* function to call, and %edx containing
* the "args".
*/
extern void kernel_thread_helper(void);
__asm__(".align 4\n"
"kernel_thread_helper:\n\t"
"movl %edx,%eax\n\t"
"pushl %edx\n\t"
"call *%ebx\n\t"
"pushl %eax\n\t"
"call do_exit");
/* /*
* Create a kernel thread * Create a kernel thread
*/ */
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{ {
long retval, d0; struct task_struct *p;
struct pt_regs regs;
__asm__ __volatile__(
"movl %%esp,%%esi\n\t" memset(&regs, 0, sizeof(regs));
"int $0x80\n\t" /* Linux/i386 system call */
"cmpl %%esp,%%esi\n\t" /* child or parent? */ regs.ebx = (unsigned long) fn;
"je 1f\n\t" /* parent - jump */ regs.edx = (unsigned long) arg;
/* Load the argument into eax, and push it. That way, it does
* not matter whether the called function is compiled with regs.xds = __KERNEL_DS;
* -mregparm or not. */ regs.xes = __KERNEL_DS;
"movl %4,%%eax\n\t" regs.orig_eax = -1;
"pushl %%eax\n\t" regs.eip = (unsigned long) kernel_thread_helper;
"call *%5\n\t" /* call fn */ regs.xcs = __KERNEL_CS;
"movl %3,%0\n\t" /* exit */ regs.eflags = 0x286;
"int $0x80\n"
"1:\t" /* Ok, create the new process.. */
:"=&a" (retval), "=&S" (d0) p = do_fork(flags | CLONE_VM, 0, &regs, 0);
:"0" (__NR_clone), "i" (__NR_exit), return IS_ERR(p) ? PTR_ERR(p) : p->pid;
"r" (arg), "r" (fn),
"b" (flags | CLONE_VM)
: "memory");
return retval;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment