
From: Martin Schwidefsky <schwidefsky@de.ibm.com>

The different stack frame layout for packed stacks broke cpu hotplug. 
Recreate the initial stack frame of the idle thread for offline cpus coming
back online.  Reenable interrupts after loading the initial registers.  In
addition this patch contains two more bug fixes: a typo for 64 bit
(__SMALL_STACK_SIZE vs.  __SMALL_STACK) and show_trace didn't show a trace
if for task == NULL.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/s390/kernel/entry.S       |    2 +-
 25-akpm/arch/s390/kernel/entry64.S     |    2 +-
 25-akpm/arch/s390/kernel/smp.c         |    8 +++++++-
 25-akpm/arch/s390/kernel/traps.c       |    4 ++--
 25-akpm/include/asm-s390/thread_info.h |    2 +-
 5 files changed, 12 insertions(+), 6 deletions(-)

diff -puN arch/s390/kernel/entry64.S~s390-packed-stack-vs-cpu-hotplug arch/s390/kernel/entry64.S
--- 25/arch/s390/kernel/entry64.S~s390-packed-stack-vs-cpu-hotplug	2004-09-03 22:35:47.552250608 -0700
+++ 25-akpm/arch/s390/kernel/entry64.S	2004-09-03 22:35:47.562249088 -0700
@@ -644,8 +644,8 @@ restart_int_handler:
         lctlg   %c0,%c15,0(%r10) # get new ctl regs
         lghi    %r10,__LC_AREGS_SAVE_AREA
         lam     %a0,%a15,0(%r10)
-        stosm   0(%r15),0x04           # now we can turn dat on
         lmg     %r6,%r15,__SF_GPRS(%r15) # load registers from clone
+        stosm   __SF_EMPTY(%r15),0x04    # now we can turn dat on
 	jg      start_secondary
 #else
 /*
diff -puN arch/s390/kernel/entry.S~s390-packed-stack-vs-cpu-hotplug arch/s390/kernel/entry.S
--- 25/arch/s390/kernel/entry.S~s390-packed-stack-vs-cpu-hotplug	2004-09-03 22:35:47.553250456 -0700
+++ 25-akpm/arch/s390/kernel/entry.S	2004-09-03 22:35:47.561249240 -0700
@@ -602,8 +602,8 @@ restart_int_handler:
         l       %r15,__LC_SAVE_AREA+60 # load ksp
         lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
         lam     %a0,%a15,__LC_AREGS_SAVE_AREA
-        stosm   0(%r15),0x04           # now we can turn dat on
         lm      %r6,%r15,__SF_GPRS(%r15) # load registers from clone
+        stosm   __SF_EMPTY(%r15),0x04    # now we can turn dat on
         basr    %r14,0
         l       %r14,restart_addr-.(%r14)
         br      %r14                   # branch to start_secondary
diff -puN arch/s390/kernel/smp.c~s390-packed-stack-vs-cpu-hotplug arch/s390/kernel/smp.c
--- 25/arch/s390/kernel/smp.c~s390-packed-stack-vs-cpu-hotplug	2004-09-03 22:35:47.554250304 -0700
+++ 25-akpm/arch/s390/kernel/smp.c	2004-09-03 22:35:47.563248936 -0700
@@ -637,6 +637,7 @@ __cpu_up(unsigned int cpu)
 {
 	struct task_struct *idle;
         struct _lowcore    *cpu_lowcore;
+	struct stack_frame *sf;
         sigp_ccode          ccode;
 	int                 curr_cpu;
 
@@ -660,9 +661,14 @@ __cpu_up(unsigned int cpu)
 
 	idle = current_set[cpu];
         cpu_lowcore = lowcore_ptr[cpu];
-	cpu_lowcore->save_area[15] = idle->thread.ksp;
 	cpu_lowcore->kernel_stack = (unsigned long)
 		idle->thread_info + (THREAD_SIZE);
+	sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
+				     - sizeof(struct pt_regs)
+				     - sizeof(struct stack_frame));
+	memset(sf, 0, sizeof(struct stack_frame));
+	sf->gprs[9] = (unsigned long) sf;
+	cpu_lowcore->save_area[15] = (unsigned long) sf;
 	__ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15);
 	__asm__ __volatile__("stam  0,15,0(%0)"
 			     : : "a" (&cpu_lowcore->access_regs_save_area)
diff -puN arch/s390/kernel/traps.c~s390-packed-stack-vs-cpu-hotplug arch/s390/kernel/traps.c
--- 25/arch/s390/kernel/traps.c~s390-packed-stack-vs-cpu-hotplug	2004-09-03 22:35:47.556250000 -0700
+++ 25-akpm/arch/s390/kernel/traps.c	2004-09-03 22:35:47.564248784 -0700
@@ -138,8 +138,8 @@ void show_trace(struct task_struct *task
 		__show_trace(sp, (unsigned long) task->thread_info,
 			     (unsigned long) task->thread_info + THREAD_SIZE);
 	else
-		__show_trace(sp, S390_lowcore.thread_info - THREAD_SIZE,
-			     S390_lowcore.thread_info);
+		__show_trace(sp, S390_lowcore.thread_info,
+			     S390_lowcore.thread_info + THREAD_SIZE);
 	printk("\n");
 }
 
diff -puN include/asm-s390/thread_info.h~s390-packed-stack-vs-cpu-hotplug include/asm-s390/thread_info.h
--- 25/include/asm-s390/thread_info.h~s390-packed-stack-vs-cpu-hotplug	2004-09-03 22:35:47.558249696 -0700
+++ 25-akpm/include/asm-s390/thread_info.h	2004-09-03 22:35:47.564248784 -0700
@@ -23,7 +23,7 @@
 #define ASYNC_ORDER  0
 #endif
 #else /* __s390x__ */
-#ifndef __SMALL_STACK_STACK
+#ifndef __SMALL_STACK
 #define THREAD_ORDER 2
 #define ASYNC_ORDER  2
 #else
_
