xref: /openbmc/linux/arch/s390/kernel/entry.S (revision ecc23d0a422a3118fcf6e4f0a46e17a6c2047b02)
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
11b8c723f1SMasahiro Yamada#include <linux/export.h>
124bfc86ceSHeiko Carstens#include <linux/init.h>
134bfc86ceSHeiko Carstens#include <linux/linkage.h>
14d09a307fSHeiko Carstens#include <asm/asm-extable.h>
15b058661aSMartin Schwidefsky#include <asm/alternative-asm.h>
164bfc86ceSHeiko Carstens#include <asm/processor.h>
174bfc86ceSHeiko Carstens#include <asm/cache.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>
306dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h>
314bfc86ceSHeiko Carstens
32e5b98199SMartin Schwidefsky_LPP_OFFSET	= __LC_LPP
33e5b98199SMartin Schwidefsky
343b051e89SSven Schnelle	.macro STBEAR address
35fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193
363b051e89SSven Schnelle	.endm
373b051e89SSven Schnelle
383b051e89SSven Schnelle	.macro LBEAR address
39fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193
403b051e89SSven Schnelle	.endm
413b051e89SSven Schnelle
423b051e89SSven Schnelle	.macro LPSWEY address,lpswe
43fad442d3SHeiko Carstens	ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193
443b051e89SSven Schnelle	.endm
453b051e89SSven Schnelle
463b051e89SSven Schnelle	.macro MBEAR reg
47fad442d3SHeiko Carstens	ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
483b051e89SSven Schnelle	.endm
493b051e89SSven Schnelle
50ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
514bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
52c2c3258fSHeiko Carstens	tml	%r15,THREAD_SIZE - CONFIG_STACK_GUARD
534bfc86ceSHeiko Carstens	lghi	%r14,\savearea
544bfc86ceSHeiko Carstens	jz	stack_overflow
554bfc86ceSHeiko Carstens#endif
564bfc86ceSHeiko Carstens	.endm
574bfc86ceSHeiko Carstens
58ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
59ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
60ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
61c2c3258fSHeiko Carstens	nill	%r14,0x10000 - THREAD_SIZE
62c2c3258fSHeiko Carstens	oill	%r14,STACK_INIT_OFFSET
63ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
64ce3dc447SMartin Schwidefsky	je	\oklabel
65ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
66ce3dc447SMartin Schwidefsky	je	\oklabel
67b61b1595SSven Schnelle	clg	%r14,__LC_MCCK_STACK
68b61b1595SSven Schnelle	je	\oklabel
69ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
70ce3dc447SMartin Schwidefsky	je	\oklabel
71ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
72ce3dc447SMartin Schwidefsky	je	\oklabel
73ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
74ce3dc447SMartin Schwidefsky	j	stack_overflow
75ce3dc447SMartin Schwidefsky#else
76ce3dc447SMartin Schwidefsky	j	\oklabel
77ce3dc447SMartin Schwidefsky#endif
78ce3dc447SMartin Schwidefsky	.endm
79ce3dc447SMartin Schwidefsky
8083abeffbSHendrik Brueckner	/*
8183abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
8283abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
8383abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
8483abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
8583abeffbSHendrik Brueckner	 * instruction.
8683abeffbSHendrik Brueckner	 */
8783abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
8883abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
8983abeffbSHendrik Brueckner			.if (\mask & 0xff)
9083abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
9183abeffbSHendrik Brueckner			.endif
9283abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
9383abeffbSHendrik Brueckner			.exitm
9483abeffbSHendrik Brueckner		.endif
9583abeffbSHendrik Brueckner		.ifeq \mask
9683abeffbSHendrik Brueckner			.error "Mask must not be zero"
9783abeffbSHendrik Brueckner		.endif
9883abeffbSHendrik Brueckner		off = \size - \bytepos - 1
9983abeffbSHendrik Brueckner		tm	off+\addr, \mask
10083abeffbSHendrik Brueckner	.endm
10183abeffbSHendrik Brueckner
102d768bd89SMartin Schwidefsky	.macro BPOFF
103fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82
104d768bd89SMartin Schwidefsky	.endm
105d768bd89SMartin Schwidefsky
106d768bd89SMartin Schwidefsky	.macro BPON
107fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82
108d768bd89SMartin Schwidefsky	.endm
109d768bd89SMartin Schwidefsky
1106b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
1116982dba1SHeiko Carstens	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
112fad442d3SHeiko Carstens		    "j .+12; nop; nop", 82
1136b73044bSMartin Schwidefsky	.endm
1146b73044bSMartin Schwidefsky
1156b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1166b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
1176982dba1SHeiko Carstens	ALTERNATIVE "jz .+8;  .insn rrf,0xb2e80000,0,0,12,0", \
1186982dba1SHeiko Carstens		    "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
1196b73044bSMartin Schwidefsky	.endm
1206b73044bSMartin Schwidefsky
121b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM)
122b5415c8fSAlexander Gordeev	/*
123b5415c8fSAlexander Gordeev	 * The OUTSIDE macro jumps to the provided label in case the value
124b5415c8fSAlexander Gordeev	 * in the provided register is outside of the provided range. The
125b5415c8fSAlexander Gordeev	 * macro is useful for checking whether a PSW stored in a register
126b5415c8fSAlexander Gordeev	 * pair points inside or outside of a block of instructions.
127b5415c8fSAlexander Gordeev	 * @reg: register to check
128b5415c8fSAlexander Gordeev	 * @start: start of the range
129b5415c8fSAlexander Gordeev	 * @end: end of the range
130b5415c8fSAlexander Gordeev	 * @outside_label: jump here if @reg is outside of [@start..@end)
131b5415c8fSAlexander Gordeev	 */
132b5415c8fSAlexander Gordeev	.macro OUTSIDE reg,start,end,outside_label
133b5415c8fSAlexander Gordeev	lgr	%r14,\reg
134b5415c8fSAlexander Gordeev	larl	%r13,\start
135b5415c8fSAlexander Gordeev	slgr	%r14,%r13
1364c25f0ffSHeiko Carstens	clgfrl	%r14,.Lrange_size\@
137b5415c8fSAlexander Gordeev	jhe	\outside_label
1384c25f0ffSHeiko Carstens	.section .rodata, "a"
13927d45655SHeiko Carstens	.balign 4
1404c25f0ffSHeiko Carstens.Lrange_size\@:
1414c25f0ffSHeiko Carstens	.long	\end - \start
1424c25f0ffSHeiko Carstens	.previous
143b5415c8fSAlexander Gordeev	.endm
144fbbdfca5SAlexander Gordeev
145fbbdfca5SAlexander Gordeev	.macro SIEEXIT
146fbbdfca5SAlexander Gordeev	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
147fbbdfca5SAlexander Gordeev	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
148fbbdfca5SAlexander Gordeev	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
149fbbdfca5SAlexander Gordeev	larl	%r9,sie_exit			# skip forward to sie_exit
150fbbdfca5SAlexander Gordeev	.endm
151b5415c8fSAlexander Gordeev#endif
152b5415c8fSAlexander Gordeev
153b94c0ebbSHeiko Carstens	.macro STACKLEAK_ERASE
154b94c0ebbSHeiko Carstens#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
155b94c0ebbSHeiko Carstens	brasl	%r14,stackleak_erase_on_task_stack
156b94c0ebbSHeiko Carstens#endif
157b94c0ebbSHeiko Carstens	.endm
158b94c0ebbSHeiko Carstens
1596dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
160f19fbd5eSMartin Schwidefsky
1614bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
16246210c44SHeiko Carstens.Ldummy:
16346210c44SHeiko Carstens	/*
16469a407bfSHeiko Carstens	 * The following nop exists only in order to avoid that the next
16569a407bfSHeiko Carstens	 * symbol starts at the beginning of the kprobes text section.
16669a407bfSHeiko Carstens	 * In that case there would be several symbols at the same address.
16769a407bfSHeiko Carstens	 * E.g. objdump would take an arbitrary symbol when disassembling
16869a407bfSHeiko Carstens	 * the code.
16969a407bfSHeiko Carstens	 * With the added nop in between this cannot happen.
17046210c44SHeiko Carstens	 */
17146210c44SHeiko Carstens	nop	0
1724bfc86ceSHeiko Carstens
1734bfc86ceSHeiko Carstens/*
1744bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
1754bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
1764bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
1774bfc86ceSHeiko Carstens * Returns:
1784bfc86ceSHeiko Carstens *  gpr2 = prev
1794bfc86ceSHeiko Carstens */
180fda1dffaSHeiko CarstensSYM_FUNC_START(__switch_to)
1814bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
1823241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
1833241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
184c2c3258fSHeiko Carstens	llill	%r5,STACK_INIT_OFFSET
1853241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
1869fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
1879fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
1884bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
1894bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
1903241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
1913241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
1923241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
1934bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
194fad442d3SHeiko Carstens	ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
1956dd85fbbSMartin Schwidefsky	BR_EX	%r14
196fda1dffaSHeiko CarstensSYM_FUNC_END(__switch_to)
1974bfc86ceSHeiko Carstens
198d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
199d0fc4107SMartin Schwidefsky/*
2006b33e68aSNico Boehr * __sie64a calling convention:
2016b33e68aSNico Boehr * %r2 pointer to sie control block phys
2026b33e68aSNico Boehr * %r3 pointer to sie control block virt
2036b33e68aSNico Boehr * %r4 guest register save area
204d0fc4107SMartin Schwidefsky */
205fda1dffaSHeiko CarstensSYM_FUNC_START(__sie64a)
206d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2076b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
2086b33e68aSNico Boehr	stg	%r2,__SF_SIE_CONTROL_PHYS(%r15)	# save sie block physical..
2096b33e68aSNico Boehr	stg	%r3,__SF_SIE_CONTROL(%r15)	# ...and virtual addresses
2106b33e68aSNico Boehr	stg	%r4,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
21192fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
21292fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
2136b33e68aSNico Boehr	lmg	%r0,%r13,0(%r4)			# load guest gprs 0-13
214d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
215d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
216d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
217d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
218d0fc4107SMartin Schwidefsky.Lsie_gmap:
21992fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
220d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
221d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
222d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
22383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
224d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
2256b33e68aSNico Boehr	lg	%r14,__SF_SIE_CONTROL_PHYS(%r15)	# get sie block phys addr
226f33f2d4cSHeiko Carstens	BPEXIT	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
227c929500dSQingFeng Hao.Lsie_entry:
228d0fc4107SMartin Schwidefsky	sie	0(%r14)
22929ccaa4bSAlexander Gordeev# Let the next instruction be NOP to avoid triggering a machine check
23029ccaa4bSAlexander Gordeev# and handling it in a guest as result of the instruction execution.
23129ccaa4bSAlexander Gordeev	nopr	7
23229ccaa4bSAlexander Gordeev.Lsie_leave:
233d768bd89SMartin Schwidefsky	BPOFF
234f33f2d4cSHeiko Carstens	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
235d0fc4107SMartin Schwidefsky.Lsie_skip:
2366b33e68aSNico Boehr	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
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.
2436b33e68aSNico Boehr# 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
251fda1dffaSHeiko CarstensSYM_INNER_LABEL(sie_exit, SYM_L_GLOBAL)
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)
271fda1dffaSHeiko CarstensSYM_FUNC_END(__sie64a)
2726b33e68aSNico BoehrEXPORT_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
281fda1dffaSHeiko CarstensSYM_CODE_START(system_call)
28256e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
2834bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
284d768bd89SMartin Schwidefsky	BPOFF
28556e62a73SSven Schnelle	lghi	%r14,0
2864bfc86ceSHeiko Carstens.Lsysc_per:
2873b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
28887d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
2894bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
2909365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
29156e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
292d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
293d3f46896SChristian Borntraeger	xgr	%r0,%r0
29456e62a73SSven Schnelle	xgr	%r1,%r1
29556e62a73SSven Schnelle	xgr	%r4,%r4
29656e62a73SSven Schnelle	xgr	%r5,%r5
29756e62a73SSven Schnelle	xgr	%r6,%r6
29856e62a73SSven Schnelle	xgr	%r7,%r7
29956e62a73SSven Schnelle	xgr	%r8,%r8
30056e62a73SSven Schnelle	xgr	%r9,%r9
30156e62a73SSven Schnelle	xgr	%r10,%r10
30256e62a73SSven Schnelle	xgr	%r11,%r11
30356e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
304af9ad822SSven Schnelle	mvc	__PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
3053b051e89SSven Schnelle	MBEAR	%r2
30656e62a73SSven Schnelle	lgr	%r3,%r14
30756e62a73SSven Schnelle	brasl	%r14,__do_syscall
308b94c0ebbSHeiko Carstens	STACKLEAK_ERASE
30987d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
31056e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
311f33f2d4cSHeiko Carstens	BPON
3123b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
31356e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3144bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3153b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
316fda1dffaSHeiko CarstensSYM_CODE_END(system_call)
3174bfc86ceSHeiko Carstens
3184bfc86ceSHeiko Carstens#
3194bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3204bfc86ceSHeiko Carstens#
321fda1dffaSHeiko CarstensSYM_CODE_START(ret_from_fork)
32256e62a73SSven Schnelle	lgr	%r3,%r11
32356e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
324b94c0ebbSHeiko Carstens	STACKLEAK_ERASE
32556e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
32656e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
327f33f2d4cSHeiko Carstens	BPON
3283b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
32956e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
33056e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
3313b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
332fda1dffaSHeiko CarstensSYM_CODE_END(ret_from_fork)
33326a374aeSMartin Schwidefsky
3344bfc86ceSHeiko Carstens/*
3354bfc86ceSHeiko Carstens * Program check handler routine
3364bfc86ceSHeiko Carstens */
3374bfc86ceSHeiko Carstens
338fda1dffaSHeiko CarstensSYM_CODE_START(pgm_check_handler)
33956e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
340d768bd89SMartin Schwidefsky	BPOFF
3414bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
34256e62a73SSven Schnelle	lghi	%r10,0
3434bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
34487d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
34587d59863SHeiko Carstens	jno	.Lpgm_skip_asce
34687d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
34756e62a73SSven Schnelle	j	3f			# -> fault in user space
34887d59863SHeiko Carstens.Lpgm_skip_asce:
349d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3506b33e68aSNico Boehr	# cleanup critical section for program checks in __sie64a
351b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f
352f33f2d4cSHeiko Carstens	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
353fbbdfca5SAlexander Gordeev	SIEEXIT
35456e62a73SSven Schnelle	lghi	%r10,_PIF_GUEST_FAULT
355d0fc4107SMartin Schwidefsky#endif
3560b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
3570b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
3584bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
3594bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
3600b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
3614bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
36256e62a73SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 4f
36356e62a73SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
364f33f2d4cSHeiko Carstens3:	lg	%r15,__LC_KERNEL_STACK
36556e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
36656e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
36756e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3684bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
36956e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3703b051e89SSven Schnelle	mvc	__PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK
37156e62a73SSven Schnelle	stmg	%r8,%r9,__PT_PSW(%r11)
37256e62a73SSven Schnelle
3737041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
3747041d281SMartin Schwidefsky	xgr	%r0,%r0
3757041d281SMartin Schwidefsky	xgr	%r1,%r1
3767041d281SMartin Schwidefsky	xgr	%r3,%r3
3777041d281SMartin Schwidefsky	xgr	%r4,%r4
3787041d281SMartin Schwidefsky	xgr	%r5,%r5
3797041d281SMartin Schwidefsky	xgr	%r6,%r6
3807041d281SMartin Schwidefsky	xgr	%r7,%r7
38156e62a73SSven Schnelle	lgr	%r2,%r11
38256e62a73SSven Schnelle	brasl	%r14,__do_pgm_check
38356e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user space?
38456e62a73SSven Schnelle	jno	.Lpgm_exit_kernel
385b94c0ebbSHeiko Carstens	STACKLEAK_ERASE
38656e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
387f33f2d4cSHeiko Carstens	BPON
3880cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
38956e62a73SSven Schnelle.Lpgm_exit_kernel:
39056e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3913b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
39256e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3933b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
3944bfc86ceSHeiko Carstens
3954bfc86ceSHeiko Carstens#
3964bfc86ceSHeiko Carstens# single stepped system call
3974bfc86ceSHeiko Carstens#
3984bfc86ceSHeiko Carstens.Lpgm_svcper:
3994bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
4004bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
4014bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
40256e62a73SSven Schnelle	lghi	%r14,1
4033b051e89SSven Schnelle	LBEAR	__LC_PGM_LAST_BREAK
4043b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per
405fda1dffaSHeiko CarstensSYM_CODE_END(pgm_check_handler)
4064bfc86ceSHeiko Carstens
4074bfc86ceSHeiko Carstens/*
40856e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4094bfc86ceSHeiko Carstens */
41056e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
411fda1dffaSHeiko CarstensSYM_CODE_START(\name)
41210bc15baSVasily Gorbik	stckf	__LC_INT_CLOCK
41356e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
4143b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
415d768bd89SMartin Schwidefsky	BPOFF
4164bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
41756e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
418b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
419b0d31159SSven Schnelle	jnz	1f
420b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
421b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,0f
422f33f2d4cSHeiko Carstens	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
423fbbdfca5SAlexander Gordeev	SIEEXIT
424b0d31159SSven Schnelle#endif
425b0d31159SSven Schnelle0:	CHECK_STACK __LC_SAVE_AREA_ASYNC
426b0d31159SSven Schnelle	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
427b0d31159SSven Schnelle	j	2f
428f33f2d4cSHeiko Carstens1:	lctlg	%c1,%c1,__LC_KERNEL_ASCE
429b0d31159SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
430b74e409eSVasily Gorbik2:	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
431b74e409eSVasily Gorbik	la	%r11,STACK_FRAME_OVERHEAD(%r15)
4324bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4337041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4347041d281SMartin Schwidefsky	xgr	%r0,%r0
4357041d281SMartin Schwidefsky	xgr	%r1,%r1
4367041d281SMartin Schwidefsky	xgr	%r3,%r3
4377041d281SMartin Schwidefsky	xgr	%r4,%r4
4387041d281SMartin Schwidefsky	xgr	%r5,%r5
4397041d281SMartin Schwidefsky	xgr	%r6,%r6
4407041d281SMartin Schwidefsky	xgr	%r7,%r7
4417041d281SMartin Schwidefsky	xgr	%r10,%r10
442ca1f4d70SSven Schnelle	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
4434bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
4443b051e89SSven Schnelle	MBEAR	%r11
4454bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
44629b06ad7SHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
44756e62a73SSven Schnelle	brasl	%r14,\handler
4484bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
44956e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
45056e62a73SSven Schnelle	jno	2f
451b94c0ebbSHeiko Carstens	STACKLEAK_ERASE
45287d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
453f33f2d4cSHeiko Carstens	BPON
4544bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4553b051e89SSven Schnelle2:	LBEAR	__PT_LAST_BREAK(%r11)
4563b051e89SSven Schnelle	lmg	%r0,%r15,__PT_R0(%r11)
4573b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
458fda1dffaSHeiko CarstensSYM_CODE_END(\name)
45956e62a73SSven Schnelle.endm
4604bfc86ceSHeiko Carstens
461*1af22528SVasily Gorbik	.section .irqentry.text, "ax"
462*1af22528SVasily Gorbik
46356e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
46456e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
4654bfc86ceSHeiko Carstens
466*1af22528SVasily Gorbik	.section .kprobes.text, "ax"
467*1af22528SVasily Gorbik
4684bfc86ceSHeiko Carstens/*
4690b0ed657SSven Schnelle * Load idle PSW.
4704bfc86ceSHeiko Carstens */
471fda1dffaSHeiko CarstensSYM_FUNC_START(psw_idle)
472a994eddbSVasily Gorbik	stg	%r14,(__SF_GPRS+8*8)(%r15)
4734bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
47456e62a73SSven Schnelle	larl	%r1,psw_idle_exit
4754bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
47672d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
47772d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
47872d38b19SMartin Schwidefsky	ltgr	%r1,%r1
47972d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
48056e62a73SSven Schnelle	.insn	rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
48172d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
482419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
483d768bd89SMartin Schwidefsky	BPON
48410bc15baSVasily Gorbik	stckf	__CLOCK_IDLE_ENTER(%r2)
4854bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
4864bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
487fda1dffaSHeiko CarstensSYM_INNER_LABEL(psw_idle_exit, SYM_L_GLOBAL)
4886dd85fbbSMartin Schwidefsky	BR_EX	%r14
489fda1dffaSHeiko CarstensSYM_FUNC_END(psw_idle)
4904bfc86ceSHeiko Carstens
491b5510d9bSHendrik Brueckner/*
4924bfc86ceSHeiko Carstens * Machine check handler routines
4934bfc86ceSHeiko Carstens */
494fda1dffaSHeiko CarstensSYM_CODE_START(mcck_int_handler)
495d768bd89SMartin Schwidefsky	BPOFF
4963037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
4973037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
4983b051e89SSven Schnelle	LBEAR	__LC_LAST_BREAK_SAVE_AREA-4095(%r1)		# validate bear
499385bf43cSVasily Gorbik	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA		# validate gprs
5004bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
50183abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
5024bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
5033037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
5043037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
505385bf43cSVasily Gorbik	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA		# validate ctl regs
5063037a52fSMartin Schwidefsky	ptlb
5075fa2ea07SAlexander Gordeev	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5084bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
50983abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5104bfc86ceSHeiko Carstens	jo	3f
51156e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
51256e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5134bfc86ceSHeiko Carstens	jl	1f
5144bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5154bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5164bfc86ceSHeiko Carstens	jl	2f
5174bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5184bfc86ceSHeiko Carstens2:	spt	0(%r14)
5194bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5203037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5213037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5223037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
523742aed05SHeiko Carstens	jnz	.Lmcck_user
5243037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5253037a52fSMartin Schwidefsky	jno	.Lmcck_panic
526b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
527f33f2d4cSHeiko Carstens	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,.Lmcck_user
52829ccaa4bSAlexander Gordeev	OUTSIDE	%r9,.Lsie_entry,.Lsie_leave,4f
52920232b18SAlexander Gordeev	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
530f33f2d4cSHeiko Carstens4:	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
531fbbdfca5SAlexander Gordeev	SIEEXIT
532e2c13d64SAlexander Gordeev#endif
533742aed05SHeiko Carstens.Lmcck_user:
534b61b1595SSven Schnelle	lg	%r15,__LC_MCCK_STACK
535b61b1595SSven Schnelle	la	%r11,STACK_FRAME_OVERHEAD(%r15)
53626521412SSven Schnelle	stctg	%c1,%c1,__PT_CR1(%r11)
537b61b1595SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
538b61b1595SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5394bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5404bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5417041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5427041d281SMartin Schwidefsky	xgr	%r0,%r0
5437041d281SMartin Schwidefsky	xgr	%r1,%r1
5447041d281SMartin Schwidefsky	xgr	%r3,%r3
5457041d281SMartin Schwidefsky	xgr	%r4,%r4
5467041d281SMartin Schwidefsky	xgr	%r5,%r5
5477041d281SMartin Schwidefsky	xgr	%r6,%r6
5487041d281SMartin Schwidefsky	xgr	%r7,%r7
5497041d281SMartin Schwidefsky	xgr	%r10,%r10
5504bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
5514bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
5524bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
5534bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5544bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5554bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
55687d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
5574bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
5584bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
5594bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
5604bfc86ceSHeiko Carstens	jno	0f
561f33f2d4cSHeiko Carstens	BPON
5624bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
563fad442d3SHeiko Carstens0:	ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
5643b051e89SSven Schnelle	LBEAR	0(%r12)
5653b051e89SSven Schnelle	lmg	%r11,%r15,__PT_R11(%r11)
5663b051e89SSven Schnelle	LPSWEY	__LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
5674bfc86ceSHeiko Carstens
5684bfc86ceSHeiko Carstens.Lmcck_panic:
5697f6dc8d4SAlexander Gordeev	/*
5707f6dc8d4SAlexander Gordeev	 * Iterate over all possible CPU addresses in the range 0..0xffff
5717f6dc8d4SAlexander Gordeev	 * and stop each CPU using signal processor. Use compare and swap
5727f6dc8d4SAlexander Gordeev	 * to allow just one CPU-stopper and prevent concurrent CPUs from
5737f6dc8d4SAlexander Gordeev	 * stopping each other while leaving the others running.
5747f6dc8d4SAlexander Gordeev	 */
5757f6dc8d4SAlexander Gordeev	lhi	%r5,0
5767f6dc8d4SAlexander Gordeev	lhi	%r6,1
577fda1dffaSHeiko Carstens	larl	%r7,stop_lock
5787f6dc8d4SAlexander Gordeev	cs	%r5,%r6,0(%r7)		# single CPU-stopper only
5797f6dc8d4SAlexander Gordeev	jnz	4f
580fda1dffaSHeiko Carstens	larl	%r7,this_cpu
5817f6dc8d4SAlexander Gordeev	stap	0(%r7)			# this CPU address
5827f6dc8d4SAlexander Gordeev	lh	%r4,0(%r7)
5837f6dc8d4SAlexander Gordeev	nilh	%r4,0
5847f6dc8d4SAlexander Gordeev	lhi	%r0,1
5857f6dc8d4SAlexander Gordeev	sll	%r0,16			# CPU counter
5867f6dc8d4SAlexander Gordeev	lhi	%r3,0			# next CPU address
5877f6dc8d4SAlexander Gordeev0:	cr	%r3,%r4
5887f6dc8d4SAlexander Gordeev	je	2f
5897f6dc8d4SAlexander Gordeev1:	sigp	%r1,%r3,SIGP_STOP	# stop next CPU
5907f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,1b
5917f6dc8d4SAlexander Gordeev2:	ahi	%r3,1
5927f6dc8d4SAlexander Gordeev	brct	%r0,0b
5937f6dc8d4SAlexander Gordeev3:	sigp	%r1,%r4,SIGP_STOP	# stop this CPU
5947f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,3b
5957f6dc8d4SAlexander Gordeev4:	j	4b
596fda1dffaSHeiko CarstensSYM_CODE_END(mcck_int_handler)
5974bfc86ceSHeiko Carstens
598fda1dffaSHeiko CarstensSYM_CODE_START(restart_int_handler)
599fad442d3SHeiko Carstens	ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
600e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
601915fea04SAlexander Gordeev	TSTMSK	__LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
602915fea04SAlexander Gordeev	jz	0f
603385bf43cSVasily Gorbik	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA
604edbe2898SAlexander Gordeev0:	larl	%r15,daton_psw
605edbe2898SAlexander Gordeev	lpswe	0(%r15)				# turn dat on, keep irqs off
606edbe2898SAlexander Gordeev.Ldaton:
6074bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
608ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
609ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
610ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
611ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
6124bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
6134bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
6144bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
615915fea04SAlexander Gordeev	lgf	%r3,__LC_RESTART_SOURCE
6164bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
6174bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
6184bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
6194bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
6204bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
6214bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
6224bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
6234bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
6244bfc86ceSHeiko Carstens	brc	2,2b
6254bfc86ceSHeiko Carstens3:	j	3b
626fda1dffaSHeiko CarstensSYM_CODE_END(restart_int_handler)
6274bfc86ceSHeiko Carstens
6284bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
6294bfc86ceSHeiko Carstens
630ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
6314bfc86ceSHeiko Carstens/*
6324bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
6334bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
6344bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
6354bfc86ceSHeiko Carstens */
636fda1dffaSHeiko CarstensSYM_CODE_START(stack_overflow)
637ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
6384bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6394bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6404bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6414bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
6424bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
6434bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6444bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6454bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
646fda1dffaSHeiko CarstensSYM_CODE_END(stack_overflow)
6474bfc86ceSHeiko Carstens#endif
6484bfc86ceSHeiko Carstens
6497f6dc8d4SAlexander Gordeev	.section .data, "aw"
650fda1dffaSHeiko Carstens	.balign	4
651fda1dffaSHeiko CarstensSYM_DATA_LOCAL(stop_lock,	.long 0)
652fda1dffaSHeiko CarstensSYM_DATA_LOCAL(this_cpu,	.short 0)
653edbe2898SAlexander Gordeev	.balign	8
654edbe2898SAlexander GordeevSYM_DATA_START_LOCAL(daton_psw)
655edbe2898SAlexander Gordeev	.quad	PSW_KERNEL_BITS
656edbe2898SAlexander Gordeev	.quad	.Ldaton
657edbe2898SAlexander GordeevSYM_DATA_END(daton_psw)
658fda1dffaSHeiko Carstens
6594bfc86ceSHeiko Carstens	.section .rodata, "a"
6603dcb2223SSumanth Korikkar	.balign	8
661ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
662fda1dffaSHeiko CarstensSYM_DATA_START(sys_call_table)
6634381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
664fda1dffaSHeiko CarstensSYM_DATA_END(sys_call_table)
6654bfc86ceSHeiko Carstens#undef SYSCALL
6664bfc86ceSHeiko Carstens
6674bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
6684bfc86ceSHeiko Carstens
669ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
670fda1dffaSHeiko CarstensSYM_DATA_START(sys_call_table_emu)
6714381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
672fda1dffaSHeiko CarstensSYM_DATA_END(sys_call_table_emu)
6734bfc86ceSHeiko Carstens#undef SYSCALL
6744bfc86ceSHeiko Carstens#endif
675