aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens2016-02-01 14:14:04 +0100
committerMartin Schwidefsky2016-02-10 09:25:21 +0100
commit66adce8f1f9f3bcd743a0e72c10aa850df8c5fa7 (patch)
tree4f439578bf730b056ccbdec3737421141bdd714d /arch
parentf6331aaccbd980a49bff1559d66abcbd46af5b0a (diff)
s390/stacktrace: save full stack traces
save_stack_trace() only saves the stack trace of the current context (interrupt or process context). This is different to what other architectures like x86 do, which save the full stack trace across different contexts. Also extract a __save_stack_trace() helper function which will be used by a follow on patch. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Tested-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kernel/stacktrace.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 75e6ea930692..e0fec2d8ac40 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -59,26 +59,29 @@ static unsigned long save_context_stack(struct stack_trace *trace,
}
}
-void save_stack_trace(struct stack_trace *trace)
+static void __save_stack_trace(struct stack_trace *trace, unsigned long sp)
{
- register unsigned long sp asm ("15");
- unsigned long orig_sp, new_sp, frame_size;
+ unsigned long new_sp, frame_size;
frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
- orig_sp = sp;
- new_sp = save_context_stack(trace, orig_sp,
+ new_sp = save_context_stack(trace, sp,
S390_lowcore.panic_stack + frame_size - PAGE_SIZE,
S390_lowcore.panic_stack + frame_size, 1);
- if (new_sp != orig_sp)
- return;
new_sp = save_context_stack(trace, new_sp,
S390_lowcore.async_stack + frame_size - ASYNC_SIZE,
S390_lowcore.async_stack + frame_size, 1);
- if (new_sp != orig_sp)
- return;
save_context_stack(trace, new_sp,
S390_lowcore.thread_info,
S390_lowcore.thread_info + THREAD_SIZE, 1);
+}
+
+void save_stack_trace(struct stack_trace *trace)
+{
+ register unsigned long r15 asm ("15");
+ unsigned long sp;
+
+ sp = r15;
+ __save_stack_trace(trace, sp);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}