Skip to content

Commit ff340d2

Browse files
author
Martin Schwidefsky
committed
s390: add stack switch helper
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
1 parent 53c99bd commit ff340d2

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

arch/s390/include/asm/processor.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,55 @@ static inline unsigned short stap(void)
250250
return cpu_address;
251251
}
252252

253+
#define CALL_ARGS_0() \
254+
register unsigned long r2 asm("2")
255+
#define CALL_ARGS_1(arg1) \
256+
register unsigned long r2 asm("2") = (unsigned long)(arg1)
257+
#define CALL_ARGS_2(arg1, arg2) \
258+
CALL_ARGS_1(arg1); \
259+
register unsigned long r3 asm("3") = (unsigned long)(arg2)
260+
#define CALL_ARGS_3(arg1, arg2, arg3) \
261+
CALL_ARGS_2(arg1, arg2); \
262+
register unsigned long r4 asm("4") = (unsigned long)(arg3)
263+
#define CALL_ARGS_4(arg1, arg2, arg3, arg4) \
264+
CALL_ARGS_3(arg1, arg2, arg3); \
265+
register unsigned long r4 asm("5") = (unsigned long)(arg4)
266+
#define CALL_ARGS_5(arg1, arg2, arg3, arg4, arg5) \
267+
CALL_ARGS_4(arg1, arg2, arg3, arg4); \
268+
register unsigned long r4 asm("6") = (unsigned long)(arg5)
269+
270+
#define CALL_FMT_0
271+
#define CALL_FMT_1 CALL_FMT_0, "0" (r2)
272+
#define CALL_FMT_2 CALL_FMT_1, "d" (r3)
273+
#define CALL_FMT_3 CALL_FMT_2, "d" (r4)
274+
#define CALL_FMT_4 CALL_FMT_3, "d" (r5)
275+
#define CALL_FMT_5 CALL_FMT_4, "d" (r6)
276+
277+
#define CALL_CLOBBER_5 "0", "1", "14", "cc", "memory"
278+
#define CALL_CLOBBER_4 CALL_CLOBBER_5
279+
#define CALL_CLOBBER_3 CALL_CLOBBER_4, "5"
280+
#define CALL_CLOBBER_2 CALL_CLOBBER_3, "4"
281+
#define CALL_CLOBBER_1 CALL_CLOBBER_2, "3"
282+
#define CALL_CLOBBER_0 CALL_CLOBBER_1
283+
284+
#define CALL_ON_STACK(fn, stack, nr, args...) \
285+
({ \
286+
CALL_ARGS_##nr(args); \
287+
unsigned long prev; \
288+
\
289+
asm volatile( \
290+
" la %[_prev],0(15)\n" \
291+
" la 15,0(%[_stack])\n" \
292+
" stg %[_prev],%[_bc](15)\n" \
293+
" brasl 14,%[_fn]\n" \
294+
" la 15,0(%[_prev])\n" \
295+
: "+&d" (r2), [_prev] "=&a" (prev) \
296+
: [_stack] "a" (stack), \
297+
[_bc] "i" (offsetof(struct stack_frame, back_chain)), \
298+
[_fn] "X" (fn) CALL_FMT_##nr : CALL_CLOBBER_##nr); \
299+
r2; \
300+
})
301+
253302
/*
254303
* Give up the time slice of the virtual PU.
255304
*/

arch/s390/kernel/irq.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,7 @@ void do_softirq_own_stack(void)
172172
/* Check against async. stack address range. */
173173
new = S390_lowcore.async_stack;
174174
if (((new - old) >> (PAGE_SHIFT + THREAD_SIZE_ORDER)) != 0) {
175-
/* Need to switch to the async. stack. */
176-
new -= STACK_FRAME_OVERHEAD;
177-
((struct stack_frame *) new)->back_chain = old;
178-
asm volatile(" la 15,0(%0)\n"
179-
" brasl 14,__do_softirq\n"
180-
" la 15,0(%1)\n"
181-
: : "a" (new), "a" (old)
182-
: "0", "1", "2", "3", "4", "5", "14",
183-
"cc", "memory" );
175+
CALL_ON_STACK(__do_softirq, new, 0);
184176
} else {
185177
/* We are already on the async stack. */
186178
__do_softirq();

0 commit comments

Comments
 (0)