summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2016-01-31 14:23:30 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-02-10 09:25:20 +0100
commit665ca9187c4087736fa57b0e00bcf33ea601fb6f (patch)
treef88c4d75b615a3749a9ab2ac82dcce6ef66e83e2
parent2178cbc68f3602dc0b5949b9be2c8383ad3d93ef (diff)
downloadlwn-665ca9187c4087736fa57b0e00bcf33ea601fb6f.tar.gz
lwn-665ca9187c4087736fa57b0e00bcf33ea601fb6f.zip
s390/stacktrace: fix save_stack_trace_tsk() for current task
The function save_stack_trace_tsk() did not consider that it can be used for tsk == current, for which the current stack pointer obviously cannot be found in the thread structure. Fix this and get the stack pointer with an inline assembly. This fixes e.g. the output of "cat /proc/self/stack". Before: [<0000000000000000>] (null) [<ffffffffffffffff>] 0xffffffffffffffff After: [<000000000011b3ee>] save_stack_trace_tsk+0x56/0x98 [<0000000000366cde>] proc_pid_stack+0xae/0x108 [<00000000003636f0>] proc_single_show+0x70/0xc0 [<0000000000311fbc>] seq_read+0xcc/0x448 [<00000000002e7716>] __vfs_read+0x36/0x100 [<00000000002e872e>] vfs_read+0x76/0x130 [<00000000002e975e>] SyS_read+0x66/0xd8 [<000000000089490e>] system_call+0xd6/0x264 [<ffffffffffffffff>] 0xffffffffffffffff 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>
-rw-r--r--arch/s390/kernel/stacktrace.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 5acba3cb7220..dd484c75be56 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -86,6 +86,10 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
unsigned long sp, low, high;
sp = tsk->thread.ksp;
+ if (tsk == current) {
+ /* Get current stack pointer. */
+ asm volatile("la %0,0(15)" : "=a" (sp));
+ }
low = (unsigned long) task_stack_page(tsk);
high = (unsigned long) task_pt_regs(tsk);
save_context_stack(trace, sp, low, high, 0);