[S390] stacktrace bug.
authorChristian Borntraeger <cborntra@de.ibm.com>
Wed, 11 Oct 2006 13:31:52 +0000 (15:31 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 11 Oct 2006 13:31:52 +0000 (15:31 +0200)
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>
arch/s390/kernel/stacktrace.c

index d9428a0..0d14a47 100644 (file)
@@ -62,27 +62,26 @@ static inline unsigned long save_context_stack(struct stack_trace *trace,
 void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
 {
        register unsigned long sp asm ("15");
-       unsigned long orig_sp;
+       unsigned long orig_sp, new_sp;
 
-       sp &= PSW_ADDR_INSN;
-       orig_sp = sp;
+       orig_sp = sp & PSW_ADDR_INSN;
 
-       sp = save_context_stack(trace, &trace->skip, sp,
+       new_sp = save_context_stack(trace, &trace->skip, orig_sp,
                                S390_lowcore.panic_stack - PAGE_SIZE,
                                S390_lowcore.panic_stack);
-       if ((sp != orig_sp) && !trace->all_contexts)
+       if ((new_sp != orig_sp) && !trace->all_contexts)
                return;
-       sp = save_context_stack(trace, &trace->skip, sp,
+       new_sp = save_context_stack(trace, &trace->skip, new_sp,
                                S390_lowcore.async_stack - ASYNC_SIZE,
                                S390_lowcore.async_stack);
-       if ((sp != orig_sp) && !trace->all_contexts)
+       if ((new_sp != orig_sp) && !trace->all_contexts)
                return;
        if (task)
-               save_context_stack(trace, &trace->skip, sp,
+               save_context_stack(trace, &trace->skip, new_sp,
                                   (unsigned long) task_stack_page(task),
                                   (unsigned long) task_stack_page(task) + THREAD_SIZE);
        else
-               save_context_stack(trace, &trace->skip, sp,
+               save_context_stack(trace, &trace->skip, new_sp,
                                   S390_lowcore.thread_info,
                                   S390_lowcore.thread_info + THREAD_SIZE);
        return;