From: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>

encapsulates the rest of arch-dependent operations with thread_info access. 
Two new helpers - setup_thread_stack() and end_of_stack().  For normal case
the former consists of copying thread_info of parent to new thread_info and
the latter returns pointer immediately past the end of thread_info.

Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 include/linux/sched.h |   11 +++++++++++
 kernel/fork.c         |    3 +--
 kernel/sched.c        |    4 ++--
 3 files changed, 14 insertions(+), 4 deletions(-)

diff -puN include/linux/sched.h~m68k-introduce-setup_thread_stack-end_of_stack include/linux/sched.h
--- devel/include/linux/sched.h~m68k-introduce-setup_thread_stack-end_of_stack	2005-09-07 20:11:04.000000000 -0700
+++ devel-akpm/include/linux/sched.h	2005-09-07 20:11:04.000000000 -0700
@@ -1184,6 +1184,17 @@ static inline void task_unlock(struct ta
 
 #define task_thread_info(task) (task)->thread_info
 
+static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
+{
+	*task_thread_info(p) = *task_thread_info(org);
+	task_thread_info(p)->task = p;
+}
+
+static inline unsigned long *end_of_stack(struct task_struct *p)
+{
+	return (unsigned long *)(p->thread_info + 1);
+}
+
 /* set thread flags in other task's structures
  * - see asm/thread_info.h for TIF_xxxx flags available
  */
diff -puN kernel/fork.c~m68k-introduce-setup_thread_stack-end_of_stack kernel/fork.c
--- devel/kernel/fork.c~m68k-introduce-setup_thread_stack-end_of_stack	2005-09-07 20:11:04.000000000 -0700
+++ devel-akpm/kernel/fork.c	2005-09-07 20:11:04.000000000 -0700
@@ -169,10 +169,9 @@ static struct task_struct *dup_task_stru
 		return NULL;
 	}
 
-	*ti = *orig->thread_info;
 	*tsk = *orig;
 	tsk->thread_info = ti;
-	ti->task = tsk;
+	setup_thread_stack(tsk, orig);
 
 	/* One for us, one for whoever does the "release_task()" (usually parent) */
 	atomic_set(&tsk->usage,2);
diff -puN kernel/sched.c~m68k-introduce-setup_thread_stack-end_of_stack kernel/sched.c
--- devel/kernel/sched.c~m68k-introduce-setup_thread_stack-end_of_stack	2005-09-07 20:11:04.000000000 -0700
+++ devel-akpm/kernel/sched.c	2005-09-07 20:11:04.000000000 -0700
@@ -4336,10 +4336,10 @@ static void show_task(task_t *p)
 #endif
 #ifdef CONFIG_DEBUG_STACK_USAGE
 	{
-		unsigned long *n = (unsigned long *) (p->thread_info+1);
+		unsigned long *n = end_of_stack(p);
 		while (!*n)
 			n++;
-		free = (unsigned long) n - (unsigned long)(p->thread_info+1);
+		free = (unsigned long)n - (unsigned long)end_of_stack(p);
 	}
 #endif
 	printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
_