From: Martin Schwidefsky 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 Signed-off-by: Andrew Morton --- 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 _