xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 915fea04f9320d0f4ab6ecbb6bf759eebcd2c41d)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
24bfc86ceSHeiko Carstens/*
34bfc86ceSHeiko Carstens *    S390 low-level entry points.
44bfc86ceSHeiko Carstens *
54bfc86ceSHeiko Carstens *    Copyright IBM Corp. 1999, 2012
64bfc86ceSHeiko Carstens *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
74bfc86ceSHeiko Carstens *		 Hartmut Penner (hp@de.ibm.com),
84bfc86ceSHeiko Carstens *		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
94bfc86ceSHeiko Carstens *		 Heiko Carstens <heiko.carstens@de.ibm.com>
104bfc86ceSHeiko Carstens */
114bfc86ceSHeiko Carstens
124bfc86ceSHeiko Carstens#include <linux/init.h>
134bfc86ceSHeiko Carstens#include <linux/linkage.h>
14b058661aSMartin Schwidefsky#include <asm/alternative-asm.h>
154bfc86ceSHeiko Carstens#include <asm/processor.h>
164bfc86ceSHeiko Carstens#include <asm/cache.h>
17dc24b7b4SHendrik Brueckner#include <asm/dwarf.h>
184bfc86ceSHeiko Carstens#include <asm/errno.h>
194bfc86ceSHeiko Carstens#include <asm/ptrace.h>
204bfc86ceSHeiko Carstens#include <asm/thread_info.h>
214bfc86ceSHeiko Carstens#include <asm/asm-offsets.h>
224bfc86ceSHeiko Carstens#include <asm/unistd.h>
234bfc86ceSHeiko Carstens#include <asm/page.h>
244bfc86ceSHeiko Carstens#include <asm/sigp.h>
254bfc86ceSHeiko Carstens#include <asm/irq.h>
269977e886SHendrik Brueckner#include <asm/vx-insn.h>
2783abeffbSHendrik Brueckner#include <asm/setup.h>
2883abeffbSHendrik Brueckner#include <asm/nmi.h>
29711f5df7SAl Viro#include <asm/export.h>
306dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h>
314bfc86ceSHeiko Carstens
324bfc86ceSHeiko Carstens__PT_R0      =	__PT_GPRS
334bfc86ceSHeiko Carstens__PT_R1      =	__PT_GPRS + 8
344bfc86ceSHeiko Carstens__PT_R2      =	__PT_GPRS + 16
354bfc86ceSHeiko Carstens__PT_R3      =	__PT_GPRS + 24
364bfc86ceSHeiko Carstens__PT_R4      =	__PT_GPRS + 32
374bfc86ceSHeiko Carstens__PT_R5      =	__PT_GPRS + 40
384bfc86ceSHeiko Carstens__PT_R6      =	__PT_GPRS + 48
394bfc86ceSHeiko Carstens__PT_R7      =	__PT_GPRS + 56
404bfc86ceSHeiko Carstens__PT_R8      =	__PT_GPRS + 64
414bfc86ceSHeiko Carstens__PT_R9      =	__PT_GPRS + 72
424bfc86ceSHeiko Carstens__PT_R10     =	__PT_GPRS + 80
434bfc86ceSHeiko Carstens__PT_R11     =	__PT_GPRS + 88
444bfc86ceSHeiko Carstens__PT_R12     =	__PT_GPRS + 96
454bfc86ceSHeiko Carstens__PT_R13     =	__PT_GPRS + 104
464bfc86ceSHeiko Carstens__PT_R14     =	__PT_GPRS + 112
474bfc86ceSHeiko Carstens__PT_R15     =	__PT_GPRS + 120
484bfc86ceSHeiko Carstens
493a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER
504bfc86ceSHeiko CarstensSTACK_SIZE  = 1 << STACK_SHIFT
514bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
524bfc86ceSHeiko Carstens
53e5b98199SMartin Schwidefsky_LPP_OFFSET	= __LC_LPP
54e5b98199SMartin Schwidefsky
55ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
564bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
57ce3dc447SMartin Schwidefsky	tml	%r15,STACK_SIZE - CONFIG_STACK_GUARD
584bfc86ceSHeiko Carstens	lghi	%r14,\savearea
594bfc86ceSHeiko Carstens	jz	stack_overflow
604bfc86ceSHeiko Carstens#endif
614bfc86ceSHeiko Carstens	.endm
624bfc86ceSHeiko Carstens
63ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
64ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
65ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
66ce3dc447SMartin Schwidefsky	nill	%r14,0x10000 - STACK_SIZE
67ce3dc447SMartin Schwidefsky	oill	%r14,STACK_INIT
68ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
69ce3dc447SMartin Schwidefsky	je	\oklabel
70ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
71ce3dc447SMartin Schwidefsky	je	\oklabel
72b61b1595SSven Schnelle	clg	%r14,__LC_MCCK_STACK
73b61b1595SSven Schnelle	je	\oklabel
74ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
75ce3dc447SMartin Schwidefsky	je	\oklabel
76ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
77ce3dc447SMartin Schwidefsky	je	\oklabel
78ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
79ce3dc447SMartin Schwidefsky	j	stack_overflow
80ce3dc447SMartin Schwidefsky#else
81ce3dc447SMartin Schwidefsky	j	\oklabel
82ce3dc447SMartin Schwidefsky#endif
83ce3dc447SMartin Schwidefsky	.endm
84ce3dc447SMartin Schwidefsky
854bfc86ceSHeiko Carstens	.macro STCK savearea
8678f65709SHeiko Carstens	ALTERNATIVE ".insn	s,0xb2050000,\savearea", \
8778f65709SHeiko Carstens		    ".insn	s,0xb27c0000,\savearea", 25
884bfc86ceSHeiko Carstens	.endm
894bfc86ceSHeiko Carstens
9083abeffbSHendrik Brueckner	/*
9183abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
9283abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
9383abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
9483abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
9583abeffbSHendrik Brueckner	 * instruction.
9683abeffbSHendrik Brueckner	 */
9783abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
9883abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
9983abeffbSHendrik Brueckner			.if (\mask & 0xff)
10083abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
10183abeffbSHendrik Brueckner			.endif
10283abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
10383abeffbSHendrik Brueckner			.exitm
10483abeffbSHendrik Brueckner		.endif
10583abeffbSHendrik Brueckner		.ifeq \mask
10683abeffbSHendrik Brueckner			.error "Mask must not be zero"
10783abeffbSHendrik Brueckner		.endif
10883abeffbSHendrik Brueckner		off = \size - \bytepos - 1
10983abeffbSHendrik Brueckner		tm	off+\addr, \mask
11083abeffbSHendrik Brueckner	.endm
11183abeffbSHendrik Brueckner
112d768bd89SMartin Schwidefsky	.macro BPOFF
113b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
114d768bd89SMartin Schwidefsky	.endm
115d768bd89SMartin Schwidefsky
116d768bd89SMartin Schwidefsky	.macro BPON
117b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
118d768bd89SMartin Schwidefsky	.endm
119d768bd89SMartin Schwidefsky
1206b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
121b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
122b058661aSMartin Schwidefsky		    "", 82
1236b73044bSMartin Schwidefsky	.endm
1246b73044bSMartin Schwidefsky
1256b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1266b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
127b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
128b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
1296b73044bSMartin Schwidefsky	.endm
1306b73044bSMartin Schwidefsky
131d35925b3SAlexander Gordeev	/*
132d35925b3SAlexander Gordeev	 * The CHKSTG macro jumps to the provided label in case the
133d35925b3SAlexander Gordeev	 * machine check interruption code reports one of unrecoverable
134d35925b3SAlexander Gordeev	 * storage errors:
135d35925b3SAlexander Gordeev	 * - Storage error uncorrected
136d35925b3SAlexander Gordeev	 * - Storage key error uncorrected
137d35925b3SAlexander Gordeev	 * - Storage degradation with Failing-storage-address validity
138d35925b3SAlexander Gordeev	 */
139d35925b3SAlexander Gordeev	.macro CHKSTG errlabel
140d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR)
141d35925b3SAlexander Gordeev	jnz	\errlabel
142d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD
143d35925b3SAlexander Gordeev	jz	oklabel\@
144d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR
145d35925b3SAlexander Gordeev	jnz	\errlabel
146d35925b3SAlexander Gordeevoklabel\@:
147d35925b3SAlexander Gordeev	.endm
148d35925b3SAlexander Gordeev
149b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM)
150b5415c8fSAlexander Gordeev	/*
151b5415c8fSAlexander Gordeev	 * The OUTSIDE macro jumps to the provided label in case the value
152b5415c8fSAlexander Gordeev	 * in the provided register is outside of the provided range. The
153b5415c8fSAlexander Gordeev	 * macro is useful for checking whether a PSW stored in a register
154b5415c8fSAlexander Gordeev	 * pair points inside or outside of a block of instructions.
155b5415c8fSAlexander Gordeev	 * @reg: register to check
156b5415c8fSAlexander Gordeev	 * @start: start of the range
157b5415c8fSAlexander Gordeev	 * @end: end of the range
158b5415c8fSAlexander Gordeev	 * @outside_label: jump here if @reg is outside of [@start..@end)
159b5415c8fSAlexander Gordeev	 */
160b5415c8fSAlexander Gordeev	.macro OUTSIDE reg,start,end,outside_label
161b5415c8fSAlexander Gordeev	lgr	%r14,\reg
162b5415c8fSAlexander Gordeev	larl	%r13,\start
163b5415c8fSAlexander Gordeev	slgr	%r14,%r13
164b5415c8fSAlexander Gordeev	lghi	%r13,\end - \start
165b5415c8fSAlexander Gordeev	clgr	%r14,%r13
166b5415c8fSAlexander Gordeev	jhe	\outside_label
167b5415c8fSAlexander Gordeev	.endm
168fbbdfca5SAlexander Gordeev
169fbbdfca5SAlexander Gordeev	.macro SIEEXIT
170fbbdfca5SAlexander Gordeev	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
171fbbdfca5SAlexander Gordeev	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
172fbbdfca5SAlexander Gordeev	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
173fbbdfca5SAlexander Gordeev	larl	%r9,sie_exit			# skip forward to sie_exit
174fbbdfca5SAlexander Gordeev	.endm
175b5415c8fSAlexander Gordeev#endif
176b5415c8fSAlexander Gordeev
1776dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
17833ea0487SSven Schnelle	GEN_BR_THUNK %r14,%r13
179f19fbd5eSMartin Schwidefsky
1804bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
18146210c44SHeiko Carstens.Ldummy:
18246210c44SHeiko Carstens	/*
18356e62a73SSven Schnelle	 * This nop exists only in order to avoid that __bpon starts at
18446210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
18546210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
18646210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
18756e62a73SSven Schnelle	 * With the added nop in between the __bpon symbol is unique
18846210c44SHeiko Carstens	 * again.
18946210c44SHeiko Carstens	 */
19046210c44SHeiko Carstens	nop	0
1914bfc86ceSHeiko Carstens
192d768bd89SMartin SchwidefskyENTRY(__bpon)
193d768bd89SMartin Schwidefsky	.globl __bpon
194d768bd89SMartin Schwidefsky	BPON
1956dd85fbbSMartin Schwidefsky	BR_EX	%r14
19626a374aeSMartin SchwidefskyENDPROC(__bpon)
197d768bd89SMartin Schwidefsky
1984bfc86ceSHeiko Carstens/*
1994bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2004bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2014bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2024bfc86ceSHeiko Carstens * Returns:
2034bfc86ceSHeiko Carstens *  gpr2 = prev
2044bfc86ceSHeiko Carstens */
2054bfc86ceSHeiko CarstensENTRY(__switch_to)
2064bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2073241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2083241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2099fed920eSVasily Gorbik	llill	%r5,STACK_INIT
2103241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2119fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
2129fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
2134bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2144bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2153241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2163241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2173241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2184bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
219e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2206dd85fbbSMartin Schwidefsky	BR_EX	%r14
22126a374aeSMartin SchwidefskyENDPROC(__switch_to)
2224bfc86ceSHeiko Carstens
223d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
224d0fc4107SMartin Schwidefsky/*
225d0fc4107SMartin Schwidefsky * sie64a calling convention:
226d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
227d0fc4107SMartin Schwidefsky * %r3 guest register save area
228d0fc4107SMartin Schwidefsky */
229d0fc4107SMartin SchwidefskyENTRY(sie64a)
230d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2316b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
23292fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
23392fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
23492fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
23592fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
236d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
237d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
238d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
239d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
240d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
241d0fc4107SMartin Schwidefsky.Lsie_gmap:
24292fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
243d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
244d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
245d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
24683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
247d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
24892fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
249c929500dSQingFeng Hao.Lsie_entry:
250d0fc4107SMartin Schwidefsky	sie	0(%r14)
251d768bd89SMartin Schwidefsky	BPOFF
25292fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
253d0fc4107SMartin Schwidefsky.Lsie_skip:
254d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
25587d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
256d0fc4107SMartin Schwidefsky.Lsie_done:
257d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
258c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
259c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
260c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
261c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
262c0e7bb38SChristian Borntraeger.Lrewind_pad6:
263c0e7bb38SChristian Borntraeger	nopr	7
264c0e7bb38SChristian Borntraeger.Lrewind_pad4:
265c0e7bb38SChristian Borntraeger	nopr	7
266c0e7bb38SChristian Borntraeger.Lrewind_pad2:
267c0e7bb38SChristian Borntraeger	nopr	7
268d0fc4107SMartin Schwidefsky	.globl sie_exit
269d0fc4107SMartin Schwidefskysie_exit:
27092fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
271d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2727041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2737041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2747041d281SMartin Schwidefsky	xgr	%r3,%r3
2757041d281SMartin Schwidefsky	xgr	%r4,%r4
2767041d281SMartin Schwidefsky	xgr	%r5,%r5
277d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
27892fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
2796dd85fbbSMartin Schwidefsky	BR_EX	%r14
280d0fc4107SMartin Schwidefsky.Lsie_fault:
281d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
28292fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
283d0fc4107SMartin Schwidefsky	j	sie_exit
284d0fc4107SMartin Schwidefsky
285c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
286c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
287c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
288d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
28926a374aeSMartin SchwidefskyENDPROC(sie64a)
290711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
291711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
292d0fc4107SMartin Schwidefsky#endif
293d0fc4107SMartin Schwidefsky
2944bfc86ceSHeiko Carstens/*
2954bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
2967b7735c5SChristian Borntraeger * are entered with interrupts disabled.
2974bfc86ceSHeiko Carstens */
2984bfc86ceSHeiko Carstens
2994bfc86ceSHeiko CarstensENTRY(system_call)
30056e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
3014bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
302d768bd89SMartin Schwidefsky	BPOFF
30356e62a73SSven Schnelle	lghi	%r14,0
3044bfc86ceSHeiko Carstens.Lsysc_per:
30587d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
30656e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
3074bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3089365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
30956e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
31056e62a73SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
311d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
312d3f46896SChristian Borntraeger	xgr	%r0,%r0
31356e62a73SSven Schnelle	xgr	%r1,%r1
31456e62a73SSven Schnelle	xgr	%r4,%r4
31556e62a73SSven Schnelle	xgr	%r5,%r5
31656e62a73SSven Schnelle	xgr	%r6,%r6
31756e62a73SSven Schnelle	xgr	%r7,%r7
31856e62a73SSven Schnelle	xgr	%r8,%r8
31956e62a73SSven Schnelle	xgr	%r9,%r9
32056e62a73SSven Schnelle	xgr	%r10,%r10
32156e62a73SSven Schnelle	xgr	%r11,%r11
32256e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
323af9ad822SSven Schnelle	mvc	__PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
32456e62a73SSven Schnelle	lgr	%r3,%r14
32556e62a73SSven Schnelle	brasl	%r14,__do_syscall
32687d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
32756e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3286b73044bSMartin Schwidefsky	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
32956e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3304bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3310b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
33226a374aeSMartin SchwidefskyENDPROC(system_call)
3334bfc86ceSHeiko Carstens
3344bfc86ceSHeiko Carstens#
3354bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3364bfc86ceSHeiko Carstens#
3374bfc86ceSHeiko CarstensENTRY(ret_from_fork)
33856e62a73SSven Schnelle	lgr	%r3,%r11
33956e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
34056e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
34156e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
34256e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
34356e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
34456e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
34556e62a73SSven Schnelle	b	__LC_RETURN_LPSWE
34626a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
34726a374aeSMartin Schwidefsky
3484bfc86ceSHeiko Carstens/*
3494bfc86ceSHeiko Carstens * Program check handler routine
3504bfc86ceSHeiko Carstens */
3514bfc86ceSHeiko Carstens
3524bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
35356e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
354d768bd89SMartin Schwidefsky	BPOFF
3554bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
35656e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
35756e62a73SSven Schnelle	lghi	%r10,0
3584bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
35987d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
36087d59863SHeiko Carstens	jno	.Lpgm_skip_asce
36187d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
36256e62a73SSven Schnelle	j	3f			# -> fault in user space
36387d59863SHeiko Carstens.Lpgm_skip_asce:
364d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3650a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
366b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f
367fbbdfca5SAlexander Gordeev	SIEEXIT
36856e62a73SSven Schnelle	lghi	%r10,_PIF_GUEST_FAULT
369d0fc4107SMartin Schwidefsky#endif
3700b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
3710b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
3724bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
3734bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
3740b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
3754bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
37656e62a73SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 4f
37756e62a73SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
37856e62a73SSven Schnelle3:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3794bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
38056e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
38156e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
38256e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3834bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
38456e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
38556e62a73SSven Schnelle	stmg	%r8,%r9,__PT_PSW(%r11)
38656e62a73SSven Schnelle
3877041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
3887041d281SMartin Schwidefsky	xgr	%r0,%r0
3897041d281SMartin Schwidefsky	xgr	%r1,%r1
3907041d281SMartin Schwidefsky	xgr	%r3,%r3
3917041d281SMartin Schwidefsky	xgr	%r4,%r4
3927041d281SMartin Schwidefsky	xgr	%r5,%r5
3937041d281SMartin Schwidefsky	xgr	%r6,%r6
3947041d281SMartin Schwidefsky	xgr	%r7,%r7
39556e62a73SSven Schnelle	lgr	%r2,%r11
39656e62a73SSven Schnelle	brasl	%r14,__do_pgm_check
39756e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user space?
39856e62a73SSven Schnelle	jno	.Lpgm_exit_kernel
39956e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
40056e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
4010cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
40256e62a73SSven Schnelle.Lpgm_exit_kernel:
40356e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
40456e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
4050cd9b723SHeiko Carstens	b	__LC_RETURN_LPSWE
4064bfc86ceSHeiko Carstens
4074bfc86ceSHeiko Carstens#
4084bfc86ceSHeiko Carstens# single stepped system call
4094bfc86ceSHeiko Carstens#
4104bfc86ceSHeiko Carstens.Lpgm_svcper:
4114bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
4124bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
4134bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
41456e62a73SSven Schnelle	lghi	%r14,1
4150b0ed657SSven Schnelle	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per
41626a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
4174bfc86ceSHeiko Carstens
4184bfc86ceSHeiko Carstens/*
41956e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4204bfc86ceSHeiko Carstens */
42156e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
42256e62a73SSven SchnelleENTRY(\name)
4234bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
42456e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
425d768bd89SMartin Schwidefsky	BPOFF
4264bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
427d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
42856e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
429b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
430b0d31159SSven Schnelle	jnz	1f
431b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
432b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,0f
433fbbdfca5SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
434fbbdfca5SAlexander Gordeev	SIEEXIT
435b0d31159SSven Schnelle#endif
436b0d31159SSven Schnelle0:	CHECK_STACK __LC_SAVE_AREA_ASYNC
437b0d31159SSven Schnelle	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
438b0d31159SSven Schnelle	j	2f
439b0d31159SSven Schnelle1:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
440b0d31159SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
441b0d31159SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
442b74e409eSVasily Gorbik2:	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
443b74e409eSVasily Gorbik	la	%r11,STACK_FRAME_OVERHEAD(%r15)
4444bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4457041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4467041d281SMartin Schwidefsky	xgr	%r0,%r0
4477041d281SMartin Schwidefsky	xgr	%r1,%r1
4487041d281SMartin Schwidefsky	xgr	%r3,%r3
4497041d281SMartin Schwidefsky	xgr	%r4,%r4
4507041d281SMartin Schwidefsky	xgr	%r5,%r5
4517041d281SMartin Schwidefsky	xgr	%r6,%r6
4527041d281SMartin Schwidefsky	xgr	%r7,%r7
4537041d281SMartin Schwidefsky	xgr	%r10,%r10
454ca1f4d70SSven Schnelle	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
4554bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
4564bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
45756e62a73SSven Schnelle	tm	%r8,0x0001		# coming from user space?
45856e62a73SSven Schnelle	jno	1f
45987d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
46056e62a73SSven Schnelle1:	lgr	%r2,%r11		# pass pointer to pt_regs
46156e62a73SSven Schnelle	brasl	%r14,\handler
4624bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
46356e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
46456e62a73SSven Schnelle	jno	2f
46587d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
4666b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4674bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
46856e62a73SSven Schnelle2:	lmg	%r0,%r15,__PT_R0(%r11)
4690b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
47056e62a73SSven SchnelleENDPROC(\name)
47156e62a73SSven Schnelle.endm
4724bfc86ceSHeiko Carstens
47356e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
47456e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
4754bfc86ceSHeiko Carstens
4764bfc86ceSHeiko Carstens/*
4770b0ed657SSven Schnelle * Load idle PSW.
4784bfc86ceSHeiko Carstens */
4794bfc86ceSHeiko CarstensENTRY(psw_idle)
480a994eddbSVasily Gorbik	stg	%r14,(__SF_GPRS+8*8)(%r15)
4814bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
48256e62a73SSven Schnelle	larl	%r1,psw_idle_exit
4834bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
48472d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
48572d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
48672d38b19SMartin Schwidefsky	ltgr	%r1,%r1
48772d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
48856e62a73SSven Schnelle	.insn	rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
48972d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
490419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
491d768bd89SMartin Schwidefsky	BPON
4924bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
4934bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
4944bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
49556e62a73SSven Schnelle.globl psw_idle_exit
49656e62a73SSven Schnellepsw_idle_exit:
4976dd85fbbSMartin Schwidefsky	BR_EX	%r14
49826a374aeSMartin SchwidefskyENDPROC(psw_idle)
4994bfc86ceSHeiko Carstens
500b5510d9bSHendrik Brueckner/*
5014bfc86ceSHeiko Carstens * Machine check handler routines
5024bfc86ceSHeiko Carstens */
5034bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
5044bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
505d768bd89SMartin Schwidefsky	BPOFF
5063037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
5073037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
5083037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
509d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
5104bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
51183abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
5124bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
5133037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
5143037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
5153037a52fSMartin Schwidefsky	la	%r14,4095
5163037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
5173037a52fSMartin Schwidefsky	ptlb
5185fa2ea07SAlexander Gordeev	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5194bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
52083abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5214bfc86ceSHeiko Carstens	jo	3f
52256e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
52356e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5244bfc86ceSHeiko Carstens	jl	1f
5254bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5264bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5274bfc86ceSHeiko Carstens	jl	2f
5284bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5294bfc86ceSHeiko Carstens2:	spt	0(%r14)
5304bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5313037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5323037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5333037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
534d35925b3SAlexander Gordeev	jnz	6f
5353037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5363037a52fSMartin Schwidefsky	jno	.Lmcck_panic
537b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
538d35925b3SAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,6f
539d35925b3SAlexander Gordeev	OUTSIDE	%r9,.Lsie_entry,.Lsie_skip,4f
54020232b18SAlexander Gordeev	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
541d35925b3SAlexander Gordeev	j	5f
542d35925b3SAlexander Gordeev4:	CHKSTG	.Lmcck_panic
543d35925b3SAlexander Gordeev5:	larl	%r14,.Lstosm_tmp
544d35925b3SAlexander Gordeev	stosm	0(%r14),0x04		# turn dat on, keep irqs off
545d35925b3SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
546fbbdfca5SAlexander Gordeev	SIEEXIT
547b61b1595SSven Schnelle	j	.Lmcck_stack
548e2c13d64SAlexander Gordeev#endif
549d35925b3SAlexander Gordeev6:	CHKSTG	.Lmcck_panic
550d35925b3SAlexander Gordeev	larl	%r14,.Lstosm_tmp
551d35925b3SAlexander Gordeev	stosm	0(%r14),0x04		# turn dat on, keep irqs off
552d35925b3SAlexander Gordeev	tmhh	%r8,0x0001		# interrupting from user ?
553d35925b3SAlexander Gordeev	jz	.Lmcck_stack
554b0d31159SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
555b61b1595SSven Schnelle.Lmcck_stack:
556b61b1595SSven Schnelle	lg	%r15,__LC_MCCK_STACK
557b61b1595SSven Schnelle	la	%r11,STACK_FRAME_OVERHEAD(%r15)
55826521412SSven Schnelle	stctg	%c1,%c1,__PT_CR1(%r11)
559b61b1595SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
560b61b1595SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5614bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5624bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5637041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5647041d281SMartin Schwidefsky	xgr	%r0,%r0
5657041d281SMartin Schwidefsky	xgr	%r1,%r1
5667041d281SMartin Schwidefsky	xgr	%r3,%r3
5677041d281SMartin Schwidefsky	xgr	%r4,%r4
5687041d281SMartin Schwidefsky	xgr	%r5,%r5
5697041d281SMartin Schwidefsky	xgr	%r6,%r6
5707041d281SMartin Schwidefsky	xgr	%r7,%r7
5717041d281SMartin Schwidefsky	xgr	%r10,%r10
5724bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
5734bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
5744bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
5754bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5764bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5774bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
5780b0ed657SSven Schnelle	cghi	%r2,0
5790b0ed657SSven Schnelle	je	.Lmcck_return
5804bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
5814bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
5824bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
5834bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
5844bfc86ceSHeiko Carstens	lgr	%r15,%r1
5854bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
5864bfc86ceSHeiko Carstens.Lmcck_return:
58787d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
5884bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
5894bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
5904bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
5914bfc86ceSHeiko Carstens	jno	0f
5926b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
5934bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
5944bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
5950b38b5e1SSven Schnelle	b	__LC_RETURN_MCCK_LPSWE
5964bfc86ceSHeiko Carstens
5974bfc86ceSHeiko Carstens.Lmcck_panic:
5987f6dc8d4SAlexander Gordeev	/*
5997f6dc8d4SAlexander Gordeev	 * Iterate over all possible CPU addresses in the range 0..0xffff
6007f6dc8d4SAlexander Gordeev	 * and stop each CPU using signal processor. Use compare and swap
6017f6dc8d4SAlexander Gordeev	 * to allow just one CPU-stopper and prevent concurrent CPUs from
6027f6dc8d4SAlexander Gordeev	 * stopping each other while leaving the others running.
6037f6dc8d4SAlexander Gordeev	 */
6047f6dc8d4SAlexander Gordeev	lhi	%r5,0
6057f6dc8d4SAlexander Gordeev	lhi	%r6,1
6067f6dc8d4SAlexander Gordeev	larl	%r7,.Lstop_lock
6077f6dc8d4SAlexander Gordeev	cs	%r5,%r6,0(%r7)		# single CPU-stopper only
6087f6dc8d4SAlexander Gordeev	jnz	4f
6097f6dc8d4SAlexander Gordeev	larl	%r7,.Lthis_cpu
6107f6dc8d4SAlexander Gordeev	stap	0(%r7)			# this CPU address
6117f6dc8d4SAlexander Gordeev	lh	%r4,0(%r7)
6127f6dc8d4SAlexander Gordeev	nilh	%r4,0
6137f6dc8d4SAlexander Gordeev	lhi	%r0,1
6147f6dc8d4SAlexander Gordeev	sll	%r0,16			# CPU counter
6157f6dc8d4SAlexander Gordeev	lhi	%r3,0			# next CPU address
6167f6dc8d4SAlexander Gordeev0:	cr	%r3,%r4
6177f6dc8d4SAlexander Gordeev	je	2f
6187f6dc8d4SAlexander Gordeev1:	sigp	%r1,%r3,SIGP_STOP	# stop next CPU
6197f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,1b
6207f6dc8d4SAlexander Gordeev2:	ahi	%r3,1
6217f6dc8d4SAlexander Gordeev	brct	%r0,0b
6227f6dc8d4SAlexander Gordeev3:	sigp	%r1,%r4,SIGP_STOP	# stop this CPU
6237f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,3b
6247f6dc8d4SAlexander Gordeev4:	j	4b
62526a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
6264bfc86ceSHeiko Carstens
6274bfc86ceSHeiko CarstensENTRY(restart_int_handler)
628e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
629e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
630*915fea04SAlexander Gordeev	TSTMSK	__LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
631*915fea04SAlexander Gordeev	jz	0f
632*915fea04SAlexander Gordeev	la	%r15,4095
633*915fea04SAlexander Gordeev	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15)
634*915fea04SAlexander Gordeev0:	larl	%r15,.Lstosm_tmp
635*915fea04SAlexander Gordeev	stosm	0(%r15),0x04			# turn dat on, keep irqs off
6364bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
637ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
638ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
639ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
640ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
6414bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
6424bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
6434bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
644*915fea04SAlexander Gordeev	lgf	%r3,__LC_RESTART_SOURCE
6454bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
6464bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
6474bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
6484bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
6494bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
6504bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
6514bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
6524bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
6534bfc86ceSHeiko Carstens	brc	2,2b
6544bfc86ceSHeiko Carstens3:	j	3b
65526a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
6564bfc86ceSHeiko Carstens
6574bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
6584bfc86ceSHeiko Carstens
659ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
6604bfc86ceSHeiko Carstens/*
6614bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
6624bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
6634bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
6644bfc86ceSHeiko Carstens */
66526a374aeSMartin SchwidefskyENTRY(stack_overflow)
666ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
6674bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6684bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6694bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6704bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
6714bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
6724bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6734bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6744bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
67526a374aeSMartin SchwidefskyENDPROC(stack_overflow)
6764bfc86ceSHeiko Carstens#endif
6774bfc86ceSHeiko Carstens
6787f6dc8d4SAlexander Gordeev	.section .data, "aw"
6797f6dc8d4SAlexander Gordeev		.align	4
6807f6dc8d4SAlexander Gordeev.Lstop_lock:	.long	0
6817f6dc8d4SAlexander Gordeev.Lthis_cpu:	.short	0
682d35925b3SAlexander Gordeev.Lstosm_tmp:	.byte	0
6834bfc86ceSHeiko Carstens	.section .rodata, "a"
684ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
6854bfc86ceSHeiko Carstens	.globl	sys_call_table
6864bfc86ceSHeiko Carstenssys_call_table:
6874381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
6884bfc86ceSHeiko Carstens#undef SYSCALL
6894bfc86ceSHeiko Carstens
6904bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
6914bfc86ceSHeiko Carstens
692ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
6934bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
6944bfc86ceSHeiko Carstenssys_call_table_emu:
6954381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
6964bfc86ceSHeiko Carstens#undef SYSCALL
6974bfc86ceSHeiko Carstens#endif
698