xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 3b051e89da70d464a036a86d70ce2ed61c73f792)
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
55*3b051e89SSven Schnelle	.macro STBEAR address
56*3b051e89SSven Schnelle	ALTERNATIVE "", ".insn	s,0xb2010000,\address", 193
57*3b051e89SSven Schnelle	.endm
58*3b051e89SSven Schnelle
59*3b051e89SSven Schnelle	.macro LBEAR address
60*3b051e89SSven Schnelle	ALTERNATIVE "", ".insn	s,0xb2000000,\address", 193
61*3b051e89SSven Schnelle	.endm
62*3b051e89SSven Schnelle
63*3b051e89SSven Schnelle	.macro LPSWEY address,lpswe
64*3b051e89SSven Schnelle	ALTERNATIVE "b \lpswe", ".insn siy,0xeb0000000071,\address,0", 193
65*3b051e89SSven Schnelle	.endm
66*3b051e89SSven Schnelle
67*3b051e89SSven Schnelle	.macro MBEAR reg
68*3b051e89SSven Schnelle	ALTERNATIVE "", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
69*3b051e89SSven Schnelle	.endm
70*3b051e89SSven Schnelle
71ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
724bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
73ce3dc447SMartin Schwidefsky	tml	%r15,STACK_SIZE - CONFIG_STACK_GUARD
744bfc86ceSHeiko Carstens	lghi	%r14,\savearea
754bfc86ceSHeiko Carstens	jz	stack_overflow
764bfc86ceSHeiko Carstens#endif
774bfc86ceSHeiko Carstens	.endm
784bfc86ceSHeiko Carstens
79ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
80ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
81ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
82ce3dc447SMartin Schwidefsky	nill	%r14,0x10000 - STACK_SIZE
83ce3dc447SMartin Schwidefsky	oill	%r14,STACK_INIT
84ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
85ce3dc447SMartin Schwidefsky	je	\oklabel
86ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
87ce3dc447SMartin Schwidefsky	je	\oklabel
88b61b1595SSven Schnelle	clg	%r14,__LC_MCCK_STACK
89b61b1595SSven Schnelle	je	\oklabel
90ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
91ce3dc447SMartin Schwidefsky	je	\oklabel
92ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
93ce3dc447SMartin Schwidefsky	je	\oklabel
94ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
95ce3dc447SMartin Schwidefsky	j	stack_overflow
96ce3dc447SMartin Schwidefsky#else
97ce3dc447SMartin Schwidefsky	j	\oklabel
98ce3dc447SMartin Schwidefsky#endif
99ce3dc447SMartin Schwidefsky	.endm
100ce3dc447SMartin Schwidefsky
1014bfc86ceSHeiko Carstens	.macro STCK savearea
10278f65709SHeiko Carstens	ALTERNATIVE ".insn	s,0xb2050000,\savearea", \
10378f65709SHeiko Carstens		    ".insn	s,0xb27c0000,\savearea", 25
1044bfc86ceSHeiko Carstens	.endm
1054bfc86ceSHeiko Carstens
10683abeffbSHendrik Brueckner	/*
10783abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
10883abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
10983abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
11083abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
11183abeffbSHendrik Brueckner	 * instruction.
11283abeffbSHendrik Brueckner	 */
11383abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
11483abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
11583abeffbSHendrik Brueckner			.if (\mask & 0xff)
11683abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
11783abeffbSHendrik Brueckner			.endif
11883abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
11983abeffbSHendrik Brueckner			.exitm
12083abeffbSHendrik Brueckner		.endif
12183abeffbSHendrik Brueckner		.ifeq \mask
12283abeffbSHendrik Brueckner			.error "Mask must not be zero"
12383abeffbSHendrik Brueckner		.endif
12483abeffbSHendrik Brueckner		off = \size - \bytepos - 1
12583abeffbSHendrik Brueckner		tm	off+\addr, \mask
12683abeffbSHendrik Brueckner	.endm
12783abeffbSHendrik Brueckner
128d768bd89SMartin Schwidefsky	.macro BPOFF
129b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
130d768bd89SMartin Schwidefsky	.endm
131d768bd89SMartin Schwidefsky
132d768bd89SMartin Schwidefsky	.macro BPON
133b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
134d768bd89SMartin Schwidefsky	.endm
135d768bd89SMartin Schwidefsky
1366b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
137b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
138b058661aSMartin Schwidefsky		    "", 82
1396b73044bSMartin Schwidefsky	.endm
1406b73044bSMartin Schwidefsky
1416b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1426b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
143b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
144b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
1456b73044bSMartin Schwidefsky	.endm
1466b73044bSMartin Schwidefsky
147d35925b3SAlexander Gordeev	/*
148d35925b3SAlexander Gordeev	 * The CHKSTG macro jumps to the provided label in case the
149d35925b3SAlexander Gordeev	 * machine check interruption code reports one of unrecoverable
150d35925b3SAlexander Gordeev	 * storage errors:
151d35925b3SAlexander Gordeev	 * - Storage error uncorrected
152d35925b3SAlexander Gordeev	 * - Storage key error uncorrected
153d35925b3SAlexander Gordeev	 * - Storage degradation with Failing-storage-address validity
154d35925b3SAlexander Gordeev	 */
155d35925b3SAlexander Gordeev	.macro CHKSTG errlabel
156d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR)
157d35925b3SAlexander Gordeev	jnz	\errlabel
158d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD
15915256194SHeiko Carstens	jz	.Loklabel\@
160d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR
161d35925b3SAlexander Gordeev	jnz	\errlabel
16215256194SHeiko Carstens.Loklabel\@:
163d35925b3SAlexander Gordeev	.endm
164d35925b3SAlexander Gordeev
165b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM)
166b5415c8fSAlexander Gordeev	/*
167b5415c8fSAlexander Gordeev	 * The OUTSIDE macro jumps to the provided label in case the value
168b5415c8fSAlexander Gordeev	 * in the provided register is outside of the provided range. The
169b5415c8fSAlexander Gordeev	 * macro is useful for checking whether a PSW stored in a register
170b5415c8fSAlexander Gordeev	 * pair points inside or outside of a block of instructions.
171b5415c8fSAlexander Gordeev	 * @reg: register to check
172b5415c8fSAlexander Gordeev	 * @start: start of the range
173b5415c8fSAlexander Gordeev	 * @end: end of the range
174b5415c8fSAlexander Gordeev	 * @outside_label: jump here if @reg is outside of [@start..@end)
175b5415c8fSAlexander Gordeev	 */
176b5415c8fSAlexander Gordeev	.macro OUTSIDE reg,start,end,outside_label
177b5415c8fSAlexander Gordeev	lgr	%r14,\reg
178b5415c8fSAlexander Gordeev	larl	%r13,\start
179b5415c8fSAlexander Gordeev	slgr	%r14,%r13
180b5415c8fSAlexander Gordeev	lghi	%r13,\end - \start
181b5415c8fSAlexander Gordeev	clgr	%r14,%r13
182b5415c8fSAlexander Gordeev	jhe	\outside_label
183b5415c8fSAlexander Gordeev	.endm
184fbbdfca5SAlexander Gordeev
185fbbdfca5SAlexander Gordeev	.macro SIEEXIT
186fbbdfca5SAlexander Gordeev	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
187fbbdfca5SAlexander Gordeev	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
188fbbdfca5SAlexander Gordeev	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
189fbbdfca5SAlexander Gordeev	larl	%r9,sie_exit			# skip forward to sie_exit
190fbbdfca5SAlexander Gordeev	.endm
191b5415c8fSAlexander Gordeev#endif
192b5415c8fSAlexander Gordeev
1936dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
19433ea0487SSven Schnelle	GEN_BR_THUNK %r14,%r13
195f19fbd5eSMartin Schwidefsky
1964bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
19746210c44SHeiko Carstens.Ldummy:
19846210c44SHeiko Carstens	/*
19956e62a73SSven Schnelle	 * This nop exists only in order to avoid that __bpon starts at
20046210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
20146210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
20246210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
20356e62a73SSven Schnelle	 * With the added nop in between the __bpon symbol is unique
20446210c44SHeiko Carstens	 * again.
20546210c44SHeiko Carstens	 */
20646210c44SHeiko Carstens	nop	0
2074bfc86ceSHeiko Carstens
208d768bd89SMartin SchwidefskyENTRY(__bpon)
209d768bd89SMartin Schwidefsky	.globl __bpon
210d768bd89SMartin Schwidefsky	BPON
2116dd85fbbSMartin Schwidefsky	BR_EX	%r14
21226a374aeSMartin SchwidefskyENDPROC(__bpon)
213d768bd89SMartin Schwidefsky
2144bfc86ceSHeiko Carstens/*
2154bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2164bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2174bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2184bfc86ceSHeiko Carstens * Returns:
2194bfc86ceSHeiko Carstens *  gpr2 = prev
2204bfc86ceSHeiko Carstens */
2214bfc86ceSHeiko CarstensENTRY(__switch_to)
2224bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2233241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2243241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2259fed920eSVasily Gorbik	llill	%r5,STACK_INIT
2263241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2279fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
2289fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
2294bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2304bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2313241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2323241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2333241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2344bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
235e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2366dd85fbbSMartin Schwidefsky	BR_EX	%r14
23726a374aeSMartin SchwidefskyENDPROC(__switch_to)
2384bfc86ceSHeiko Carstens
239d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
240d0fc4107SMartin Schwidefsky/*
241d0fc4107SMartin Schwidefsky * sie64a calling convention:
242d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
243d0fc4107SMartin Schwidefsky * %r3 guest register save area
244d0fc4107SMartin Schwidefsky */
245d0fc4107SMartin SchwidefskyENTRY(sie64a)
246d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2476b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
24892fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
24992fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
25092fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
25192fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
252d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
253d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
254d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
255d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
256d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
257d0fc4107SMartin Schwidefsky.Lsie_gmap:
25892fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
259d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
260d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
261d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
26283abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
263d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
26492fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
265c929500dSQingFeng Hao.Lsie_entry:
266d0fc4107SMartin Schwidefsky	sie	0(%r14)
267d768bd89SMartin Schwidefsky	BPOFF
26892fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
269d0fc4107SMartin Schwidefsky.Lsie_skip:
270d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
27187d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
272d0fc4107SMartin Schwidefsky.Lsie_done:
273d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
274c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
275c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
276c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
277c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
278c0e7bb38SChristian Borntraeger.Lrewind_pad6:
279c0e7bb38SChristian Borntraeger	nopr	7
280c0e7bb38SChristian Borntraeger.Lrewind_pad4:
281c0e7bb38SChristian Borntraeger	nopr	7
282c0e7bb38SChristian Borntraeger.Lrewind_pad2:
283c0e7bb38SChristian Borntraeger	nopr	7
284d0fc4107SMartin Schwidefsky	.globl sie_exit
285d0fc4107SMartin Schwidefskysie_exit:
28692fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
287d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2887041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2897041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2907041d281SMartin Schwidefsky	xgr	%r3,%r3
2917041d281SMartin Schwidefsky	xgr	%r4,%r4
2927041d281SMartin Schwidefsky	xgr	%r5,%r5
293d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
29492fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
2956dd85fbbSMartin Schwidefsky	BR_EX	%r14
296d0fc4107SMartin Schwidefsky.Lsie_fault:
297d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
29892fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
299d0fc4107SMartin Schwidefsky	j	sie_exit
300d0fc4107SMartin Schwidefsky
301c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
302c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
303c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
304d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
30526a374aeSMartin SchwidefskyENDPROC(sie64a)
306711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
307711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
308d0fc4107SMartin Schwidefsky#endif
309d0fc4107SMartin Schwidefsky
3104bfc86ceSHeiko Carstens/*
3114bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3127b7735c5SChristian Borntraeger * are entered with interrupts disabled.
3134bfc86ceSHeiko Carstens */
3144bfc86ceSHeiko Carstens
3154bfc86ceSHeiko CarstensENTRY(system_call)
31656e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
3174bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
318d768bd89SMartin Schwidefsky	BPOFF
31956e62a73SSven Schnelle	lghi	%r14,0
3204bfc86ceSHeiko Carstens.Lsysc_per:
321*3b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
32287d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
32356e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
3244bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3259365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
32656e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
32756e62a73SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
328d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
329d3f46896SChristian Borntraeger	xgr	%r0,%r0
33056e62a73SSven Schnelle	xgr	%r1,%r1
33156e62a73SSven Schnelle	xgr	%r4,%r4
33256e62a73SSven Schnelle	xgr	%r5,%r5
33356e62a73SSven Schnelle	xgr	%r6,%r6
33456e62a73SSven Schnelle	xgr	%r7,%r7
33556e62a73SSven Schnelle	xgr	%r8,%r8
33656e62a73SSven Schnelle	xgr	%r9,%r9
33756e62a73SSven Schnelle	xgr	%r10,%r10
33856e62a73SSven Schnelle	xgr	%r11,%r11
33956e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
340af9ad822SSven Schnelle	mvc	__PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
341*3b051e89SSven Schnelle	MBEAR	%r2
34256e62a73SSven Schnelle	lgr	%r3,%r14
34356e62a73SSven Schnelle	brasl	%r14,__do_syscall
34487d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
34556e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3466b73044bSMartin Schwidefsky	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
347*3b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
34856e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3494bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
350*3b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
35126a374aeSMartin SchwidefskyENDPROC(system_call)
3524bfc86ceSHeiko Carstens
3534bfc86ceSHeiko Carstens#
3544bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3554bfc86ceSHeiko Carstens#
3564bfc86ceSHeiko CarstensENTRY(ret_from_fork)
35756e62a73SSven Schnelle	lgr	%r3,%r11
35856e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
35956e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
36056e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
36156e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
362*3b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
36356e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
36456e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
365*3b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
36626a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
36726a374aeSMartin Schwidefsky
3684bfc86ceSHeiko Carstens/*
3694bfc86ceSHeiko Carstens * Program check handler routine
3704bfc86ceSHeiko Carstens */
3714bfc86ceSHeiko Carstens
3724bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
37356e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
374d768bd89SMartin Schwidefsky	BPOFF
3754bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
37656e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
37756e62a73SSven Schnelle	lghi	%r10,0
3784bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
37987d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
38087d59863SHeiko Carstens	jno	.Lpgm_skip_asce
38187d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
38256e62a73SSven Schnelle	j	3f			# -> fault in user space
38387d59863SHeiko Carstens.Lpgm_skip_asce:
384d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3850a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
386b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f
387fbbdfca5SAlexander Gordeev	SIEEXIT
38856e62a73SSven Schnelle	lghi	%r10,_PIF_GUEST_FAULT
389d0fc4107SMartin Schwidefsky#endif
3900b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
3910b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
3924bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
3934bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
3940b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
3954bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
39656e62a73SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 4f
39756e62a73SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
39856e62a73SSven Schnelle3:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3994bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
40056e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
40156e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
40256e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
4034bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
40456e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
405*3b051e89SSven Schnelle	mvc	__PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK
40656e62a73SSven Schnelle	stmg	%r8,%r9,__PT_PSW(%r11)
40756e62a73SSven Schnelle
4087041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4097041d281SMartin Schwidefsky	xgr	%r0,%r0
4107041d281SMartin Schwidefsky	xgr	%r1,%r1
4117041d281SMartin Schwidefsky	xgr	%r3,%r3
4127041d281SMartin Schwidefsky	xgr	%r4,%r4
4137041d281SMartin Schwidefsky	xgr	%r5,%r5
4147041d281SMartin Schwidefsky	xgr	%r6,%r6
4157041d281SMartin Schwidefsky	xgr	%r7,%r7
41656e62a73SSven Schnelle	lgr	%r2,%r11
41756e62a73SSven Schnelle	brasl	%r14,__do_pgm_check
41856e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user space?
41956e62a73SSven Schnelle	jno	.Lpgm_exit_kernel
42056e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
42156e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
4220cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
42356e62a73SSven Schnelle.Lpgm_exit_kernel:
42456e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
425*3b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
42656e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
427*3b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
4284bfc86ceSHeiko Carstens
4294bfc86ceSHeiko Carstens#
4304bfc86ceSHeiko Carstens# single stepped system call
4314bfc86ceSHeiko Carstens#
4324bfc86ceSHeiko Carstens.Lpgm_svcper:
4334bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
4344bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
4354bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
43656e62a73SSven Schnelle	lghi	%r14,1
437*3b051e89SSven Schnelle	LBEAR	__LC_PGM_LAST_BREAK
438*3b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per
43926a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
4404bfc86ceSHeiko Carstens
4414bfc86ceSHeiko Carstens/*
44256e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4434bfc86ceSHeiko Carstens */
44456e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
44556e62a73SSven SchnelleENTRY(\name)
4464bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
44756e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
448*3b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
449d768bd89SMartin Schwidefsky	BPOFF
4504bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
451d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
45256e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
453b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
454b0d31159SSven Schnelle	jnz	1f
455b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
456b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,0f
457fbbdfca5SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
458fbbdfca5SAlexander Gordeev	SIEEXIT
459b0d31159SSven Schnelle#endif
460b0d31159SSven Schnelle0:	CHECK_STACK __LC_SAVE_AREA_ASYNC
461b0d31159SSven Schnelle	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
462b0d31159SSven Schnelle	j	2f
463b0d31159SSven Schnelle1:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
464b0d31159SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
465b0d31159SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
466b74e409eSVasily Gorbik2:	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
467b74e409eSVasily Gorbik	la	%r11,STACK_FRAME_OVERHEAD(%r15)
4684bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4697041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4707041d281SMartin Schwidefsky	xgr	%r0,%r0
4717041d281SMartin Schwidefsky	xgr	%r1,%r1
4727041d281SMartin Schwidefsky	xgr	%r3,%r3
4737041d281SMartin Schwidefsky	xgr	%r4,%r4
4747041d281SMartin Schwidefsky	xgr	%r5,%r5
4757041d281SMartin Schwidefsky	xgr	%r6,%r6
4767041d281SMartin Schwidefsky	xgr	%r7,%r7
4777041d281SMartin Schwidefsky	xgr	%r10,%r10
478ca1f4d70SSven Schnelle	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
4794bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
480*3b051e89SSven Schnelle	MBEAR	%r11
4814bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
48256e62a73SSven Schnelle	tm	%r8,0x0001		# coming from user space?
48356e62a73SSven Schnelle	jno	1f
48487d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
48556e62a73SSven Schnelle1:	lgr	%r2,%r11		# pass pointer to pt_regs
48656e62a73SSven Schnelle	brasl	%r14,\handler
4874bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
48856e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
48956e62a73SSven Schnelle	jno	2f
49087d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
4916b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4924bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
493*3b051e89SSven Schnelle2:	LBEAR	__PT_LAST_BREAK(%r11)
494*3b051e89SSven Schnelle	lmg	%r0,%r15,__PT_R0(%r11)
495*3b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
49656e62a73SSven SchnelleENDPROC(\name)
49756e62a73SSven Schnelle.endm
4984bfc86ceSHeiko Carstens
49956e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
50056e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
5014bfc86ceSHeiko Carstens
5024bfc86ceSHeiko Carstens/*
5030b0ed657SSven Schnelle * Load idle PSW.
5044bfc86ceSHeiko Carstens */
5054bfc86ceSHeiko CarstensENTRY(psw_idle)
506a994eddbSVasily Gorbik	stg	%r14,(__SF_GPRS+8*8)(%r15)
5074bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
50856e62a73SSven Schnelle	larl	%r1,psw_idle_exit
5094bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
51072d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
51172d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
51272d38b19SMartin Schwidefsky	ltgr	%r1,%r1
51372d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
51456e62a73SSven Schnelle	.insn	rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
51572d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
516419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
517d768bd89SMartin Schwidefsky	BPON
5184bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
5194bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
5204bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
52156e62a73SSven Schnelle.globl psw_idle_exit
52256e62a73SSven Schnellepsw_idle_exit:
5236dd85fbbSMartin Schwidefsky	BR_EX	%r14
52426a374aeSMartin SchwidefskyENDPROC(psw_idle)
5254bfc86ceSHeiko Carstens
526b5510d9bSHendrik Brueckner/*
5274bfc86ceSHeiko Carstens * Machine check handler routines
5284bfc86ceSHeiko Carstens */
5294bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
5304bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
531d768bd89SMartin Schwidefsky	BPOFF
5323037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
5333037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
534*3b051e89SSven Schnelle	LBEAR	__LC_LAST_BREAK_SAVE_AREA-4095(%r1)		# validate bear
5353037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
536d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
5374bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
53883abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
5394bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
5403037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
5413037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
5423037a52fSMartin Schwidefsky	la	%r14,4095
5433037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
5443037a52fSMartin Schwidefsky	ptlb
5455fa2ea07SAlexander Gordeev	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5464bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
54783abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5484bfc86ceSHeiko Carstens	jo	3f
54956e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
55056e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5514bfc86ceSHeiko Carstens	jl	1f
5524bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5534bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5544bfc86ceSHeiko Carstens	jl	2f
5554bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5564bfc86ceSHeiko Carstens2:	spt	0(%r14)
5574bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5583037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5593037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5603037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
561d35925b3SAlexander Gordeev	jnz	6f
5623037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5633037a52fSMartin Schwidefsky	jno	.Lmcck_panic
564b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
565d35925b3SAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,6f
566d35925b3SAlexander Gordeev	OUTSIDE	%r9,.Lsie_entry,.Lsie_skip,4f
56720232b18SAlexander Gordeev	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
568d35925b3SAlexander Gordeev	j	5f
569d35925b3SAlexander Gordeev4:	CHKSTG	.Lmcck_panic
570d35925b3SAlexander Gordeev5:	larl	%r14,.Lstosm_tmp
571d35925b3SAlexander Gordeev	stosm	0(%r14),0x04		# turn dat on, keep irqs off
572d35925b3SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
573fbbdfca5SAlexander Gordeev	SIEEXIT
574b61b1595SSven Schnelle	j	.Lmcck_stack
575e2c13d64SAlexander Gordeev#endif
576d35925b3SAlexander Gordeev6:	CHKSTG	.Lmcck_panic
577d35925b3SAlexander Gordeev	larl	%r14,.Lstosm_tmp
578d35925b3SAlexander Gordeev	stosm	0(%r14),0x04		# turn dat on, keep irqs off
579d35925b3SAlexander Gordeev	tmhh	%r8,0x0001		# interrupting from user ?
580d35925b3SAlexander Gordeev	jz	.Lmcck_stack
581b0d31159SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
582b61b1595SSven Schnelle.Lmcck_stack:
583b61b1595SSven Schnelle	lg	%r15,__LC_MCCK_STACK
584b61b1595SSven Schnelle	la	%r11,STACK_FRAME_OVERHEAD(%r15)
58526521412SSven Schnelle	stctg	%c1,%c1,__PT_CR1(%r11)
586b61b1595SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
587b61b1595SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5884bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5894bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5907041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5917041d281SMartin Schwidefsky	xgr	%r0,%r0
5927041d281SMartin Schwidefsky	xgr	%r1,%r1
5937041d281SMartin Schwidefsky	xgr	%r3,%r3
5947041d281SMartin Schwidefsky	xgr	%r4,%r4
5957041d281SMartin Schwidefsky	xgr	%r5,%r5
5967041d281SMartin Schwidefsky	xgr	%r6,%r6
5977041d281SMartin Schwidefsky	xgr	%r7,%r7
5987041d281SMartin Schwidefsky	xgr	%r10,%r10
5994bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
6004bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6014bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
6024bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6034bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6044bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
6050b0ed657SSven Schnelle	cghi	%r2,0
6060b0ed657SSven Schnelle	je	.Lmcck_return
6074bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
6084bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
6094bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
6104bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
6114bfc86ceSHeiko Carstens	lgr	%r15,%r1
6124bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
6134bfc86ceSHeiko Carstens.Lmcck_return:
61487d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
6154bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
6164bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
6174bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
6184bfc86ceSHeiko Carstens	jno	0f
6196b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
6204bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
621*3b051e89SSven Schnelle0:	ALTERNATIVE "", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
622*3b051e89SSven Schnelle	LBEAR	0(%r12)
623*3b051e89SSven Schnelle	lmg	%r11,%r15,__PT_R11(%r11)
624*3b051e89SSven Schnelle	LPSWEY	__LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
6254bfc86ceSHeiko Carstens
6264bfc86ceSHeiko Carstens.Lmcck_panic:
6277f6dc8d4SAlexander Gordeev	/*
6287f6dc8d4SAlexander Gordeev	 * Iterate over all possible CPU addresses in the range 0..0xffff
6297f6dc8d4SAlexander Gordeev	 * and stop each CPU using signal processor. Use compare and swap
6307f6dc8d4SAlexander Gordeev	 * to allow just one CPU-stopper and prevent concurrent CPUs from
6317f6dc8d4SAlexander Gordeev	 * stopping each other while leaving the others running.
6327f6dc8d4SAlexander Gordeev	 */
6337f6dc8d4SAlexander Gordeev	lhi	%r5,0
6347f6dc8d4SAlexander Gordeev	lhi	%r6,1
6357f6dc8d4SAlexander Gordeev	larl	%r7,.Lstop_lock
6367f6dc8d4SAlexander Gordeev	cs	%r5,%r6,0(%r7)		# single CPU-stopper only
6377f6dc8d4SAlexander Gordeev	jnz	4f
6387f6dc8d4SAlexander Gordeev	larl	%r7,.Lthis_cpu
6397f6dc8d4SAlexander Gordeev	stap	0(%r7)			# this CPU address
6407f6dc8d4SAlexander Gordeev	lh	%r4,0(%r7)
6417f6dc8d4SAlexander Gordeev	nilh	%r4,0
6427f6dc8d4SAlexander Gordeev	lhi	%r0,1
6437f6dc8d4SAlexander Gordeev	sll	%r0,16			# CPU counter
6447f6dc8d4SAlexander Gordeev	lhi	%r3,0			# next CPU address
6457f6dc8d4SAlexander Gordeev0:	cr	%r3,%r4
6467f6dc8d4SAlexander Gordeev	je	2f
6477f6dc8d4SAlexander Gordeev1:	sigp	%r1,%r3,SIGP_STOP	# stop next CPU
6487f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,1b
6497f6dc8d4SAlexander Gordeev2:	ahi	%r3,1
6507f6dc8d4SAlexander Gordeev	brct	%r0,0b
6517f6dc8d4SAlexander Gordeev3:	sigp	%r1,%r4,SIGP_STOP	# stop this CPU
6527f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,3b
6537f6dc8d4SAlexander Gordeev4:	j	4b
65426a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
6554bfc86ceSHeiko Carstens
6564bfc86ceSHeiko CarstensENTRY(restart_int_handler)
657e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
658e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
659915fea04SAlexander Gordeev	TSTMSK	__LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
660915fea04SAlexander Gordeev	jz	0f
661915fea04SAlexander Gordeev	la	%r15,4095
662915fea04SAlexander Gordeev	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15)
663915fea04SAlexander Gordeev0:	larl	%r15,.Lstosm_tmp
664915fea04SAlexander Gordeev	stosm	0(%r15),0x04			# turn dat on, keep irqs off
6654bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
666ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
667ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
668ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
669ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
6704bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
6714bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
6724bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
673915fea04SAlexander Gordeev	lgf	%r3,__LC_RESTART_SOURCE
6744bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
6754bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
6764bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
6774bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
6784bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
6794bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
6804bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
6814bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
6824bfc86ceSHeiko Carstens	brc	2,2b
6834bfc86ceSHeiko Carstens3:	j	3b
68426a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
6854bfc86ceSHeiko Carstens
6864bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
6874bfc86ceSHeiko Carstens
688ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
6894bfc86ceSHeiko Carstens/*
6904bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
6914bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
6924bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
6934bfc86ceSHeiko Carstens */
69426a374aeSMartin SchwidefskyENTRY(stack_overflow)
695ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
6964bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6974bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6984bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6994bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
7004bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
7014bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7024bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7034bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
70426a374aeSMartin SchwidefskyENDPROC(stack_overflow)
7054bfc86ceSHeiko Carstens#endif
7064bfc86ceSHeiko Carstens
7077f6dc8d4SAlexander Gordeev	.section .data, "aw"
7087f6dc8d4SAlexander Gordeev		.align	4
7097f6dc8d4SAlexander Gordeev.Lstop_lock:	.long	0
7107f6dc8d4SAlexander Gordeev.Lthis_cpu:	.short	0
711d35925b3SAlexander Gordeev.Lstosm_tmp:	.byte	0
7124bfc86ceSHeiko Carstens	.section .rodata, "a"
713ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
7144bfc86ceSHeiko Carstens	.globl	sys_call_table
7154bfc86ceSHeiko Carstenssys_call_table:
7164381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
7174bfc86ceSHeiko Carstens#undef SYSCALL
7184bfc86ceSHeiko Carstens
7194bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
7204bfc86ceSHeiko Carstens
721ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
7224bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
7234bfc86ceSHeiko Carstenssys_call_table_emu:
7244381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
7254bfc86ceSHeiko Carstens#undef SYSCALL
7264bfc86ceSHeiko Carstens#endif
727