alpha: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@ -259,33 +259,35 @@ alpha_vfork(struct pt_regs *regs)
|
||||
|
||||
/*
|
||||
* Copy an alpha thread..
|
||||
*
|
||||
* Note the "stack_offset" stuff: when returning to kernel mode, we need
|
||||
* to have some extra stack-space for the kernel stack that still exists
|
||||
* after the "ret_from_fork". When returning to user mode, we only want
|
||||
* the space needed by the syscall stack frame (ie "struct pt_regs").
|
||||
* Use the passed "regs" pointer to determine how much space we need
|
||||
* for a kernel fork().
|
||||
*/
|
||||
|
||||
int
|
||||
copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
unsigned long unused,
|
||||
unsigned long arg,
|
||||
struct task_struct * p, struct pt_regs * regs)
|
||||
{
|
||||
extern void ret_from_fork(void);
|
||||
extern void ret_from_kernel_thread(void);
|
||||
|
||||
struct thread_info *childti = task_thread_info(p);
|
||||
struct pt_regs * childregs;
|
||||
struct switch_stack * childstack, *stack;
|
||||
unsigned long stack_offset, settls;
|
||||
struct pt_regs *childregs = task_pt_regs(p);
|
||||
struct switch_stack *childstack, *stack;
|
||||
unsigned long settls;
|
||||
|
||||
stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
|
||||
if (!(regs->ps & 8))
|
||||
stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
|
||||
childregs = (struct pt_regs *)
|
||||
(stack_offset + PAGE_SIZE + task_stack_page(p));
|
||||
|
||||
childstack = ((struct switch_stack *) childregs) - 1;
|
||||
if (unlikely(!regs)) {
|
||||
/* kernel thread */
|
||||
memset(childstack, 0,
|
||||
sizeof(struct switch_stack) + sizeof(struct pt_regs));
|
||||
childstack->r26 = (unsigned long) ret_from_kernel_thread;
|
||||
childstack->r9 = usp; /* function */
|
||||
childstack->r10 = arg;
|
||||
childregs->hae = alpha_mv.hae_cache,
|
||||
childti->pcb.usp = 0;
|
||||
childti->pcb.ksp = (unsigned long) childstack;
|
||||
childti->pcb.flags = 1; /* set FEN, clear everything else */
|
||||
return 0;
|
||||
}
|
||||
*childregs = *regs;
|
||||
settls = regs->r20;
|
||||
childregs->r0 = 0;
|
||||
@ -293,7 +295,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
|
||||
regs->r20 = 0;
|
||||
stack = ((struct switch_stack *) regs) - 1;
|
||||
childstack = ((struct switch_stack *) childregs) - 1;
|
||||
*childstack = *stack;
|
||||
childstack->r26 = (unsigned long) ret_from_fork;
|
||||
childti->pcb.usp = usp;
|
||||
|
Reference in New Issue
Block a user