frv: split ret_from_fork, simplify kernel_thread() a lot
Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "local.h"
|
||||
|
||||
asmlinkage void ret_from_fork(void);
|
||||
asmlinkage void ret_from_kernel_thread(void);
|
||||
|
||||
#include <asm/pgalloc.h>
|
||||
|
||||
@@ -172,29 +173,21 @@ int copy_thread(unsigned long clone_flags,
|
||||
unsigned long usp, unsigned long topstk,
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *childregs0, *childregs, *regs0;
|
||||
struct pt_regs *childregs;
|
||||
|
||||
regs0 = __kernel_frame0_ptr;
|
||||
childregs0 = (struct pt_regs *)
|
||||
childregs = (struct pt_regs *)
|
||||
(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
|
||||
childregs = childregs0;
|
||||
|
||||
/* set up the userspace frame (the only place that the USP is stored) */
|
||||
*childregs0 = *regs0;
|
||||
*childregs = *regs;
|
||||
|
||||
childregs0->gr8 = 0;
|
||||
childregs0->sp = usp;
|
||||
childregs0->next_frame = NULL;
|
||||
childregs->sp = usp;
|
||||
childregs->next_frame = NULL;
|
||||
|
||||
/* set up the return kernel frame if called from kernel_thread() */
|
||||
if (regs != regs0) {
|
||||
childregs--;
|
||||
*childregs = *regs;
|
||||
childregs->sp = (unsigned long) childregs0;
|
||||
childregs->next_frame = childregs0;
|
||||
childregs->gr15 = (unsigned long) task_thread_info(p);
|
||||
childregs->gr29 = (unsigned long) p;
|
||||
}
|
||||
if (unlikely(!user_mode(regs)))
|
||||
p->thread.pc = (unsigned long) ret_from_kernel_thread;
|
||||
else
|
||||
p->thread.pc = (unsigned long) ret_from_fork;
|
||||
|
||||
p->set_child_tid = p->clear_child_tid = NULL;
|
||||
|
||||
@@ -203,8 +196,7 @@ int copy_thread(unsigned long clone_flags,
|
||||
p->thread.sp = (unsigned long) childregs;
|
||||
p->thread.fp = 0;
|
||||
p->thread.lr = 0;
|
||||
p->thread.pc = (unsigned long) ret_from_fork;
|
||||
p->thread.frame0 = childregs0;
|
||||
p->thread.frame0 = childregs;
|
||||
|
||||
/* the new TLS pointer is passed in as arg #5 to sys_clone() */
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
@@ -347,3 +339,13 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
|
||||
sizeof(current->thread.user->f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
|
||||
{
|
||||
struct pt_regs regs = {
|
||||
.gr8 = (unsigned long)arg;
|
||||
.gr9 = (unsigned long)fn;
|
||||
.psr = PSR_S;
|
||||
};
|
||||
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user