int copy_thread()

in kernel/process.c [33:71]


int copy_thread(unsigned long clone_flags,
		unsigned long usp,
		unsigned long kthread_arg,
		struct task_struct *p,
		unsigned long tls)
{
	struct switch_stack *childstack;
	struct pt_regs *childregs = task_pt_regs(p);

#ifdef CONFIG_CPU_HAS_FPU
	save_to_user_fp(&p->thread.user_fp);
#endif

	childstack = ((struct switch_stack *) childregs) - 1;
	memset(childstack, 0, sizeof(struct switch_stack));

	/* setup thread.sp for switch_to !!! */
	p->thread.sp = (unsigned long)childstack;

	if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
		memset(childregs, 0, sizeof(struct pt_regs));
		childstack->r15 = (unsigned long) ret_from_kernel_thread;
		childstack->r10 = kthread_arg;
		childstack->r9 = usp;
		childregs->sr = mfcr("psr");
	} else {
		*childregs = *(current_pt_regs());
		if (usp)
			childregs->usp = usp;
		if (clone_flags & CLONE_SETTLS)
			task_thread_info(p)->tp_value = childregs->tls
						      = tls;

		childregs->a0 = 0;
		childstack->r15 = (unsigned long) ret_from_fork;
	}

	return 0;
}