diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2016-01-31 14:23:30 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-02-10 09:25:20 +0100 |
commit | 665ca9187c4087736fa57b0e00bcf33ea601fb6f (patch) | |
tree | f88c4d75b615a3749a9ab2ac82dcce6ef66e83e2 | |
parent | 2178cbc68f3602dc0b5949b9be2c8383ad3d93ef (diff) | |
download | lwn-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.c | 4 |
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); |