aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/include
diff options
context:
space:
mode:
authorVasily Gorbik2019-11-22 13:12:57 +0100
committerVasily Gorbik2019-11-30 10:52:45 +0100
commit7bcaad1f9fac889f5fcd1a383acf7e00d006da41 (patch)
treeaf2851175e748e5dbee515c9e7ab8369b43ffc00 /arch/s390/include
parent7579425777c0d802237e0d59ae395e8cf60723e1 (diff)
s390: avoid misusing CALL_ON_STACK for task stack setup
CALL_ON_STACK is intended to be used for temporary stack switching with potential return to the caller. When CALL_ON_STACK is misused to switch from nodat stack to task stack back_chain information would later lead stack unwinder from task stack into (per cpu) nodat stack which is reused for other purposes. This would yield confusing unwinding result or errors. To avoid that introduce CALL_ON_STACK_NORETURN to be used instead. It makes sure that back_chain is zeroed and unwinder finishes gracefully ending up at task pt_regs. Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/include')
-rw-r--r--arch/s390/include/asm/stacktrace.h11
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h
index bb854e33e460..4f3dd1c86c0d 100644
--- a/arch/s390/include/asm/stacktrace.h
+++ b/arch/s390/include/asm/stacktrace.h
@@ -124,4 +124,15 @@ struct stack_frame {
r2; \
})
+#define CALL_ON_STACK_NORETURN(fn, stack) \
+({ \
+ asm volatile( \
+ " la 15,0(%[_stack])\n" \
+ " xc %[_bc](8,15),%[_bc](15)\n" \
+ " brasl 14,%[_fn]\n" \
+ ::[_bc] "i" (offsetof(struct stack_frame, back_chain)), \
+ [_stack] "a" (stack), [_fn] "X" (fn)); \
+ BUG(); \
+})
+
#endif /* _ASM_S390_STACKTRACE_H */