{
        struct pt_regs * childregs;
        struct switch_stack * childstack, *stack;
-       unsigned long stack_offset, *retp;
+       unsigned long *retp;
 
-       stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
-       childregs = (struct pt_regs *) ((unsigned long) (p->thread_info) + stack_offset);
+       childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
 
        *childregs = *regs;
        childregs->d0 = 0;
        if (!p || p == current || p->state == TASK_RUNNING)
                return 0;
 
-       stack_page = (unsigned long)(p->thread_info);
+       stack_page = (unsigned long)task_stack_page(p);
        fp = ((struct switch_stack *)p->thread.ksp)->a6;
        do {
                if (fp < stack_page+sizeof(struct thread_info) ||