diff options
Diffstat (limited to 'arch/blackfin/kernel/process.c')
-rw-r--r-- | arch/blackfin/kernel/process.c | 98 |
1 files changed, 21 insertions, 77 deletions
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index bb1cc721fcf..3e16ad9b0a9 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -102,40 +102,6 @@ void cpu_idle(void) } /* - * This gets run with P1 containing the - * function to call, and R1 containing - * the "args". Note P0 is clobbered on the way here. - */ -void kernel_thread_helper(void); -__asm__(".section .text\n" - ".align 4\n" - "_kernel_thread_helper:\n\t" - "\tsp += -12;\n\t" - "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.r1 = (unsigned long)arg; - regs.p1 = (unsigned long)fn; - regs.pc = (unsigned long)kernel_thread_helper; - regs.orig_p0 = -1; - /* Set bit 2 to tell ret_from_fork we should be returning to kernel - mode. */ - regs.ipend = 0x8002; - __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):); - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, - NULL); -} -EXPORT_SYMBOL(kernel_thread); - -/* * Do necessary setup to start up a newly executed thread. * * pass the data segment into user programs if it exists, @@ -161,70 +127,48 @@ void flush_thread(void) { } -asmlinkage int bfin_vfork(struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, - NULL); -} - -asmlinkage int bfin_clone(struct pt_regs *regs) +asmlinkage int bfin_clone(unsigned long clone_flags, unsigned long newsp) { - unsigned long clone_flags; - unsigned long newsp; - #ifdef __ARCH_SYNC_CORE_DCACHE if (current->nr_cpus_allowed == num_possible_cpus()) set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id())); #endif - - /* syscall2 puts clone_flags in r0 and usp in r1 */ - clone_flags = regs->r0; - newsp = regs->r1; - if (!newsp) - newsp = rdusp(); - else + if (newsp) newsp -= 12; - return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); + return do_fork(clone_flags, newsp, 0, NULL, NULL); } int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long topstk, - struct task_struct *p, struct pt_regs *regs) + struct task_struct *p) { struct pt_regs *childregs; + unsigned long *v; childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; - *childregs = *regs; - childregs->r0 = 0; + v = ((unsigned long *)childregs) - 2; + if (unlikely(p->flags & PF_KTHREAD)) { + memset(childregs, 0, sizeof(struct pt_regs)); + v[0] = usp; + v[1] = topstk; + childregs->orig_p0 = -1; + childregs->ipend = 0x8000; + __asm__ __volatile__("%0 = syscfg;":"=da"(childregs->syscfg):); + p->thread.usp = 0; + } else { + *childregs = *current_pt_regs(); + childregs->r0 = 0; + p->thread.usp = usp ? : rdusp(); + v[0] = v[1] = 0; + } - p->thread.usp = usp; - p->thread.ksp = (unsigned long)childregs; + p->thread.ksp = (unsigned long)v; p->thread.pc = (unsigned long)ret_from_fork; return 0; } -/* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(const char __user *name, - const char __user *const __user *argv, - const char __user *const __user *envp) -{ - int error; - struct filename *filename; - struct pt_regs *regs = (struct pt_regs *)((&name) + 6); - - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - return error; - error = do_execve(filename->name, argv, envp, regs); - putname(filename); - return error; -} - unsigned long get_wchan(struct task_struct *p) { unsigned long fp, pc; |