xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 56e62a73702836017564eaacd5212e4d0fa1c01d)
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>
173037a52fSMartin Schwidefsky#include <asm/ctl_reg.h>
18dc24b7b4SHendrik Brueckner#include <asm/dwarf.h>
194bfc86ceSHeiko Carstens#include <asm/errno.h>
204bfc86ceSHeiko Carstens#include <asm/ptrace.h>
214bfc86ceSHeiko Carstens#include <asm/thread_info.h>
224bfc86ceSHeiko Carstens#include <asm/asm-offsets.h>
234bfc86ceSHeiko Carstens#include <asm/unistd.h>
244bfc86ceSHeiko Carstens#include <asm/page.h>
254bfc86ceSHeiko Carstens#include <asm/sigp.h>
264bfc86ceSHeiko Carstens#include <asm/irq.h>
279977e886SHendrik Brueckner#include <asm/vx-insn.h>
2883abeffbSHendrik Brueckner#include <asm/setup.h>
2983abeffbSHendrik Brueckner#include <asm/nmi.h>
30711f5df7SAl Viro#include <asm/export.h>
316dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h>
324bfc86ceSHeiko Carstens
334bfc86ceSHeiko Carstens__PT_R0      =	__PT_GPRS
344bfc86ceSHeiko Carstens__PT_R1      =	__PT_GPRS + 8
354bfc86ceSHeiko Carstens__PT_R2      =	__PT_GPRS + 16
364bfc86ceSHeiko Carstens__PT_R3      =	__PT_GPRS + 24
374bfc86ceSHeiko Carstens__PT_R4      =	__PT_GPRS + 32
384bfc86ceSHeiko Carstens__PT_R5      =	__PT_GPRS + 40
394bfc86ceSHeiko Carstens__PT_R6      =	__PT_GPRS + 48
404bfc86ceSHeiko Carstens__PT_R7      =	__PT_GPRS + 56
414bfc86ceSHeiko Carstens__PT_R8      =	__PT_GPRS + 64
424bfc86ceSHeiko Carstens__PT_R9      =	__PT_GPRS + 72
434bfc86ceSHeiko Carstens__PT_R10     =	__PT_GPRS + 80
444bfc86ceSHeiko Carstens__PT_R11     =	__PT_GPRS + 88
454bfc86ceSHeiko Carstens__PT_R12     =	__PT_GPRS + 96
464bfc86ceSHeiko Carstens__PT_R13     =	__PT_GPRS + 104
474bfc86ceSHeiko Carstens__PT_R14     =	__PT_GPRS + 112
484bfc86ceSHeiko Carstens__PT_R15     =	__PT_GPRS + 120
494bfc86ceSHeiko Carstens
503a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER
514bfc86ceSHeiko CarstensSTACK_SIZE  = 1 << STACK_SHIFT
524bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
534bfc86ceSHeiko Carstens
54e5b98199SMartin Schwidefsky_LPP_OFFSET	= __LC_LPP
55e5b98199SMartin Schwidefsky
56ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
574bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
58ce3dc447SMartin Schwidefsky	tml	%r15,STACK_SIZE - CONFIG_STACK_GUARD
594bfc86ceSHeiko Carstens	lghi	%r14,\savearea
604bfc86ceSHeiko Carstens	jz	stack_overflow
614bfc86ceSHeiko Carstens#endif
624bfc86ceSHeiko Carstens	.endm
634bfc86ceSHeiko Carstens
64ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
65ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
66ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
67ce3dc447SMartin Schwidefsky	nill	%r14,0x10000 - STACK_SIZE
68ce3dc447SMartin Schwidefsky	oill	%r14,STACK_INIT
69ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
70ce3dc447SMartin Schwidefsky	je	\oklabel
71ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
72ce3dc447SMartin Schwidefsky	je	\oklabel
73ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
74ce3dc447SMartin Schwidefsky	je	\oklabel
75ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
76ce3dc447SMartin Schwidefsky	je	\oklabel
77ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
78ce3dc447SMartin Schwidefsky	j	stack_overflow
79ce3dc447SMartin Schwidefsky#else
80ce3dc447SMartin Schwidefsky	j	\oklabel
81ce3dc447SMartin Schwidefsky#endif
82ce3dc447SMartin Schwidefsky	.endm
83ce3dc447SMartin Schwidefsky
84*56e62a73SSven Schnelle	.macro	SWITCH_KERNEL savearea
854bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# interrupting from user ?
86*56e62a73SSven Schnelle	jnz	1f
870b0ed657SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
884bfc86ceSHeiko Carstens	lgr	%r14,%r9
890b0ed657SSven Schnelle	larl	%r13,.Lsie_gmap
900b0ed657SSven Schnelle	slgr	%r14,%r13
910b0ed657SSven Schnelle	lghi	%r13,.Lsie_done - .Lsie_gmap
920b0ed657SSven Schnelle	clgr	%r14,%r13
930b0ed657SSven Schnelle	jhe	0f
944bfc86ceSHeiko Carstens	lghi	%r11,\savearea		# inside critical section, do cleanup
950b0ed657SSven Schnelle	brasl	%r14,.Lcleanup_sie
960b0ed657SSven Schnelle#endif
97*56e62a73SSven Schnelle0:	CHECK_STACK \savearea
98*56e62a73SSven Schnelle	lgr	%r11,%r15
994bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
100*56e62a73SSven Schnelle	stg	%r11,__SF_BACKCHAIN(%r15)
101*56e62a73SSven Schnelle	j	2f
102*56e62a73SSven Schnelle1:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
103*56e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
104*56e62a73SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
105*56e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
106*56e62a73SSven Schnelle2:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
1070b0ed657SSven Schnelle	.endm
1080b0ed657SSven Schnelle
1094bfc86ceSHeiko Carstens	.macro STCK savearea
1104bfc86ceSHeiko Carstens#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
1114bfc86ceSHeiko Carstens	.insn	s,0xb27c0000,\savearea		# store clock fast
1124bfc86ceSHeiko Carstens#else
1134bfc86ceSHeiko Carstens	.insn	s,0xb2050000,\savearea		# store clock
1144bfc86ceSHeiko Carstens#endif
1154bfc86ceSHeiko Carstens	.endm
1164bfc86ceSHeiko Carstens
11783abeffbSHendrik Brueckner	/*
11883abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
11983abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
12083abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
12183abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
12283abeffbSHendrik Brueckner	 * instruction.
12383abeffbSHendrik Brueckner	 */
12483abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
12583abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
12683abeffbSHendrik Brueckner			.if (\mask & 0xff)
12783abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
12883abeffbSHendrik Brueckner			.endif
12983abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
13083abeffbSHendrik Brueckner			.exitm
13183abeffbSHendrik Brueckner		.endif
13283abeffbSHendrik Brueckner		.ifeq \mask
13383abeffbSHendrik Brueckner			.error "Mask must not be zero"
13483abeffbSHendrik Brueckner		.endif
13583abeffbSHendrik Brueckner		off = \size - \bytepos - 1
13683abeffbSHendrik Brueckner		tm	off+\addr, \mask
13783abeffbSHendrik Brueckner	.endm
13883abeffbSHendrik Brueckner
139d768bd89SMartin Schwidefsky	.macro BPOFF
140b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
141d768bd89SMartin Schwidefsky	.endm
142d768bd89SMartin Schwidefsky
143d768bd89SMartin Schwidefsky	.macro BPON
144b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
145d768bd89SMartin Schwidefsky	.endm
146d768bd89SMartin Schwidefsky
1476b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
148b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
149b058661aSMartin Schwidefsky		    "", 82
1506b73044bSMartin Schwidefsky	.endm
1516b73044bSMartin Schwidefsky
1526b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1536b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
154b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
155b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
1566b73044bSMartin Schwidefsky	.endm
1576b73044bSMartin Schwidefsky
1586dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
1596dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14,%r11
160f19fbd5eSMartin Schwidefsky
1614bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
16246210c44SHeiko Carstens.Ldummy:
16346210c44SHeiko Carstens	/*
164*56e62a73SSven Schnelle	 * This nop exists only in order to avoid that __bpon starts at
16546210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
16646210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
16746210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
168*56e62a73SSven Schnelle	 * With the added nop in between the __bpon symbol is unique
16946210c44SHeiko Carstens	 * again.
17046210c44SHeiko Carstens	 */
17146210c44SHeiko Carstens	nop	0
1724bfc86ceSHeiko Carstens
173d768bd89SMartin SchwidefskyENTRY(__bpon)
174d768bd89SMartin Schwidefsky	.globl __bpon
175d768bd89SMartin Schwidefsky	BPON
1766dd85fbbSMartin Schwidefsky	BR_EX	%r14
17726a374aeSMartin SchwidefskyENDPROC(__bpon)
178d768bd89SMartin Schwidefsky
1794bfc86ceSHeiko Carstens/*
1804bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
1814bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
1824bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
1834bfc86ceSHeiko Carstens * Returns:
1844bfc86ceSHeiko Carstens *  gpr2 = prev
1854bfc86ceSHeiko Carstens */
1864bfc86ceSHeiko CarstensENTRY(__switch_to)
1874bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
1883241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
1893241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
1909fed920eSVasily Gorbik	llill	%r5,STACK_INIT
1913241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
1929fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
1939fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
1944bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
1954bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
1963241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
1973241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
1983241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
1994bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
200e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2016dd85fbbSMartin Schwidefsky	BR_EX	%r14
20226a374aeSMartin SchwidefskyENDPROC(__switch_to)
2034bfc86ceSHeiko Carstens
204d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
205d0fc4107SMartin Schwidefsky/*
206d0fc4107SMartin Schwidefsky * sie64a calling convention:
207d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
208d0fc4107SMartin Schwidefsky * %r3 guest register save area
209d0fc4107SMartin Schwidefsky */
210d0fc4107SMartin SchwidefskyENTRY(sie64a)
211d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2126b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
21392fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
21492fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
21592fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
21692fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
217d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
218d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
219d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
220d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
221d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
222d0fc4107SMartin Schwidefsky.Lsie_gmap:
22392fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
224d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
225d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
226d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
22783abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
228d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
22992fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
230c929500dSQingFeng Hao.Lsie_entry:
231d0fc4107SMartin Schwidefsky	sie	0(%r14)
232d768bd89SMartin Schwidefsky	BPOFF
23392fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
234d0fc4107SMartin Schwidefsky.Lsie_skip:
235d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
23687d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
237d0fc4107SMartin Schwidefsky.Lsie_done:
238d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
239c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
240c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
241c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
242c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
243d0fc4107SMartin Schwidefsky# See also .Lcleanup_sie
244c0e7bb38SChristian Borntraeger.Lrewind_pad6:
245c0e7bb38SChristian Borntraeger	nopr	7
246c0e7bb38SChristian Borntraeger.Lrewind_pad4:
247c0e7bb38SChristian Borntraeger	nopr	7
248c0e7bb38SChristian Borntraeger.Lrewind_pad2:
249c0e7bb38SChristian Borntraeger	nopr	7
250d0fc4107SMartin Schwidefsky	.globl sie_exit
251d0fc4107SMartin Schwidefskysie_exit:
25292fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
253d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2547041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2557041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2567041d281SMartin Schwidefsky	xgr	%r3,%r3
2577041d281SMartin Schwidefsky	xgr	%r4,%r4
2587041d281SMartin Schwidefsky	xgr	%r5,%r5
259d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
26092fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
2616dd85fbbSMartin Schwidefsky	BR_EX	%r14
262d0fc4107SMartin Schwidefsky.Lsie_fault:
263d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
26492fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
265d0fc4107SMartin Schwidefsky	j	sie_exit
266d0fc4107SMartin Schwidefsky
267c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
268c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
269c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
270d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
27126a374aeSMartin SchwidefskyENDPROC(sie64a)
272711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
273711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
274d0fc4107SMartin Schwidefsky#endif
275d0fc4107SMartin Schwidefsky
2764bfc86ceSHeiko Carstens/*
2774bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
2787b7735c5SChristian Borntraeger * are entered with interrupts disabled.
2794bfc86ceSHeiko Carstens */
2804bfc86ceSHeiko Carstens
2814bfc86ceSHeiko CarstensENTRY(system_call)
282*56e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
2834bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
284d768bd89SMartin Schwidefsky	BPOFF
285*56e62a73SSven Schnelle	lghi	%r14,0
2864bfc86ceSHeiko Carstens.Lsysc_per:
28787d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
288*56e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
2894bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
2909365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
291*56e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
292*56e62a73SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
293d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
294d3f46896SChristian Borntraeger	xgr	%r0,%r0
295*56e62a73SSven Schnelle	xgr	%r1,%r1
296*56e62a73SSven Schnelle	xgr	%r4,%r4
297*56e62a73SSven Schnelle	xgr	%r5,%r5
298*56e62a73SSven Schnelle	xgr	%r6,%r6
299*56e62a73SSven Schnelle	xgr	%r7,%r7
300*56e62a73SSven Schnelle	xgr	%r8,%r8
301*56e62a73SSven Schnelle	xgr	%r9,%r9
302*56e62a73SSven Schnelle	xgr	%r10,%r10
303*56e62a73SSven Schnelle	xgr	%r11,%r11
304*56e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
305*56e62a73SSven Schnelle	lgr	%r3,%r14
306*56e62a73SSven Schnelle	brasl	%r14,__do_syscall
30787d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
308*56e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3096b73044bSMartin Schwidefsky	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
310*56e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3114bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3120b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
31326a374aeSMartin SchwidefskyENDPROC(system_call)
3144bfc86ceSHeiko Carstens
3154bfc86ceSHeiko Carstens#
3164bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3174bfc86ceSHeiko Carstens#
3184bfc86ceSHeiko CarstensENTRY(ret_from_fork)
319*56e62a73SSven Schnelle	lgr	%r3,%r11
320*56e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
321*56e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
322*56e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
323*56e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
324*56e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
325*56e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
326*56e62a73SSven Schnelle	b	__LC_RETURN_LPSWE
32726a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
32826a374aeSMartin Schwidefsky
3294bfc86ceSHeiko Carstens/*
3304bfc86ceSHeiko Carstens * Program check handler routine
3314bfc86ceSHeiko Carstens */
3324bfc86ceSHeiko Carstens
3334bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
334*56e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
335d768bd89SMartin Schwidefsky	BPOFF
3364bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
337*56e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
338*56e62a73SSven Schnelle	lghi	%r10,0
3394bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
34087d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
34187d59863SHeiko Carstens	jno	.Lpgm_skip_asce
34287d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
343*56e62a73SSven Schnelle	j	3f			# -> fault in user space
34487d59863SHeiko Carstens.Lpgm_skip_asce:
345d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3460a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
347d0fc4107SMartin Schwidefsky	lgr	%r14,%r9
3480b0ed657SSven Schnelle	larl	%r13,.Lsie_gmap
3490b0ed657SSven Schnelle	slgr	%r14,%r13
3500b0ed657SSven Schnelle	lghi	%r13,.Lsie_done - .Lsie_gmap
3510b0ed657SSven Schnelle	clgr	%r14,%r13
3520b38b5e1SSven Schnelle	jhe	1f
35392fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
3540a5e2ec2SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
35587d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
3560a5e2ec2SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
357*56e62a73SSven Schnelle	lghi	%r10,_PIF_GUEST_FAULT
358d0fc4107SMartin Schwidefsky#endif
3590b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
3600b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
3614bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
3624bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
3630b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
3644bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
365*56e62a73SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 4f
366*56e62a73SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
367*56e62a73SSven Schnelle3:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3684bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
369*56e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
370*56e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
371*56e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3724bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
373*56e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
374*56e62a73SSven Schnelle	stmg	%r8,%r9,__PT_PSW(%r11)
375*56e62a73SSven Schnelle
3767041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
3777041d281SMartin Schwidefsky	xgr	%r0,%r0
3787041d281SMartin Schwidefsky	xgr	%r1,%r1
3797041d281SMartin Schwidefsky	xgr	%r3,%r3
3807041d281SMartin Schwidefsky	xgr	%r4,%r4
3817041d281SMartin Schwidefsky	xgr	%r5,%r5
3827041d281SMartin Schwidefsky	xgr	%r6,%r6
3837041d281SMartin Schwidefsky	xgr	%r7,%r7
384*56e62a73SSven Schnelle	lgr	%r2,%r11
385*56e62a73SSven Schnelle	brasl	%r14,__do_pgm_check
386*56e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user space?
387*56e62a73SSven Schnelle	jno	.Lpgm_exit_kernel
388*56e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
389*56e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
3900cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
391*56e62a73SSven Schnelle.Lpgm_exit_kernel:
392*56e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
393*56e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3940cd9b723SHeiko Carstens	b	__LC_RETURN_LPSWE
3954bfc86ceSHeiko Carstens
3964bfc86ceSHeiko Carstens#
3974bfc86ceSHeiko Carstens# single stepped system call
3984bfc86ceSHeiko Carstens#
3994bfc86ceSHeiko Carstens.Lpgm_svcper:
4004bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
4014bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
4024bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
403*56e62a73SSven Schnelle	lghi	%r14,1
4040b0ed657SSven Schnelle	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per
40526a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
4064bfc86ceSHeiko Carstens
4074bfc86ceSHeiko Carstens/*
408*56e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4094bfc86ceSHeiko Carstens */
410*56e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
411*56e62a73SSven SchnelleENTRY(\name)
4124bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
413*56e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
414d768bd89SMartin Schwidefsky	BPOFF
4154bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
416d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
417*56e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
418*56e62a73SSven Schnelle	SWITCH_KERNEL __LC_SAVE_AREA_ASYNC
4194bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4207041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4217041d281SMartin Schwidefsky	xgr	%r0,%r0
4227041d281SMartin Schwidefsky	xgr	%r1,%r1
4237041d281SMartin Schwidefsky	xgr	%r3,%r3
4247041d281SMartin Schwidefsky	xgr	%r4,%r4
4257041d281SMartin Schwidefsky	xgr	%r5,%r5
4267041d281SMartin Schwidefsky	xgr	%r6,%r6
4277041d281SMartin Schwidefsky	xgr	%r7,%r7
4287041d281SMartin Schwidefsky	xgr	%r10,%r10
4294bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
4304bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
431*56e62a73SSven Schnelle	tm	%r8,0x0001		# coming from user space?
432*56e62a73SSven Schnelle	jno	1f
43387d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
434*56e62a73SSven Schnelle1:	lgr	%r2,%r11		# pass pointer to pt_regs
435*56e62a73SSven Schnelle	brasl	%r14,\handler
4364bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
437*56e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
438*56e62a73SSven Schnelle	jno	2f
43987d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
4406b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4414bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
442*56e62a73SSven Schnelle2:	lmg	%r0,%r15,__PT_R0(%r11)
4430b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
444*56e62a73SSven SchnelleENDPROC(\name)
445*56e62a73SSven Schnelle.endm
4464bfc86ceSHeiko Carstens
447*56e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
448*56e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
4494bfc86ceSHeiko Carstens
4504bfc86ceSHeiko Carstens/*
4510b0ed657SSven Schnelle * Load idle PSW.
4524bfc86ceSHeiko Carstens */
4534bfc86ceSHeiko CarstensENTRY(psw_idle)
4544bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
455*56e62a73SSven Schnelle	larl	%r1,psw_idle_exit
4564bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
45772d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
45872d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
45972d38b19SMartin Schwidefsky	ltgr	%r1,%r1
46072d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
461*56e62a73SSven Schnelle	.insn	rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
46272d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
463419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
464d768bd89SMartin Schwidefsky	BPON
4654bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
4664bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
4674bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
468*56e62a73SSven Schnelle.globl psw_idle_exit
469*56e62a73SSven Schnellepsw_idle_exit:
4706dd85fbbSMartin Schwidefsky	BR_EX	%r14
47126a374aeSMartin SchwidefskyENDPROC(psw_idle)
4724bfc86ceSHeiko Carstens
473b5510d9bSHendrik Brueckner/*
4744bfc86ceSHeiko Carstens * Machine check handler routines
4754bfc86ceSHeiko Carstens */
4764bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
4774bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
478d768bd89SMartin Schwidefsky	BPOFF
4793037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
4803037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
4813037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
4823037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
4833037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
484d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
4854bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
48683abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
4874bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
4883037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
4893037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
4903037a52fSMartin Schwidefsky	la	%r14,4095
4913037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
4923037a52fSMartin Schwidefsky	ptlb
4932a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
4943037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
4953037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
4963037a52fSMartin Schwidefsky	jno	0f
4973037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
4983037a52fSMartin Schwidefsky	jno	0f
4993037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
5003037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
5013037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
5023037a52fSMartin Schwidefsky	jo	0f
5033037a52fSMartin Schwidefsky	sr	%r14,%r14
5043037a52fSMartin Schwidefsky0:	sfpc	%r14
5053037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
5063037a52fSMartin Schwidefsky	jo	0f
5073037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
5083037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
5093037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
5103037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
5113037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
5123037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
5133037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
5143037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
5153037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
5163037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
5173037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
5183037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
5193037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
5203037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
5213037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
5223037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
5233037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
5243037a52fSMartin Schwidefsky	j	1f
5253037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
5263037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
5273037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5284bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
52983abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5304bfc86ceSHeiko Carstens	jo	3f
531*56e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
532*56e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5334bfc86ceSHeiko Carstens	jl	1f
5344bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5354bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5364bfc86ceSHeiko Carstens	jl	2f
5374bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5384bfc86ceSHeiko Carstens2:	spt	0(%r14)
5394bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5403037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5413037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5423037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
5433037a52fSMartin Schwidefsky	jnz	4f
5443037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5453037a52fSMartin Schwidefsky	jno	.Lmcck_panic
546ce3dc447SMartin Schwidefsky4:	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
547*56e62a73SSven Schnelle	SWITCH_KERNEL __LC_GPREGS_SAVE_AREA+64
5484bfc86ceSHeiko Carstens.Lmcck_skip:
5494bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5504bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5517041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5527041d281SMartin Schwidefsky	xgr	%r0,%r0
5537041d281SMartin Schwidefsky	xgr	%r1,%r1
5547041d281SMartin Schwidefsky	xgr	%r3,%r3
5557041d281SMartin Schwidefsky	xgr	%r4,%r4
5567041d281SMartin Schwidefsky	xgr	%r5,%r5
5577041d281SMartin Schwidefsky	xgr	%r6,%r6
5587041d281SMartin Schwidefsky	xgr	%r7,%r7
5597041d281SMartin Schwidefsky	xgr	%r10,%r10
5604bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
5614bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
56287d59863SHeiko Carstens	la	%r14,4095
56387d59863SHeiko Carstens	mvc	__PT_CR1(8,%r11),__LC_CREGS_SAVE_AREA-4095+8(%r14)
5644bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
5654bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5664bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5674bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
5680b0ed657SSven Schnelle	cghi	%r2,0
5690b0ed657SSven Schnelle	je	.Lmcck_return
5704bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
5714bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
5724bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
5734bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
5744bfc86ceSHeiko Carstens	lgr	%r15,%r1
5754bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
5764bfc86ceSHeiko Carstens.Lmcck_return:
57787d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
5784bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
5794bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
5804bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
5814bfc86ceSHeiko Carstens	jno	0f
5826b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
5834bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
5844bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
5850b38b5e1SSven Schnelle	b	__LC_RETURN_MCCK_LPSWE
5864bfc86ceSHeiko Carstens
5874bfc86ceSHeiko Carstens.Lmcck_panic:
588ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK
589ce4dda3fSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
5904bfc86ceSHeiko Carstens	j	.Lmcck_skip
59126a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
5924bfc86ceSHeiko Carstens
5934bfc86ceSHeiko Carstens#
5944bfc86ceSHeiko Carstens# PSW restart interrupt handler
5954bfc86ceSHeiko Carstens#
5964bfc86ceSHeiko CarstensENTRY(restart_int_handler)
597e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
598e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
5994bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
600ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
601ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
602ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
603ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
6044bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
6054bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
6064bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
6074bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
6084bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
6094bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
6104bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
6114bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
6124bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
6134bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
6144bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
6154bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
6164bfc86ceSHeiko Carstens	brc	2,2b
6174bfc86ceSHeiko Carstens3:	j	3b
61826a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
6194bfc86ceSHeiko Carstens
6204bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
6214bfc86ceSHeiko Carstens
622ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
6234bfc86ceSHeiko Carstens/*
6244bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
6254bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
6264bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
6274bfc86ceSHeiko Carstens */
62826a374aeSMartin SchwidefskyENTRY(stack_overflow)
629ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
6304bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6314bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6324bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6334bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
6344bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
6354bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6364bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6374bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
63826a374aeSMartin SchwidefskyENDPROC(stack_overflow)
6394bfc86ceSHeiko Carstens#endif
6404bfc86ceSHeiko Carstens
641d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
642d0fc4107SMartin Schwidefsky.Lcleanup_sie:
643c929500dSQingFeng Hao	cghi	%r11,__LC_SAVE_AREA_ASYNC	#Is this in normal interrupt?
644c929500dSQingFeng Hao	je	1f
6450b0ed657SSven Schnelle	larl	%r13,.Lsie_entry
6460b0ed657SSven Schnelle	slgr	%r9,%r13
6470b0ed657SSven Schnelle	larl	%r13,.Lsie_skip
6480b0ed657SSven Schnelle	clgr	%r9,%r13
649c929500dSQingFeng Hao	jh	1f
650c929500dSQingFeng Hao	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
65192fa7a13SMartin Schwidefsky1:	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
65292fa7a13SMartin Schwidefsky	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
653e22cf8caSChristian Borntraeger	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
65487d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
655d0fc4107SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
656891f6a72SChristian Borntraeger	BR_EX	%r14,%r11
6574bfc86ceSHeiko Carstens
6584bfc86ceSHeiko Carstens#endif
6594bfc86ceSHeiko Carstens	.section .rodata, "a"
660ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
6614bfc86ceSHeiko Carstens	.globl	sys_call_table
6624bfc86ceSHeiko Carstenssys_call_table:
6634381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
6644bfc86ceSHeiko Carstens#undef SYSCALL
6654bfc86ceSHeiko Carstens
6664bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
6674bfc86ceSHeiko Carstens
668ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
6694bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
6704bfc86ceSHeiko Carstenssys_call_table_emu:
6714381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
6724bfc86ceSHeiko Carstens#undef SYSCALL
6734bfc86ceSHeiko Carstens#endif
674