Skip to content

Commit 67147e9

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390/stack: fix possible register corruption with stack switch helper
The CALL_ON_STACK macro is used to call a C function from inline assembly, and therefore must consider the C ABI, which says that only registers 6-13, and 15 are non-volatile (restored by the called function). The inline assembly incorrectly marks all registers used to pass parameters to the called function as read-only input operands, instead of operands that are read and written to. This might result in register corruption depending on usage, compiler, and compile options. Fix this by marking all operands used to pass parameters as read/write operands. To keep the code simple even register 6, if used, is marked as read-write operand. Fixes: ff340d2 ("s390: add stack switch helper") Cc: <[email protected]> # 4.20 Reviewed-by: Vasily Gorbik <[email protected]> Signed-off-by: Heiko Carstens <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 9e3d62d commit 67147e9

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

arch/s390/include/asm/stacktrace.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,16 @@ struct stack_frame {
9191
CALL_ARGS_4(arg1, arg2, arg3, arg4); \
9292
register unsigned long r4 asm("6") = (unsigned long)(arg5)
9393

94-
#define CALL_FMT_0 "=&d" (r2) :
95-
#define CALL_FMT_1 "+&d" (r2) :
96-
#define CALL_FMT_2 CALL_FMT_1 "d" (r3),
97-
#define CALL_FMT_3 CALL_FMT_2 "d" (r4),
98-
#define CALL_FMT_4 CALL_FMT_3 "d" (r5),
99-
#define CALL_FMT_5 CALL_FMT_4 "d" (r6),
94+
/*
95+
* To keep this simple mark register 2-6 as being changed (volatile)
96+
* by the called function, even though register 6 is saved/nonvolatile.
97+
*/
98+
#define CALL_FMT_0 "=&d" (r2)
99+
#define CALL_FMT_1 "+&d" (r2)
100+
#define CALL_FMT_2 CALL_FMT_1, "+&d" (r3)
101+
#define CALL_FMT_3 CALL_FMT_2, "+&d" (r4)
102+
#define CALL_FMT_4 CALL_FMT_3, "+&d" (r5)
103+
#define CALL_FMT_5 CALL_FMT_4, "+&d" (r6)
100104

101105
#define CALL_CLOBBER_5 "0", "1", "14", "cc", "memory"
102106
#define CALL_CLOBBER_4 CALL_CLOBBER_5
@@ -118,7 +122,7 @@ struct stack_frame {
118122
" brasl 14,%[_fn]\n" \
119123
" la 15,0(%[_prev])\n" \
120124
: [_prev] "=&a" (prev), CALL_FMT_##nr \
121-
[_stack] "R" (stack), \
125+
: [_stack] "R" (stack), \
122126
[_bc] "i" (offsetof(struct stack_frame, back_chain)), \
123127
[_frame] "d" (frame), \
124128
[_fn] "X" (fn) : CALL_CLOBBER_##nr); \

0 commit comments

Comments
 (0)