[S390] stacktrace bug.

The latest kernel 2.6.19-rc1 triggers a bug in the s390 specific stack
trace code when compiled with gcc 3.4.
This patch fixes the latest lock dependency validator code (2.6.19-rc1)
on s390 gcc 3.4. The variable sp was fixed to r15 (which is the stack
pointer in the s390 abi) and assigned new values to r15. Therefore,
gcc 3.4 assigns a new value to r15 and does not restore it on exit (r15
is supposed to be call save) - the kernel stack is broken. Avoid trouble
by not assigning any new value to sp (r15).

Signed-off-by: Christian Borntraeger <cborntra@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Christian Borntraeger and committed by Martin Schwidefsky 75e9de18 12975aef

+8 -9
+8 -9
arch/s390/kernel/stacktrace.c
··· 62 void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 63 { 64 register unsigned long sp asm ("15"); 65 - unsigned long orig_sp; 66 67 - sp &= PSW_ADDR_INSN; 68 - orig_sp = sp; 69 70 - sp = save_context_stack(trace, &trace->skip, sp, 71 S390_lowcore.panic_stack - PAGE_SIZE, 72 S390_lowcore.panic_stack); 73 - if ((sp != orig_sp) && !trace->all_contexts) 74 return; 75 - sp = save_context_stack(trace, &trace->skip, sp, 76 S390_lowcore.async_stack - ASYNC_SIZE, 77 S390_lowcore.async_stack); 78 - if ((sp != orig_sp) && !trace->all_contexts) 79 return; 80 if (task) 81 - save_context_stack(trace, &trace->skip, sp, 82 (unsigned long) task_stack_page(task), 83 (unsigned long) task_stack_page(task) + THREAD_SIZE); 84 else 85 - save_context_stack(trace, &trace->skip, sp, 86 S390_lowcore.thread_info, 87 S390_lowcore.thread_info + THREAD_SIZE); 88 return;
··· 62 void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 63 { 64 register unsigned long sp asm ("15"); 65 + unsigned long orig_sp, new_sp; 66 67 + orig_sp = sp & PSW_ADDR_INSN; 68 69 + new_sp = save_context_stack(trace, &trace->skip, orig_sp, 70 S390_lowcore.panic_stack - PAGE_SIZE, 71 S390_lowcore.panic_stack); 72 + if ((new_sp != orig_sp) && !trace->all_contexts) 73 return; 74 + new_sp = save_context_stack(trace, &trace->skip, new_sp, 75 S390_lowcore.async_stack - ASYNC_SIZE, 76 S390_lowcore.async_stack); 77 + if ((new_sp != orig_sp) && !trace->all_contexts) 78 return; 79 if (task) 80 + save_context_stack(trace, &trace->skip, new_sp, 81 (unsigned long) task_stack_page(task), 82 (unsigned long) task_stack_page(task) + THREAD_SIZE); 83 else 84 + save_context_stack(trace, &trace->skip, new_sp, 85 S390_lowcore.thread_info, 86 S390_lowcore.thread_info + THREAD_SIZE); 87 return;