xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 7f6dc8d4c880f64b9d450d780d88985b264d8793)
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
73b61b1595SSven Schnelle	clg	%r14,__LC_MCCK_STACK
74b61b1595SSven Schnelle	je	\oklabel
75ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
76ce3dc447SMartin Schwidefsky	je	\oklabel
77ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
78ce3dc447SMartin Schwidefsky	je	\oklabel
79ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
80ce3dc447SMartin Schwidefsky	j	stack_overflow
81ce3dc447SMartin Schwidefsky#else
82ce3dc447SMartin Schwidefsky	j	\oklabel
83ce3dc447SMartin Schwidefsky#endif
84ce3dc447SMartin Schwidefsky	.endm
85ce3dc447SMartin Schwidefsky
864bfc86ceSHeiko Carstens	.macro STCK savearea
8778f65709SHeiko Carstens	ALTERNATIVE ".insn	s,0xb2050000,\savearea", \
8878f65709SHeiko Carstens		    ".insn	s,0xb27c0000,\savearea", 25
894bfc86ceSHeiko Carstens	.endm
904bfc86ceSHeiko Carstens
9183abeffbSHendrik Brueckner	/*
9283abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
9383abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
9483abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
9583abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
9683abeffbSHendrik Brueckner	 * instruction.
9783abeffbSHendrik Brueckner	 */
9883abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
9983abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
10083abeffbSHendrik Brueckner			.if (\mask & 0xff)
10183abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
10283abeffbSHendrik Brueckner			.endif
10383abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
10483abeffbSHendrik Brueckner			.exitm
10583abeffbSHendrik Brueckner		.endif
10683abeffbSHendrik Brueckner		.ifeq \mask
10783abeffbSHendrik Brueckner			.error "Mask must not be zero"
10883abeffbSHendrik Brueckner		.endif
10983abeffbSHendrik Brueckner		off = \size - \bytepos - 1
11083abeffbSHendrik Brueckner		tm	off+\addr, \mask
11183abeffbSHendrik Brueckner	.endm
11283abeffbSHendrik Brueckner
113d768bd89SMartin Schwidefsky	.macro BPOFF
114b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
115d768bd89SMartin Schwidefsky	.endm
116d768bd89SMartin Schwidefsky
117d768bd89SMartin Schwidefsky	.macro BPON
118b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
119d768bd89SMartin Schwidefsky	.endm
120d768bd89SMartin Schwidefsky
1216b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
122b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
123b058661aSMartin Schwidefsky		    "", 82
1246b73044bSMartin Schwidefsky	.endm
1256b73044bSMartin Schwidefsky
1266b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1276b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
128b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
129b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
1306b73044bSMartin Schwidefsky	.endm
1316b73044bSMartin Schwidefsky
132b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM)
133b5415c8fSAlexander Gordeev	/*
134b5415c8fSAlexander Gordeev	 * The OUTSIDE macro jumps to the provided label in case the value
135b5415c8fSAlexander Gordeev	 * in the provided register is outside of the provided range. The
136b5415c8fSAlexander Gordeev	 * macro is useful for checking whether a PSW stored in a register
137b5415c8fSAlexander Gordeev	 * pair points inside or outside of a block of instructions.
138b5415c8fSAlexander Gordeev	 * @reg: register to check
139b5415c8fSAlexander Gordeev	 * @start: start of the range
140b5415c8fSAlexander Gordeev	 * @end: end of the range
141b5415c8fSAlexander Gordeev	 * @outside_label: jump here if @reg is outside of [@start..@end)
142b5415c8fSAlexander Gordeev	 */
143b5415c8fSAlexander Gordeev	.macro OUTSIDE reg,start,end,outside_label
144b5415c8fSAlexander Gordeev	lgr	%r14,\reg
145b5415c8fSAlexander Gordeev	larl	%r13,\start
146b5415c8fSAlexander Gordeev	slgr	%r14,%r13
147b5415c8fSAlexander Gordeev	lghi	%r13,\end - \start
148b5415c8fSAlexander Gordeev	clgr	%r14,%r13
149b5415c8fSAlexander Gordeev	jhe	\outside_label
150b5415c8fSAlexander Gordeev	.endm
151fbbdfca5SAlexander Gordeev
152fbbdfca5SAlexander Gordeev	.macro SIEEXIT
153fbbdfca5SAlexander Gordeev	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
154fbbdfca5SAlexander Gordeev	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
155fbbdfca5SAlexander Gordeev	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
156fbbdfca5SAlexander Gordeev	larl	%r9,sie_exit			# skip forward to sie_exit
157fbbdfca5SAlexander Gordeev	.endm
158b5415c8fSAlexander Gordeev#endif
159b5415c8fSAlexander Gordeev
1606dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
16133ea0487SSven Schnelle	GEN_BR_THUNK %r14,%r13
162f19fbd5eSMartin Schwidefsky
1634bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
16446210c44SHeiko Carstens.Ldummy:
16546210c44SHeiko Carstens	/*
16656e62a73SSven Schnelle	 * This nop exists only in order to avoid that __bpon starts at
16746210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
16846210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
16946210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
17056e62a73SSven Schnelle	 * With the added nop in between the __bpon symbol is unique
17146210c44SHeiko Carstens	 * again.
17246210c44SHeiko Carstens	 */
17346210c44SHeiko Carstens	nop	0
1744bfc86ceSHeiko Carstens
175d768bd89SMartin SchwidefskyENTRY(__bpon)
176d768bd89SMartin Schwidefsky	.globl __bpon
177d768bd89SMartin Schwidefsky	BPON
1786dd85fbbSMartin Schwidefsky	BR_EX	%r14
17926a374aeSMartin SchwidefskyENDPROC(__bpon)
180d768bd89SMartin Schwidefsky
1814bfc86ceSHeiko Carstens/*
1824bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
1834bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
1844bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
1854bfc86ceSHeiko Carstens * Returns:
1864bfc86ceSHeiko Carstens *  gpr2 = prev
1874bfc86ceSHeiko Carstens */
1884bfc86ceSHeiko CarstensENTRY(__switch_to)
1894bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
1903241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
1913241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
1929fed920eSVasily Gorbik	llill	%r5,STACK_INIT
1933241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
1949fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
1959fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
1964bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
1974bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
1983241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
1993241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2003241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2014bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
202e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2036dd85fbbSMartin Schwidefsky	BR_EX	%r14
20426a374aeSMartin SchwidefskyENDPROC(__switch_to)
2054bfc86ceSHeiko Carstens
206d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
207d0fc4107SMartin Schwidefsky/*
208d0fc4107SMartin Schwidefsky * sie64a calling convention:
209d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
210d0fc4107SMartin Schwidefsky * %r3 guest register save area
211d0fc4107SMartin Schwidefsky */
212d0fc4107SMartin SchwidefskyENTRY(sie64a)
213d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2146b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
21592fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
21692fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
21792fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
21892fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
219d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
220d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
221d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
222d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
223d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
224d0fc4107SMartin Schwidefsky.Lsie_gmap:
22592fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
226d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
227d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
228d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
22983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
230d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
23192fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
232c929500dSQingFeng Hao.Lsie_entry:
233d0fc4107SMartin Schwidefsky	sie	0(%r14)
234d768bd89SMartin Schwidefsky	BPOFF
23592fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
236d0fc4107SMartin Schwidefsky.Lsie_skip:
237d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
23887d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
239d0fc4107SMartin Schwidefsky.Lsie_done:
240d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
241c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
242c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
243c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
244c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
245c0e7bb38SChristian Borntraeger.Lrewind_pad6:
246c0e7bb38SChristian Borntraeger	nopr	7
247c0e7bb38SChristian Borntraeger.Lrewind_pad4:
248c0e7bb38SChristian Borntraeger	nopr	7
249c0e7bb38SChristian Borntraeger.Lrewind_pad2:
250c0e7bb38SChristian Borntraeger	nopr	7
251d0fc4107SMartin Schwidefsky	.globl sie_exit
252d0fc4107SMartin Schwidefskysie_exit:
25392fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
254d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2557041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2567041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2577041d281SMartin Schwidefsky	xgr	%r3,%r3
2587041d281SMartin Schwidefsky	xgr	%r4,%r4
2597041d281SMartin Schwidefsky	xgr	%r5,%r5
260d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
26192fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
2626dd85fbbSMartin Schwidefsky	BR_EX	%r14
263d0fc4107SMartin Schwidefsky.Lsie_fault:
264d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
26592fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
266d0fc4107SMartin Schwidefsky	j	sie_exit
267d0fc4107SMartin Schwidefsky
268c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
269c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
270c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
271d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
27226a374aeSMartin SchwidefskyENDPROC(sie64a)
273711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
274711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
275d0fc4107SMartin Schwidefsky#endif
276d0fc4107SMartin Schwidefsky
2774bfc86ceSHeiko Carstens/*
2784bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
2797b7735c5SChristian Borntraeger * are entered with interrupts disabled.
2804bfc86ceSHeiko Carstens */
2814bfc86ceSHeiko Carstens
2824bfc86ceSHeiko CarstensENTRY(system_call)
28356e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
2844bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
285d768bd89SMartin Schwidefsky	BPOFF
28656e62a73SSven Schnelle	lghi	%r14,0
2874bfc86ceSHeiko Carstens.Lsysc_per:
28887d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
28956e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
2904bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
2919365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
29256e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
29356e62a73SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
294d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
295d3f46896SChristian Borntraeger	xgr	%r0,%r0
29656e62a73SSven Schnelle	xgr	%r1,%r1
29756e62a73SSven Schnelle	xgr	%r4,%r4
29856e62a73SSven Schnelle	xgr	%r5,%r5
29956e62a73SSven Schnelle	xgr	%r6,%r6
30056e62a73SSven Schnelle	xgr	%r7,%r7
30156e62a73SSven Schnelle	xgr	%r8,%r8
30256e62a73SSven Schnelle	xgr	%r9,%r9
30356e62a73SSven Schnelle	xgr	%r10,%r10
30456e62a73SSven Schnelle	xgr	%r11,%r11
30556e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
306af9ad822SSven Schnelle	mvc	__PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
30756e62a73SSven Schnelle	lgr	%r3,%r14
30856e62a73SSven Schnelle	brasl	%r14,__do_syscall
30987d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
31056e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3116b73044bSMartin Schwidefsky	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
31256e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3134bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3140b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
31526a374aeSMartin SchwidefskyENDPROC(system_call)
3164bfc86ceSHeiko Carstens
3174bfc86ceSHeiko Carstens#
3184bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3194bfc86ceSHeiko Carstens#
3204bfc86ceSHeiko CarstensENTRY(ret_from_fork)
32156e62a73SSven Schnelle	lgr	%r3,%r11
32256e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
32356e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
32456e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
32556e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
32656e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
32756e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
32856e62a73SSven Schnelle	b	__LC_RETURN_LPSWE
32926a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
33026a374aeSMartin Schwidefsky
3314bfc86ceSHeiko Carstens/*
3324bfc86ceSHeiko Carstens * Program check handler routine
3334bfc86ceSHeiko Carstens */
3344bfc86ceSHeiko Carstens
3354bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
33656e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
337d768bd89SMartin Schwidefsky	BPOFF
3384bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
33956e62a73SSven Schnelle	lg	%r12,__LC_CURRENT
34056e62a73SSven Schnelle	lghi	%r10,0
3414bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
34287d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
34387d59863SHeiko Carstens	jno	.Lpgm_skip_asce
34487d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
34556e62a73SSven Schnelle	j	3f			# -> fault in user space
34687d59863SHeiko Carstens.Lpgm_skip_asce:
347d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3480a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
349b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f
350fbbdfca5SAlexander Gordeev	SIEEXIT
35156e62a73SSven Schnelle	lghi	%r10,_PIF_GUEST_FAULT
352d0fc4107SMartin Schwidefsky#endif
3530b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
3540b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
3554bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
3564bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
3570b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
3584bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
35956e62a73SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 4f
36056e62a73SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
36156e62a73SSven Schnelle3:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3624bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
36356e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
36456e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
36556e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3664bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
36756e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
36856e62a73SSven Schnelle	stmg	%r8,%r9,__PT_PSW(%r11)
36956e62a73SSven Schnelle
3707041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
3717041d281SMartin Schwidefsky	xgr	%r0,%r0
3727041d281SMartin Schwidefsky	xgr	%r1,%r1
3737041d281SMartin Schwidefsky	xgr	%r3,%r3
3747041d281SMartin Schwidefsky	xgr	%r4,%r4
3757041d281SMartin Schwidefsky	xgr	%r5,%r5
3767041d281SMartin Schwidefsky	xgr	%r6,%r6
3777041d281SMartin Schwidefsky	xgr	%r7,%r7
37856e62a73SSven Schnelle	lgr	%r2,%r11
37956e62a73SSven Schnelle	brasl	%r14,__do_pgm_check
38056e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user space?
38156e62a73SSven Schnelle	jno	.Lpgm_exit_kernel
38256e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
38356e62a73SSven Schnelle	BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
3840cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
38556e62a73SSven Schnelle.Lpgm_exit_kernel:
38656e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
38756e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3880cd9b723SHeiko Carstens	b	__LC_RETURN_LPSWE
3894bfc86ceSHeiko Carstens
3904bfc86ceSHeiko Carstens#
3914bfc86ceSHeiko Carstens# single stepped system call
3924bfc86ceSHeiko Carstens#
3934bfc86ceSHeiko Carstens.Lpgm_svcper:
3944bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
3954bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
3964bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
39756e62a73SSven Schnelle	lghi	%r14,1
3980b0ed657SSven Schnelle	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per
39926a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
4004bfc86ceSHeiko Carstens
4014bfc86ceSHeiko Carstens/*
40256e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4034bfc86ceSHeiko Carstens */
40456e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
40556e62a73SSven SchnelleENTRY(\name)
4064bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
40756e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
408d768bd89SMartin Schwidefsky	BPOFF
4094bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
410d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
41156e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
412b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
413b0d31159SSven Schnelle	jnz	1f
414b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
415b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,0f
416fbbdfca5SAlexander Gordeev	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
417fbbdfca5SAlexander Gordeev	SIEEXIT
418b0d31159SSven Schnelle#endif
419b0d31159SSven Schnelle0:	CHECK_STACK __LC_SAVE_AREA_ASYNC
420b0d31159SSven Schnelle	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
421b0d31159SSven Schnelle	j	2f
422b0d31159SSven Schnelle1:	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
423b0d31159SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
424b0d31159SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
425b74e409eSVasily Gorbik2:	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
426b74e409eSVasily Gorbik	la	%r11,STACK_FRAME_OVERHEAD(%r15)
4274bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4287041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4297041d281SMartin Schwidefsky	xgr	%r0,%r0
4307041d281SMartin Schwidefsky	xgr	%r1,%r1
4317041d281SMartin Schwidefsky	xgr	%r3,%r3
4327041d281SMartin Schwidefsky	xgr	%r4,%r4
4337041d281SMartin Schwidefsky	xgr	%r5,%r5
4347041d281SMartin Schwidefsky	xgr	%r6,%r6
4357041d281SMartin Schwidefsky	xgr	%r7,%r7
4367041d281SMartin Schwidefsky	xgr	%r10,%r10
437ca1f4d70SSven Schnelle	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
4384bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
4394bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
44056e62a73SSven Schnelle	tm	%r8,0x0001		# coming from user space?
44156e62a73SSven Schnelle	jno	1f
44287d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
44356e62a73SSven Schnelle1:	lgr	%r2,%r11		# pass pointer to pt_regs
44456e62a73SSven Schnelle	brasl	%r14,\handler
4454bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
44656e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
44756e62a73SSven Schnelle	jno	2f
44887d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
4496b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4504bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
45156e62a73SSven Schnelle2:	lmg	%r0,%r15,__PT_R0(%r11)
4520b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
45356e62a73SSven SchnelleENDPROC(\name)
45456e62a73SSven Schnelle.endm
4554bfc86ceSHeiko Carstens
45656e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
45756e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
4584bfc86ceSHeiko Carstens
4594bfc86ceSHeiko Carstens/*
4600b0ed657SSven Schnelle * Load idle PSW.
4614bfc86ceSHeiko Carstens */
4624bfc86ceSHeiko CarstensENTRY(psw_idle)
463a994eddbSVasily Gorbik	stg	%r14,(__SF_GPRS+8*8)(%r15)
4644bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
46556e62a73SSven Schnelle	larl	%r1,psw_idle_exit
4664bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
46772d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
46872d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
46972d38b19SMartin Schwidefsky	ltgr	%r1,%r1
47072d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
47156e62a73SSven Schnelle	.insn	rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
47272d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
473419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
474d768bd89SMartin Schwidefsky	BPON
4754bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
4764bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
4774bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
47856e62a73SSven Schnelle.globl psw_idle_exit
47956e62a73SSven Schnellepsw_idle_exit:
4806dd85fbbSMartin Schwidefsky	BR_EX	%r14
48126a374aeSMartin SchwidefskyENDPROC(psw_idle)
4824bfc86ceSHeiko Carstens
483b5510d9bSHendrik Brueckner/*
4844bfc86ceSHeiko Carstens * Machine check handler routines
4854bfc86ceSHeiko Carstens */
4864bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
4874bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
488d768bd89SMartin Schwidefsky	BPOFF
4893037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
4903037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
4913037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
4923037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
4933037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
494d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
4954bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
49683abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
4974bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
4983037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
4993037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
5003037a52fSMartin Schwidefsky	la	%r14,4095
5013037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
5023037a52fSMartin Schwidefsky	ptlb
5032a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
5043037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
5053037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
5063037a52fSMartin Schwidefsky	jno	0f
5073037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
5083037a52fSMartin Schwidefsky	jno	0f
5093037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
5103037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
5113037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
5123037a52fSMartin Schwidefsky	jo	0f
5133037a52fSMartin Schwidefsky	sr	%r14,%r14
5143037a52fSMartin Schwidefsky0:	sfpc	%r14
5153037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
5163037a52fSMartin Schwidefsky	jo	0f
5173037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
5183037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
5193037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
5203037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
5213037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
5223037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
5233037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
5243037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
5253037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
5263037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
5273037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
5283037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
5293037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
5303037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
5313037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
5323037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
5333037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
5343037a52fSMartin Schwidefsky	j	1f
5353037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
5363037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
5373037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5384bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
53983abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5404bfc86ceSHeiko Carstens	jo	3f
54156e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
54256e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5434bfc86ceSHeiko Carstens	jl	1f
5444bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5454bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5464bfc86ceSHeiko Carstens	jl	2f
5474bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5484bfc86ceSHeiko Carstens2:	spt	0(%r14)
5494bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5503037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5513037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5523037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
5533037a52fSMartin Schwidefsky	jnz	4f
5543037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5553037a52fSMartin Schwidefsky	jno	.Lmcck_panic
556ce3dc447SMartin Schwidefsky4:	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
557b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
558b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
559e2c13d64SAlexander Gordeev	jnz	.Lmcck_user
560b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack
561b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_entry,.Lsie_skip,5f
56220232b18SAlexander Gordeev	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
563fbbdfca5SAlexander Gordeev5:	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
564fbbdfca5SAlexander Gordeev	SIEEXIT
565b61b1595SSven Schnelle	j	.Lmcck_stack
566e2c13d64SAlexander Gordeev#else
567e2c13d64SAlexander Gordeev	jz	.Lmcck_stack
568e2c13d64SAlexander Gordeev#endif
569b0d31159SSven Schnelle.Lmcck_user:
570b0d31159SSven Schnelle	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
571b61b1595SSven Schnelle.Lmcck_stack:
572b61b1595SSven Schnelle	lg	%r15,__LC_MCCK_STACK
573b61b1595SSven Schnelle	la	%r11,STACK_FRAME_OVERHEAD(%r15)
57426521412SSven Schnelle	stctg	%c1,%c1,__PT_CR1(%r11)
575b61b1595SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
576b61b1595SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5774bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5784bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5797041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5807041d281SMartin Schwidefsky	xgr	%r0,%r0
5817041d281SMartin Schwidefsky	xgr	%r1,%r1
5827041d281SMartin Schwidefsky	xgr	%r3,%r3
5837041d281SMartin Schwidefsky	xgr	%r4,%r4
5847041d281SMartin Schwidefsky	xgr	%r5,%r5
5857041d281SMartin Schwidefsky	xgr	%r6,%r6
5867041d281SMartin Schwidefsky	xgr	%r7,%r7
5877041d281SMartin Schwidefsky	xgr	%r10,%r10
5884bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
5894bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
5904bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
5914bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5924bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5934bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
5940b0ed657SSven Schnelle	cghi	%r2,0
5950b0ed657SSven Schnelle	je	.Lmcck_return
5964bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
5974bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
5984bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
5994bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
6004bfc86ceSHeiko Carstens	lgr	%r15,%r1
6014bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
6024bfc86ceSHeiko Carstens.Lmcck_return:
60387d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
6044bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
6054bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
6064bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
6074bfc86ceSHeiko Carstens	jno	0f
6086b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
6094bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
6104bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
6110b38b5e1SSven Schnelle	b	__LC_RETURN_MCCK_LPSWE
6124bfc86ceSHeiko Carstens
6134bfc86ceSHeiko Carstens.Lmcck_panic:
614*7f6dc8d4SAlexander Gordeev	/*
615*7f6dc8d4SAlexander Gordeev	 * Iterate over all possible CPU addresses in the range 0..0xffff
616*7f6dc8d4SAlexander Gordeev	 * and stop each CPU using signal processor. Use compare and swap
617*7f6dc8d4SAlexander Gordeev	 * to allow just one CPU-stopper and prevent concurrent CPUs from
618*7f6dc8d4SAlexander Gordeev	 * stopping each other while leaving the others running.
619*7f6dc8d4SAlexander Gordeev	 */
620*7f6dc8d4SAlexander Gordeev	lhi	%r5,0
621*7f6dc8d4SAlexander Gordeev	lhi	%r6,1
622*7f6dc8d4SAlexander Gordeev	larl	%r7,.Lstop_lock
623*7f6dc8d4SAlexander Gordeev	cs	%r5,%r6,0(%r7)		# single CPU-stopper only
624*7f6dc8d4SAlexander Gordeev	jnz	4f
625*7f6dc8d4SAlexander Gordeev	larl	%r7,.Lthis_cpu
626*7f6dc8d4SAlexander Gordeev	stap	0(%r7)			# this CPU address
627*7f6dc8d4SAlexander Gordeev	lh	%r4,0(%r7)
628*7f6dc8d4SAlexander Gordeev	nilh	%r4,0
629*7f6dc8d4SAlexander Gordeev	lhi	%r0,1
630*7f6dc8d4SAlexander Gordeev	sll	%r0,16			# CPU counter
631*7f6dc8d4SAlexander Gordeev	lhi	%r3,0			# next CPU address
632*7f6dc8d4SAlexander Gordeev0:	cr	%r3,%r4
633*7f6dc8d4SAlexander Gordeev	je	2f
634*7f6dc8d4SAlexander Gordeev1:	sigp	%r1,%r3,SIGP_STOP	# stop next CPU
635*7f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,1b
636*7f6dc8d4SAlexander Gordeev2:	ahi	%r3,1
637*7f6dc8d4SAlexander Gordeev	brct	%r0,0b
638*7f6dc8d4SAlexander Gordeev3:	sigp	%r1,%r4,SIGP_STOP	# stop this CPU
639*7f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,3b
640*7f6dc8d4SAlexander Gordeev4:	j	4b
64126a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
6424bfc86ceSHeiko Carstens
6434bfc86ceSHeiko Carstens#
6444bfc86ceSHeiko Carstens# PSW restart interrupt handler
6454bfc86ceSHeiko Carstens#
6464bfc86ceSHeiko CarstensENTRY(restart_int_handler)
647e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
648e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
6494bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
650ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
651ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
652ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
653ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
6544bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
6554bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
6564bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
6574bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
6584bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
6594bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
6604bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
6614bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
6624bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
6634bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
6644bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
6654bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
6664bfc86ceSHeiko Carstens	brc	2,2b
6674bfc86ceSHeiko Carstens3:	j	3b
66826a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
6694bfc86ceSHeiko Carstens
6704bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
6714bfc86ceSHeiko Carstens
672ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
6734bfc86ceSHeiko Carstens/*
6744bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
6754bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
6764bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
6774bfc86ceSHeiko Carstens */
67826a374aeSMartin SchwidefskyENTRY(stack_overflow)
679ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
6804bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6814bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6824bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6834bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
6844bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
6854bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6864bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6874bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
68826a374aeSMartin SchwidefskyENDPROC(stack_overflow)
6894bfc86ceSHeiko Carstens#endif
6904bfc86ceSHeiko Carstens
691*7f6dc8d4SAlexander Gordeev	.section .data, "aw"
692*7f6dc8d4SAlexander Gordeev		.align	4
693*7f6dc8d4SAlexander Gordeev.Lstop_lock:	.long	0
694*7f6dc8d4SAlexander Gordeev.Lthis_cpu:	.short	0
695*7f6dc8d4SAlexander Gordeev
6964bfc86ceSHeiko Carstens	.section .rodata, "a"
697ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
6984bfc86ceSHeiko Carstens	.globl	sys_call_table
6994bfc86ceSHeiko Carstenssys_call_table:
7004381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
7014bfc86ceSHeiko Carstens#undef SYSCALL
7024bfc86ceSHeiko Carstens
7034bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
7044bfc86ceSHeiko Carstens
705ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
7064bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
7074bfc86ceSHeiko Carstenssys_call_table_emu:
7084381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
7094bfc86ceSHeiko Carstens#undef SYSCALL
7104bfc86ceSHeiko Carstens#endif
711