xref: /openbmc/linux/arch/s390/kernel/entry.S (revision fad442d3abde47aef97d0d822807ab6e2555784a)
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 */
104bfc86ceSHeiko Carstens
114bfc86ceSHeiko Carstens#include <linux/init.h>
124bfc86ceSHeiko Carstens#include <linux/linkage.h>
13d09a307fSHeiko Carstens#include <asm/asm-extable.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
553b051e89SSven Schnelle	.macro STBEAR address
56*fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193
573b051e89SSven Schnelle	.endm
583b051e89SSven Schnelle
593b051e89SSven Schnelle	.macro LBEAR address
60*fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193
613b051e89SSven Schnelle	.endm
623b051e89SSven Schnelle
633b051e89SSven Schnelle	.macro LPSWEY address,lpswe
64*fad442d3SHeiko Carstens	ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193
653b051e89SSven Schnelle	.endm
663b051e89SSven Schnelle
673b051e89SSven Schnelle	.macro MBEAR reg
68*fad442d3SHeiko Carstens	ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
693b051e89SSven Schnelle	.endm
703b051e89SSven 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
10183abeffbSHendrik Brueckner	/*
10283abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
10383abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
10483abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
10583abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
10683abeffbSHendrik Brueckner	 * instruction.
10783abeffbSHendrik Brueckner	 */
10883abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
10983abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
11083abeffbSHendrik Brueckner			.if (\mask & 0xff)
11183abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
11283abeffbSHendrik Brueckner			.endif
11383abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
11483abeffbSHendrik Brueckner			.exitm
11583abeffbSHendrik Brueckner		.endif
11683abeffbSHendrik Brueckner		.ifeq \mask
11783abeffbSHendrik Brueckner			.error "Mask must not be zero"
11883abeffbSHendrik Brueckner		.endif
11983abeffbSHendrik Brueckner		off = \size - \bytepos - 1
12083abeffbSHendrik Brueckner		tm	off+\addr, \mask
12183abeffbSHendrik Brueckner	.endm
12283abeffbSHendrik Brueckner
123d768bd89SMartin Schwidefsky	.macro BPOFF
124*fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82
125d768bd89SMartin Schwidefsky	.endm
126d768bd89SMartin Schwidefsky
127d768bd89SMartin Schwidefsky	.macro BPON
128*fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82
129d768bd89SMartin Schwidefsky	.endm
130d768bd89SMartin Schwidefsky
1316b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
1326982dba1SHeiko Carstens	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
133*fad442d3SHeiko Carstens		    "j .+12; nop; nop", 82
1346b73044bSMartin Schwidefsky	.endm
1356b73044bSMartin Schwidefsky
1366b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1376b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
1386982dba1SHeiko Carstens	ALTERNATIVE "jz .+8;  .insn rrf,0xb2e80000,0,0,12,0", \
1396982dba1SHeiko Carstens		    "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
1406b73044bSMartin Schwidefsky	.endm
1416b73044bSMartin Schwidefsky
142d35925b3SAlexander Gordeev	/*
143d35925b3SAlexander Gordeev	 * The CHKSTG macro jumps to the provided label in case the
144d35925b3SAlexander Gordeev	 * machine check interruption code reports one of unrecoverable
145d35925b3SAlexander Gordeev	 * storage errors:
146d35925b3SAlexander Gordeev	 * - Storage error uncorrected
147d35925b3SAlexander Gordeev	 * - Storage key error uncorrected
148d35925b3SAlexander Gordeev	 * - Storage degradation with Failing-storage-address validity
149d35925b3SAlexander Gordeev	 */
150d35925b3SAlexander Gordeev	.macro CHKSTG errlabel
151d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR)
152d35925b3SAlexander Gordeev	jnz	\errlabel
153d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD
15415256194SHeiko Carstens	jz	.Loklabel\@
155d35925b3SAlexander Gordeev	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR
156d35925b3SAlexander Gordeev	jnz	\errlabel
15715256194SHeiko Carstens.Loklabel\@:
158d35925b3SAlexander Gordeev	.endm
159d35925b3SAlexander Gordeev
160b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM)
161b5415c8fSAlexander Gordeev	/*
162b5415c8fSAlexander Gordeev	 * The OUTSIDE macro jumps to the provided label in case the value
163b5415c8fSAlexander Gordeev	 * in the provided register is outside of the provided range. The
164b5415c8fSAlexander Gordeev	 * macro is useful for checking whether a PSW stored in a register
165b5415c8fSAlexander Gordeev	 * pair points inside or outside of a block of instructions.
166b5415c8fSAlexander Gordeev	 * @reg: register to check
167b5415c8fSAlexander Gordeev	 * @start: start of the range
168b5415c8fSAlexander Gordeev	 * @end: end of the range
169b5415c8fSAlexander Gordeev	 * @outside_label: jump here if @reg is outside of [@start..@end)
170b5415c8fSAlexander Gordeev	 */
171b5415c8fSAlexander Gordeev	.macro OUTSIDE reg,start,end,outside_label
172b5415c8fSAlexander Gordeev	lgr	%r14,\reg
173b5415c8fSAlexander Gordeev	larl	%r13,\start
174b5415c8fSAlexander Gordeev	slgr	%r14,%r13
175b5415c8fSAlexander Gordeev	lghi	%r13,\end - \start
176b5415c8fSAlexander Gordeev	clgr	%r14,%r13
177b5415c8fSAlexander Gordeev	jhe	\outside_label
178b5415c8fSAlexander Gordeev	.endm
179fbbdfca5SAlexander Gordeev
180fbbdfca5SAlexander Gordeev	.macro SIEEXIT
181fbbdfca5SAlexander Gordeev	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
182fbbdfca5SAlexander Gordeev	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
183fbbdfca5SAlexander Gordeev	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
184fbbdfca5SAlexander Gordeev	larl	%r9,sie_exit			# skip forward to sie_exit
185fbbdfca5SAlexander Gordeev	.endm
186b5415c8fSAlexander Gordeev#endif
187b5415c8fSAlexander Gordeev
1886dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
189f19fbd5eSMartin Schwidefsky
1904bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
19146210c44SHeiko Carstens.Ldummy:
19246210c44SHeiko Carstens	/*
19356e62a73SSven Schnelle	 * This nop exists only in order to avoid that __bpon starts at
19446210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
19546210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
19646210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
19756e62a73SSven Schnelle	 * With the added nop in between the __bpon symbol is unique
19846210c44SHeiko Carstens	 * again.
19946210c44SHeiko Carstens	 */
20046210c44SHeiko Carstens	nop	0
2014bfc86ceSHeiko Carstens
202d768bd89SMartin SchwidefskyENTRY(__bpon)
203d768bd89SMartin Schwidefsky	.globl __bpon
204d768bd89SMartin Schwidefsky	BPON
2056dd85fbbSMartin Schwidefsky	BR_EX	%r14
20626a374aeSMartin SchwidefskyENDPROC(__bpon)
207d768bd89SMartin Schwidefsky
2084bfc86ceSHeiko Carstens/*
2094bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2104bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2114bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2124bfc86ceSHeiko Carstens * Returns:
2134bfc86ceSHeiko Carstens *  gpr2 = prev
2144bfc86ceSHeiko Carstens */
2154bfc86ceSHeiko CarstensENTRY(__switch_to)
2164bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2173241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2183241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2199fed920eSVasily Gorbik	llill	%r5,STACK_INIT
2203241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2219fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
2229fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
2234bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2244bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2253241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2263241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2273241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2284bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
229*fad442d3SHeiko Carstens	ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
2306dd85fbbSMartin Schwidefsky	BR_EX	%r14
23126a374aeSMartin SchwidefskyENDPROC(__switch_to)
2324bfc86ceSHeiko Carstens
233d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
234d0fc4107SMartin Schwidefsky/*
235d0fc4107SMartin Schwidefsky * sie64a calling convention:
236d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
237d0fc4107SMartin Schwidefsky * %r3 guest register save area
238d0fc4107SMartin Schwidefsky */
239d0fc4107SMartin SchwidefskyENTRY(sie64a)
240d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2416b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
24292fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
24392fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
24492fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
24592fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
246d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
247d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
248d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
249d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
250d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
251d0fc4107SMartin Schwidefsky.Lsie_gmap:
25292fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
253d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
254d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
255d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
25683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
257d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
25892fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
259c929500dSQingFeng Hao.Lsie_entry:
260d0fc4107SMartin Schwidefsky	sie	0(%r14)
261d768bd89SMartin Schwidefsky	BPOFF
26292fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
263d0fc4107SMartin Schwidefsky.Lsie_skip:
264d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
26587d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
266d0fc4107SMartin Schwidefsky.Lsie_done:
267d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
268c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
269c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
270c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
271c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
272c0e7bb38SChristian Borntraeger.Lrewind_pad6:
273c0e7bb38SChristian Borntraeger	nopr	7
274c0e7bb38SChristian Borntraeger.Lrewind_pad4:
275c0e7bb38SChristian Borntraeger	nopr	7
276c0e7bb38SChristian Borntraeger.Lrewind_pad2:
277c0e7bb38SChristian Borntraeger	nopr	7
278d0fc4107SMartin Schwidefsky	.globl sie_exit
279d0fc4107SMartin Schwidefskysie_exit:
28092fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
281d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2827041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2837041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2847041d281SMartin Schwidefsky	xgr	%r3,%r3
2857041d281SMartin Schwidefsky	xgr	%r4,%r4
2867041d281SMartin Schwidefsky	xgr	%r5,%r5
287d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
28892fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
2896dd85fbbSMartin Schwidefsky	BR_EX	%r14
290d0fc4107SMartin Schwidefsky.Lsie_fault:
291d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
29292fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
293d0fc4107SMartin Schwidefsky	j	sie_exit
294d0fc4107SMartin Schwidefsky
295c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
296c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
297c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
298d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
29926a374aeSMartin SchwidefskyENDPROC(sie64a)
300711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
301711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
302d0fc4107SMartin Schwidefsky#endif
303d0fc4107SMartin Schwidefsky
3044bfc86ceSHeiko Carstens/*
3054bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3067b7735c5SChristian Borntraeger * are entered with interrupts disabled.
3074bfc86ceSHeiko Carstens */
3084bfc86ceSHeiko Carstens
3094bfc86ceSHeiko CarstensENTRY(system_call)
31056e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
3114bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
312d768bd89SMartin Schwidefsky	BPOFF
31356e62a73SSven Schnelle	lghi	%r14,0
3144bfc86ceSHeiko Carstens.Lsysc_per:
3153b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
31687d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
31756e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
3184bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3199365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
32056e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
32156e62a73SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
322d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
323d3f46896SChristian Borntraeger	xgr	%r0,%r0
32456e62a73SSven Schnelle	xgr	%r1,%r1
32556e62a73SSven Schnelle	xgr	%r4,%r4
32656e62a73SSven Schnelle	xgr	%r5,%r5
32756e62a73SSven Schnelle	xgr	%r6,%r6
32856e62a73SSven Schnelle	xgr	%r7,%r7
32956e62a73SSven Schnelle	xgr	%r8,%r8
33056e62a73SSven Schnelle	xgr	%r9,%r9
33156e62a73SSven Schnelle	xgr	%r10,%r10
33256e62a73SSven Schnelle	xgr	%r11,%r11
33356e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
334af9ad822SSven Schnelle	mvc	__PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
3353b051e89SSven Schnelle	MBEAR	%r2
33656e62a73SSven Schnelle	lgr	%r3,%r14
33756e62a73SSven Schnelle	brasl	%r14,__do_syscall
33887d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
33956e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3406b73044bSMartin Schwidefsky	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
3413b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
34256e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3434bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3443b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
34526a374aeSMartin SchwidefskyENDPROC(system_call)
3464bfc86ceSHeiko Carstens
3474bfc86ceSHeiko Carstens#
3484bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3494bfc86ceSHeiko Carstens#
3504bfc86ceSHeiko CarstensENTRY(ret_from_fork)
35156e62a73SSven Schnelle	lgr	%r3,%r11
35256e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
35356e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
35456e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
35556e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
3563b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
35756e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
35856e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
3593b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
36026a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
36126a374aeSMartin Schwidefsky
3624bfc86ceSHeiko Carstens/*
3634bfc86ceSHeiko Carstens * Program check handler routine
3644bfc86ceSHeiko Carstens */
3654bfc86ceSHeiko Carstens
3664bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
36756e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
368d768bd89SMartin Schwidefsky	BPOFF
3694bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
37056e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
37156e62a73SSven Schnelle	lghi	%r10,0
3724bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
37387d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
37487d59863SHeiko Carstens	jno	.Lpgm_skip_asce
37587d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
37656e62a73SSven Schnelle	j	3f			# -> fault in user space
37787d59863SHeiko Carstens.Lpgm_skip_asce:
378d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3790a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
380b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f
381fbbdfca5SAlexander Gordeev	SIEEXIT
38256e62a73SSven Schnelle	lghi	%r10,_PIF_GUEST_FAULT
383d0fc4107SMartin Schwidefsky#endif
3840b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
3850b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
3864bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
3874bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
3880b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
3894bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
39056e62a73SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 4f
39156e62a73SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
39256e62a73SSven Schnelle3:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3934bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
39456e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
39556e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
39656e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3974bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
39856e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3993b051e89SSven Schnelle	mvc	__PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK
40056e62a73SSven Schnelle	stmg	%r8,%r9,__PT_PSW(%r11)
40156e62a73SSven Schnelle
4027041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4037041d281SMartin Schwidefsky	xgr	%r0,%r0
4047041d281SMartin Schwidefsky	xgr	%r1,%r1
4057041d281SMartin Schwidefsky	xgr	%r3,%r3
4067041d281SMartin Schwidefsky	xgr	%r4,%r4
4077041d281SMartin Schwidefsky	xgr	%r5,%r5
4087041d281SMartin Schwidefsky	xgr	%r6,%r6
4097041d281SMartin Schwidefsky	xgr	%r7,%r7
41056e62a73SSven Schnelle	lgr	%r2,%r11
41156e62a73SSven Schnelle	brasl	%r14,__do_pgm_check
41256e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user space?
41356e62a73SSven Schnelle	jno	.Lpgm_exit_kernel
41456e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
41556e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
4160cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
41756e62a73SSven Schnelle.Lpgm_exit_kernel:
41856e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
4193b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
42056e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
4213b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
4224bfc86ceSHeiko Carstens
4234bfc86ceSHeiko Carstens#
4244bfc86ceSHeiko Carstens# single stepped system call
4254bfc86ceSHeiko Carstens#
4264bfc86ceSHeiko Carstens.Lpgm_svcper:
4274bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
4284bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
4294bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
43056e62a73SSven Schnelle	lghi	%r14,1
4313b051e89SSven Schnelle	LBEAR	__LC_PGM_LAST_BREAK
4323b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per
43326a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
4344bfc86ceSHeiko Carstens
4354bfc86ceSHeiko Carstens/*
43656e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4374bfc86ceSHeiko Carstens */
43856e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
43956e62a73SSven SchnelleENTRY(\name)
44010bc15baSVasily Gorbik	stckf	__LC_INT_CLOCK
44156e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
4423b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
443d768bd89SMartin Schwidefsky	BPOFF
4444bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
445d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
44656e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
447b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
448b0d31159SSven Schnelle	jnz	1f
449b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
450b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,0f
451fbbdfca5SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
452fbbdfca5SAlexander Gordeev	SIEEXIT
453b0d31159SSven Schnelle#endif
454b0d31159SSven Schnelle0:	CHECK_STACK __LC_SAVE_AREA_ASYNC
455b0d31159SSven Schnelle	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
456b0d31159SSven Schnelle	j	2f
457b0d31159SSven Schnelle1:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
458b0d31159SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
459b0d31159SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
460b74e409eSVasily Gorbik2:	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
461b74e409eSVasily Gorbik	la	%r11,STACK_FRAME_OVERHEAD(%r15)
4624bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4637041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4647041d281SMartin Schwidefsky	xgr	%r0,%r0
4657041d281SMartin Schwidefsky	xgr	%r1,%r1
4667041d281SMartin Schwidefsky	xgr	%r3,%r3
4677041d281SMartin Schwidefsky	xgr	%r4,%r4
4687041d281SMartin Schwidefsky	xgr	%r5,%r5
4697041d281SMartin Schwidefsky	xgr	%r6,%r6
4707041d281SMartin Schwidefsky	xgr	%r7,%r7
4717041d281SMartin Schwidefsky	xgr	%r10,%r10
472ca1f4d70SSven Schnelle	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
4734bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
4743b051e89SSven Schnelle	MBEAR	%r11
4754bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
47629b06ad7SHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
47756e62a73SSven Schnelle	brasl	%r14,\handler
4784bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
47956e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
48056e62a73SSven Schnelle	jno	2f
48187d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
4826b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4834bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4843b051e89SSven Schnelle2:	LBEAR	__PT_LAST_BREAK(%r11)
4853b051e89SSven Schnelle	lmg	%r0,%r15,__PT_R0(%r11)
4863b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
48756e62a73SSven SchnelleENDPROC(\name)
48856e62a73SSven Schnelle.endm
4894bfc86ceSHeiko Carstens
49056e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
49156e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
4924bfc86ceSHeiko Carstens
4934bfc86ceSHeiko Carstens/*
4940b0ed657SSven Schnelle * Load idle PSW.
4954bfc86ceSHeiko Carstens */
4964bfc86ceSHeiko CarstensENTRY(psw_idle)
497a994eddbSVasily Gorbik	stg	%r14,(__SF_GPRS+8*8)(%r15)
4984bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
49956e62a73SSven Schnelle	larl	%r1,psw_idle_exit
5004bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
50172d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
50272d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
50372d38b19SMartin Schwidefsky	ltgr	%r1,%r1
50472d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
50556e62a73SSven Schnelle	.insn	rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
50672d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
507419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
508d768bd89SMartin Schwidefsky	BPON
50910bc15baSVasily Gorbik	stckf	__CLOCK_IDLE_ENTER(%r2)
5104bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
5114bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
51256e62a73SSven Schnelle.globl psw_idle_exit
51356e62a73SSven Schnellepsw_idle_exit:
5146dd85fbbSMartin Schwidefsky	BR_EX	%r14
51526a374aeSMartin SchwidefskyENDPROC(psw_idle)
5164bfc86ceSHeiko Carstens
517b5510d9bSHendrik Brueckner/*
5184bfc86ceSHeiko Carstens * Machine check handler routines
5194bfc86ceSHeiko Carstens */
5204bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
52110bc15baSVasily Gorbik	stckf	__LC_MCCK_CLOCK
522d768bd89SMartin Schwidefsky	BPOFF
5233037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
5243037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
5253b051e89SSven Schnelle	LBEAR	__LC_LAST_BREAK_SAVE_AREA-4095(%r1)		# validate bear
5263037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
527d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
5284bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
52983abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
5304bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
5313037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
5323037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
5333037a52fSMartin Schwidefsky	la	%r14,4095
5343037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
5353037a52fSMartin Schwidefsky	ptlb
5365fa2ea07SAlexander Gordeev	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5374bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
53883abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5394bfc86ceSHeiko Carstens	jo	3f
54056e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
54156e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5424bfc86ceSHeiko Carstens	jl	1f
5434bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5444bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5454bfc86ceSHeiko Carstens	jl	2f
5464bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5474bfc86ceSHeiko Carstens2:	spt	0(%r14)
5484bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5493037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5503037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5513037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
552d35925b3SAlexander Gordeev	jnz	6f
5533037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5543037a52fSMartin Schwidefsky	jno	.Lmcck_panic
555b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
556d35925b3SAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,6f
557d35925b3SAlexander Gordeev	OUTSIDE	%r9,.Lsie_entry,.Lsie_skip,4f
55820232b18SAlexander Gordeev	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
559d35925b3SAlexander Gordeev	j	5f
560d35925b3SAlexander Gordeev4:	CHKSTG	.Lmcck_panic
561d35925b3SAlexander Gordeev5:	larl	%r14,.Lstosm_tmp
562d35925b3SAlexander Gordeev	stosm	0(%r14),0x04		# turn dat on, keep irqs off
563d35925b3SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
564fbbdfca5SAlexander Gordeev	SIEEXIT
565b61b1595SSven Schnelle	j	.Lmcck_stack
566e2c13d64SAlexander Gordeev#endif
567d35925b3SAlexander Gordeev6:	CHKSTG	.Lmcck_panic
568d35925b3SAlexander Gordeev	larl	%r14,.Lstosm_tmp
569d35925b3SAlexander Gordeev	stosm	0(%r14),0x04		# turn dat on, keep irqs off
570d35925b3SAlexander Gordeev	tmhh	%r8,0x0001		# interrupting from user ?
571d35925b3SAlexander Gordeev	jz	.Lmcck_stack
572b0d31159SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
573b61b1595SSven Schnelle.Lmcck_stack:
574b61b1595SSven Schnelle	lg	%r15,__LC_MCCK_STACK
575b61b1595SSven Schnelle	la	%r11,STACK_FRAME_OVERHEAD(%r15)
57626521412SSven Schnelle	stctg	%c1,%c1,__PT_CR1(%r11)
577b61b1595SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
578b61b1595SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5794bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5804bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5817041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5827041d281SMartin Schwidefsky	xgr	%r0,%r0
5837041d281SMartin Schwidefsky	xgr	%r1,%r1
5847041d281SMartin Schwidefsky	xgr	%r3,%r3
5857041d281SMartin Schwidefsky	xgr	%r4,%r4
5867041d281SMartin Schwidefsky	xgr	%r5,%r5
5877041d281SMartin Schwidefsky	xgr	%r6,%r6
5887041d281SMartin Schwidefsky	xgr	%r7,%r7
5897041d281SMartin Schwidefsky	xgr	%r10,%r10
5904bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
5914bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
5924bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
5934bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5944bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5954bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
5960b0ed657SSven Schnelle	cghi	%r2,0
5970b0ed657SSven Schnelle	je	.Lmcck_return
5984bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
5994bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
6004bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
6014bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
60239d62336SThomas Richter	lgr	%r2,%r11
6034bfc86ceSHeiko Carstens	lgr	%r15,%r1
6044bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
6054bfc86ceSHeiko Carstens.Lmcck_return:
60687d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
6074bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
6084bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
6094bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
6104bfc86ceSHeiko Carstens	jno	0f
6116b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
6124bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
613*fad442d3SHeiko Carstens0:	ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
6143b051e89SSven Schnelle	LBEAR	0(%r12)
6153b051e89SSven Schnelle	lmg	%r11,%r15,__PT_R11(%r11)
6163b051e89SSven Schnelle	LPSWEY	__LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
6174bfc86ceSHeiko Carstens
6184bfc86ceSHeiko Carstens.Lmcck_panic:
6197f6dc8d4SAlexander Gordeev	/*
6207f6dc8d4SAlexander Gordeev	 * Iterate over all possible CPU addresses in the range 0..0xffff
6217f6dc8d4SAlexander Gordeev	 * and stop each CPU using signal processor. Use compare and swap
6227f6dc8d4SAlexander Gordeev	 * to allow just one CPU-stopper and prevent concurrent CPUs from
6237f6dc8d4SAlexander Gordeev	 * stopping each other while leaving the others running.
6247f6dc8d4SAlexander Gordeev	 */
6257f6dc8d4SAlexander Gordeev	lhi	%r5,0
6267f6dc8d4SAlexander Gordeev	lhi	%r6,1
6277f6dc8d4SAlexander Gordeev	larl	%r7,.Lstop_lock
6287f6dc8d4SAlexander Gordeev	cs	%r5,%r6,0(%r7)		# single CPU-stopper only
6297f6dc8d4SAlexander Gordeev	jnz	4f
6307f6dc8d4SAlexander Gordeev	larl	%r7,.Lthis_cpu
6317f6dc8d4SAlexander Gordeev	stap	0(%r7)			# this CPU address
6327f6dc8d4SAlexander Gordeev	lh	%r4,0(%r7)
6337f6dc8d4SAlexander Gordeev	nilh	%r4,0
6347f6dc8d4SAlexander Gordeev	lhi	%r0,1
6357f6dc8d4SAlexander Gordeev	sll	%r0,16			# CPU counter
6367f6dc8d4SAlexander Gordeev	lhi	%r3,0			# next CPU address
6377f6dc8d4SAlexander Gordeev0:	cr	%r3,%r4
6387f6dc8d4SAlexander Gordeev	je	2f
6397f6dc8d4SAlexander Gordeev1:	sigp	%r1,%r3,SIGP_STOP	# stop next CPU
6407f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,1b
6417f6dc8d4SAlexander Gordeev2:	ahi	%r3,1
6427f6dc8d4SAlexander Gordeev	brct	%r0,0b
6437f6dc8d4SAlexander Gordeev3:	sigp	%r1,%r4,SIGP_STOP	# stop this CPU
6447f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,3b
6457f6dc8d4SAlexander Gordeev4:	j	4b
64626a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
6474bfc86ceSHeiko Carstens
6484bfc86ceSHeiko CarstensENTRY(restart_int_handler)
649*fad442d3SHeiko Carstens	ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
650e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
651915fea04SAlexander Gordeev	TSTMSK	__LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
652915fea04SAlexander Gordeev	jz	0f
653915fea04SAlexander Gordeev	la	%r15,4095
654915fea04SAlexander Gordeev	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15)
655915fea04SAlexander Gordeev0:	larl	%r15,.Lstosm_tmp
656915fea04SAlexander Gordeev	stosm	0(%r15),0x04			# turn dat on, keep irqs off
6574bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
658ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
659ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
660ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
661ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
6624bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
6634bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
6644bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
665915fea04SAlexander Gordeev	lgf	%r3,__LC_RESTART_SOURCE
6664bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
6674bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
6684bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
6694bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
6704bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
6714bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
6724bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
6734bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
6744bfc86ceSHeiko Carstens	brc	2,2b
6754bfc86ceSHeiko Carstens3:	j	3b
67626a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
6774bfc86ceSHeiko Carstens
6784bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
6794bfc86ceSHeiko Carstens
680ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
6814bfc86ceSHeiko Carstens/*
6824bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
6834bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
6844bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
6854bfc86ceSHeiko Carstens */
68626a374aeSMartin SchwidefskyENTRY(stack_overflow)
687ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
6884bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6894bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6904bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6914bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
6924bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
6934bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6944bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6954bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
69626a374aeSMartin SchwidefskyENDPROC(stack_overflow)
6974bfc86ceSHeiko Carstens#endif
6984bfc86ceSHeiko Carstens
6997f6dc8d4SAlexander Gordeev	.section .data, "aw"
7007f6dc8d4SAlexander Gordeev		.align	4
7017f6dc8d4SAlexander Gordeev.Lstop_lock:	.long	0
7027f6dc8d4SAlexander Gordeev.Lthis_cpu:	.short	0
703d35925b3SAlexander Gordeev.Lstosm_tmp:	.byte	0
7044bfc86ceSHeiko Carstens	.section .rodata, "a"
705ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
7064bfc86ceSHeiko Carstens	.globl	sys_call_table
7074bfc86ceSHeiko Carstenssys_call_table:
7084381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
7094bfc86ceSHeiko Carstens#undef SYSCALL
7104bfc86ceSHeiko Carstens
7114bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
7124bfc86ceSHeiko Carstens
713ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
7144bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
7154bfc86ceSHeiko Carstenssys_call_table_emu:
7164381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
7174bfc86ceSHeiko Carstens#undef SYSCALL
7184bfc86ceSHeiko Carstens#endif
719