Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75e9de18 authored by Christian Borntraeger's avatar Christian Borntraeger Committed by Martin Schwidefsky
Browse files

[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: default avatarChristian Borntraeger <cborntra@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 12975aef
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -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;