Commit 1094cc5c authored by Paul Mackerras's avatar Paul Mackerras

PPC32: Add a thread-pointer argument to the clone syscall, make a prepare_to_copy().

The thread-pointer argument gets copied to R2 in the child in copy_thread() if
the CLONE_SETTLS flag is set.  Adding a prepare_to_copy simplifies the copy_thread
logic since we don't have to do the extra copy of fpu/altivec state to the child.
parent cd9a1f5f
...@@ -320,6 +320,24 @@ release_thread(struct task_struct *t) ...@@ -320,6 +320,24 @@ release_thread(struct task_struct *t)
{ {
} }
/*
* This gets called before we allocate a new thread and copy
* the current task into it.
*/
void prepare_to_copy(struct task_struct *tsk)
{
struct pt_regs *regs = tsk->thread.regs;
if (regs == NULL)
return;
if (regs->msr & MSR_FP)
giveup_fpu(current);
#ifdef CONFIG_ALTIVEC
if (regs->msr & MSR_VEC)
giveup_altivec(current);
#endif /* CONFIG_ALTIVEC */
}
/* /*
* Copy a thread.. * Copy a thread..
*/ */
...@@ -348,6 +366,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -348,6 +366,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
} else { } else {
childregs->gpr[1] = usp; childregs->gpr[1] = usp;
p->thread.regs = childregs; p->thread.regs = childregs;
if (clone_flags & CLONE_SETTLS)
childregs->gpr[2] = childregs->gpr[6];
} }
childregs->gpr[3] = 0; /* Result from fork() */ childregs->gpr[3] = 0; /* Result from fork() */
sp -= STACK_FRAME_OVERHEAD; sp -= STACK_FRAME_OVERHEAD;
...@@ -367,29 +387,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -367,29 +387,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.ksp = sp; p->thread.ksp = sp;
kregs->nip = (unsigned long)ret_from_fork; kregs->nip = (unsigned long)ret_from_fork;
/*
* copy fpu info - assume lazy fpu switch now always
* -- Cort
*/
if (regs->msr & MSR_FP) {
giveup_fpu(current);
childregs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
}
memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));
p->thread.fpscr = current->thread.fpscr;
#ifdef CONFIG_ALTIVEC
/*
* copy altiVec info - assume lazy altiVec switch
* - kumar
*/
if (regs->msr & MSR_VEC)
giveup_altivec(current);
memcpy(&p->thread.vr, &current->thread.vr, sizeof(p->thread.vr));
p->thread.vscr = current->thread.vscr;
childregs->msr &= ~MSR_VEC;
#endif /* CONFIG_ALTIVEC */
p->thread.last_syscall = -1; p->thread.last_syscall = -1;
return 0; return 0;
...@@ -444,15 +441,17 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) ...@@ -444,15 +441,17 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
return put_user(val, (unsigned int *) adr); return put_user(val, (unsigned int *) adr);
} }
int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, int sys_clone(unsigned long clone_flags, unsigned long usp, int *parent_tidp,
void *child_threadptr, int *child_tidp, int p6,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct task_struct *p; struct task_struct *p;
CHECK_FULL_REGS(regs); CHECK_FULL_REGS(regs);
if (p2 == 0) if (usp == 0)
p2 = regs->gpr[1]; /* stack pointer for child */ usp = regs->gpr[1]; /* stack pointer for child */
p = do_fork(p1 & ~CLONE_IDLETASK, p2, regs, 0, (int *)p3, (int *)p4); p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0,
parent_tidp, child_tidp);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
......
...@@ -609,7 +609,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); ...@@ -609,7 +609,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
void release_thread(struct task_struct *); void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */ /* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0) extern void prepare_to_copy(struct task_struct *tsk);
/* /*
* Create a new kernel thread. * Create a new kernel thread.
......
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