xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 385bf43c48ffe44af881039779a6be09ac8a77c8)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
24bfc86ceSHeiko Carstens/*
34bfc86ceSHeiko Carstens *    S390 low-level entry points.
44bfc86ceSHeiko Carstens *
54bfc86ceSHeiko Carstens *    Copyright IBM Corp. 1999, 2012
64bfc86ceSHeiko Carstens *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
74bfc86ceSHeiko Carstens *		 Hartmut Penner (hp@de.ibm.com),
84bfc86ceSHeiko Carstens *		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
94bfc86ceSHeiko Carstens */
104bfc86ceSHeiko Carstens
114bfc86ceSHeiko Carstens#include <linux/init.h>
124bfc86ceSHeiko Carstens#include <linux/linkage.h>
13d09a307fSHeiko Carstens#include <asm/asm-extable.h>
14b058661aSMartin Schwidefsky#include <asm/alternative-asm.h>
154bfc86ceSHeiko Carstens#include <asm/processor.h>
164bfc86ceSHeiko Carstens#include <asm/cache.h>
17dc24b7b4SHendrik Brueckner#include <asm/dwarf.h>
184bfc86ceSHeiko Carstens#include <asm/errno.h>
194bfc86ceSHeiko Carstens#include <asm/ptrace.h>
204bfc86ceSHeiko Carstens#include <asm/thread_info.h>
214bfc86ceSHeiko Carstens#include <asm/asm-offsets.h>
224bfc86ceSHeiko Carstens#include <asm/unistd.h>
234bfc86ceSHeiko Carstens#include <asm/page.h>
244bfc86ceSHeiko Carstens#include <asm/sigp.h>
254bfc86ceSHeiko Carstens#include <asm/irq.h>
269977e886SHendrik Brueckner#include <asm/vx-insn.h>
2783abeffbSHendrik Brueckner#include <asm/setup.h>
2883abeffbSHendrik Brueckner#include <asm/nmi.h>
29711f5df7SAl Viro#include <asm/export.h>
306dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h>
314bfc86ceSHeiko Carstens
323a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER
334bfc86ceSHeiko CarstensSTACK_SIZE  = 1 << STACK_SHIFT
344bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
354bfc86ceSHeiko Carstens
36e5b98199SMartin Schwidefsky_LPP_OFFSET	= __LC_LPP
37e5b98199SMartin Schwidefsky
383b051e89SSven Schnelle	.macro STBEAR address
39fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193
403b051e89SSven Schnelle	.endm
413b051e89SSven Schnelle
423b051e89SSven Schnelle	.macro LBEAR address
43fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193
443b051e89SSven Schnelle	.endm
453b051e89SSven Schnelle
463b051e89SSven Schnelle	.macro LPSWEY address,lpswe
47fad442d3SHeiko Carstens	ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193
483b051e89SSven Schnelle	.endm
493b051e89SSven Schnelle
503b051e89SSven Schnelle	.macro MBEAR reg
51fad442d3SHeiko Carstens	ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
523b051e89SSven Schnelle	.endm
533b051e89SSven Schnelle
54ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
554bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
56ce3dc447SMartin Schwidefsky	tml	%r15,STACK_SIZE - CONFIG_STACK_GUARD
574bfc86ceSHeiko Carstens	lghi	%r14,\savearea
584bfc86ceSHeiko Carstens	jz	stack_overflow
594bfc86ceSHeiko Carstens#endif
604bfc86ceSHeiko Carstens	.endm
614bfc86ceSHeiko Carstens
62ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
63ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
64ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
65ce3dc447SMartin Schwidefsky	nill	%r14,0x10000 - STACK_SIZE
66ce3dc447SMartin Schwidefsky	oill	%r14,STACK_INIT
67ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
68ce3dc447SMartin Schwidefsky	je	\oklabel
69ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
70ce3dc447SMartin Schwidefsky	je	\oklabel
71b61b1595SSven Schnelle	clg	%r14,__LC_MCCK_STACK
72b61b1595SSven Schnelle	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
8483abeffbSHendrik Brueckner	/*
8583abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
8683abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
8783abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
8883abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
8983abeffbSHendrik Brueckner	 * instruction.
9083abeffbSHendrik Brueckner	 */
9183abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
9283abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
9383abeffbSHendrik Brueckner			.if (\mask & 0xff)
9483abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
9583abeffbSHendrik Brueckner			.endif
9683abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
9783abeffbSHendrik Brueckner			.exitm
9883abeffbSHendrik Brueckner		.endif
9983abeffbSHendrik Brueckner		.ifeq \mask
10083abeffbSHendrik Brueckner			.error "Mask must not be zero"
10183abeffbSHendrik Brueckner		.endif
10283abeffbSHendrik Brueckner		off = \size - \bytepos - 1
10383abeffbSHendrik Brueckner		tm	off+\addr, \mask
10483abeffbSHendrik Brueckner	.endm
10583abeffbSHendrik Brueckner
106d768bd89SMartin Schwidefsky	.macro BPOFF
107fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82
108d768bd89SMartin Schwidefsky	.endm
109d768bd89SMartin Schwidefsky
110d768bd89SMartin Schwidefsky	.macro BPON
111fad442d3SHeiko Carstens	ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82
112d768bd89SMartin Schwidefsky	.endm
113d768bd89SMartin Schwidefsky
1146b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
1156982dba1SHeiko Carstens	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
116fad442d3SHeiko Carstens		    "j .+12; nop; nop", 82
1176b73044bSMartin Schwidefsky	.endm
1186b73044bSMartin Schwidefsky
1196b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1206b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
1216982dba1SHeiko Carstens	ALTERNATIVE "jz .+8;  .insn rrf,0xb2e80000,0,0,12,0", \
1226982dba1SHeiko Carstens		    "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
1236b73044bSMartin Schwidefsky	.endm
1246b73044bSMartin Schwidefsky
125b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM)
126b5415c8fSAlexander Gordeev	/*
127b5415c8fSAlexander Gordeev	 * The OUTSIDE macro jumps to the provided label in case the value
128b5415c8fSAlexander Gordeev	 * in the provided register is outside of the provided range. The
129b5415c8fSAlexander Gordeev	 * macro is useful for checking whether a PSW stored in a register
130b5415c8fSAlexander Gordeev	 * pair points inside or outside of a block of instructions.
131b5415c8fSAlexander Gordeev	 * @reg: register to check
132b5415c8fSAlexander Gordeev	 * @start: start of the range
133b5415c8fSAlexander Gordeev	 * @end: end of the range
134b5415c8fSAlexander Gordeev	 * @outside_label: jump here if @reg is outside of [@start..@end)
135b5415c8fSAlexander Gordeev	 */
136b5415c8fSAlexander Gordeev	.macro OUTSIDE reg,start,end,outside_label
137b5415c8fSAlexander Gordeev	lgr	%r14,\reg
138b5415c8fSAlexander Gordeev	larl	%r13,\start
139b5415c8fSAlexander Gordeev	slgr	%r14,%r13
1404c25f0ffSHeiko Carstens	clgfrl	%r14,.Lrange_size\@
141b5415c8fSAlexander Gordeev	jhe	\outside_label
1424c25f0ffSHeiko Carstens	.section .rodata, "a"
1434c25f0ffSHeiko Carstens	.align 4
1444c25f0ffSHeiko Carstens.Lrange_size\@:
1454c25f0ffSHeiko Carstens	.long	\end - \start
1464c25f0ffSHeiko Carstens	.previous
147b5415c8fSAlexander Gordeev	.endm
148fbbdfca5SAlexander Gordeev
149fbbdfca5SAlexander Gordeev	.macro SIEEXIT
150fbbdfca5SAlexander Gordeev	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
151fbbdfca5SAlexander Gordeev	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
152fbbdfca5SAlexander Gordeev	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce
153fbbdfca5SAlexander Gordeev	larl	%r9,sie_exit			# skip forward to sie_exit
154fbbdfca5SAlexander Gordeev	.endm
155b5415c8fSAlexander Gordeev#endif
156b5415c8fSAlexander Gordeev
1576dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
158f19fbd5eSMartin Schwidefsky
1594bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
16046210c44SHeiko Carstens.Ldummy:
16146210c44SHeiko Carstens	/*
16269a407bfSHeiko Carstens	 * The following nop exists only in order to avoid that the next
16369a407bfSHeiko Carstens	 * symbol starts at the beginning of the kprobes text section.
16469a407bfSHeiko Carstens	 * In that case there would be several symbols at the same address.
16569a407bfSHeiko Carstens	 * E.g. objdump would take an arbitrary symbol when disassembling
16669a407bfSHeiko Carstens	 * the code.
16769a407bfSHeiko Carstens	 * With the added nop in between this cannot happen.
16846210c44SHeiko Carstens	 */
16946210c44SHeiko Carstens	nop	0
1704bfc86ceSHeiko Carstens
1714bfc86ceSHeiko Carstens/*
1724bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
1734bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
1744bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
1754bfc86ceSHeiko Carstens * Returns:
1764bfc86ceSHeiko Carstens *  gpr2 = prev
1774bfc86ceSHeiko Carstens */
1784bfc86ceSHeiko CarstensENTRY(__switch_to)
1794bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
1803241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
1813241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
1829fed920eSVasily Gorbik	llill	%r5,STACK_INIT
1833241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
1849fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
1859fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
1864bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
1874bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
1883241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
1893241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
1903241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
1914bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
192fad442d3SHeiko Carstens	ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
1936dd85fbbSMartin Schwidefsky	BR_EX	%r14
19426a374aeSMartin SchwidefskyENDPROC(__switch_to)
1954bfc86ceSHeiko Carstens
196d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
197d0fc4107SMartin Schwidefsky/*
1986b33e68aSNico Boehr * __sie64a calling convention:
1996b33e68aSNico Boehr * %r2 pointer to sie control block phys
2006b33e68aSNico Boehr * %r3 pointer to sie control block virt
2016b33e68aSNico Boehr * %r4 guest register save area
202d0fc4107SMartin Schwidefsky */
2036b33e68aSNico BoehrENTRY(__sie64a)
204d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2056b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
2066b33e68aSNico Boehr	stg	%r2,__SF_SIE_CONTROL_PHYS(%r15)	# save sie block physical..
2076b33e68aSNico Boehr	stg	%r3,__SF_SIE_CONTROL(%r15)	# ...and virtual addresses
2086b33e68aSNico Boehr	stg	%r4,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
20992fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
21092fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
2116b33e68aSNico Boehr	lmg	%r0,%r13,0(%r4)			# load guest gprs 0-13
212d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
213d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
214d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
215d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
216d0fc4107SMartin Schwidefsky.Lsie_gmap:
21792fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
218d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
219d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
220d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
22183abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
222d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
2236b33e68aSNico Boehr	lg	%r14,__SF_SIE_CONTROL_PHYS(%r15)	# get sie block phys addr
224f33f2d4cSHeiko Carstens	BPEXIT	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
225c929500dSQingFeng Hao.Lsie_entry:
226d0fc4107SMartin Schwidefsky	sie	0(%r14)
22729ccaa4bSAlexander Gordeev# Let the next instruction be NOP to avoid triggering a machine check
22829ccaa4bSAlexander Gordeev# and handling it in a guest as result of the instruction execution.
22929ccaa4bSAlexander Gordeev	nopr	7
23029ccaa4bSAlexander Gordeev.Lsie_leave:
231d768bd89SMartin Schwidefsky	BPOFF
232f33f2d4cSHeiko Carstens	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
233d0fc4107SMartin Schwidefsky.Lsie_skip:
2346b33e68aSNico Boehr	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
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.
2416b33e68aSNico Boehr# 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.
243c0e7bb38SChristian Borntraeger.Lrewind_pad6:
244c0e7bb38SChristian Borntraeger	nopr	7
245c0e7bb38SChristian Borntraeger.Lrewind_pad4:
246c0e7bb38SChristian Borntraeger	nopr	7
247c0e7bb38SChristian Borntraeger.Lrewind_pad2:
248c0e7bb38SChristian Borntraeger	nopr	7
249d0fc4107SMartin Schwidefsky	.globl sie_exit
250d0fc4107SMartin Schwidefskysie_exit:
25192fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
252d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2537041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2547041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2557041d281SMartin Schwidefsky	xgr	%r3,%r3
2567041d281SMartin Schwidefsky	xgr	%r4,%r4
2577041d281SMartin Schwidefsky	xgr	%r5,%r5
258d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
25992fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
2606dd85fbbSMartin Schwidefsky	BR_EX	%r14
261d0fc4107SMartin Schwidefsky.Lsie_fault:
262d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
26392fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
264d0fc4107SMartin Schwidefsky	j	sie_exit
265d0fc4107SMartin Schwidefsky
266c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
267c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
268c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
269d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
2706b33e68aSNico BoehrENDPROC(__sie64a)
2716b33e68aSNico BoehrEXPORT_SYMBOL(__sie64a)
272711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
273d0fc4107SMartin Schwidefsky#endif
274d0fc4107SMartin Schwidefsky
2754bfc86ceSHeiko Carstens/*
2764bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
2777b7735c5SChristian Borntraeger * are entered with interrupts disabled.
2784bfc86ceSHeiko Carstens */
2794bfc86ceSHeiko Carstens
2804bfc86ceSHeiko CarstensENTRY(system_call)
28156e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
2824bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
283d768bd89SMartin Schwidefsky	BPOFF
28456e62a73SSven Schnelle	lghi	%r14,0
2854bfc86ceSHeiko Carstens.Lsysc_per:
2863b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
28787d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
2884bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
2899365965dSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
29056e62a73SSven Schnelle	stmg	%r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
291d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
292d3f46896SChristian Borntraeger	xgr	%r0,%r0
29356e62a73SSven Schnelle	xgr	%r1,%r1
29456e62a73SSven Schnelle	xgr	%r4,%r4
29556e62a73SSven Schnelle	xgr	%r5,%r5
29656e62a73SSven Schnelle	xgr	%r6,%r6
29756e62a73SSven Schnelle	xgr	%r7,%r7
29856e62a73SSven Schnelle	xgr	%r8,%r8
29956e62a73SSven Schnelle	xgr	%r9,%r9
30056e62a73SSven Schnelle	xgr	%r10,%r10
30156e62a73SSven Schnelle	xgr	%r11,%r11
30256e62a73SSven Schnelle	la	%r2,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
303af9ad822SSven Schnelle	mvc	__PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
3043b051e89SSven Schnelle	MBEAR	%r2
30556e62a73SSven Schnelle	lgr	%r3,%r14
30656e62a73SSven Schnelle	brasl	%r14,__do_syscall
30787d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
30856e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
309f33f2d4cSHeiko Carstens	BPON
3103b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
31156e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3124bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3133b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
31426a374aeSMartin SchwidefskyENDPROC(system_call)
3154bfc86ceSHeiko Carstens
3164bfc86ceSHeiko Carstens#
3174bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
3184bfc86ceSHeiko Carstens#
3194bfc86ceSHeiko CarstensENTRY(ret_from_fork)
32056e62a73SSven Schnelle	lgr	%r3,%r11
32156e62a73SSven Schnelle	brasl	%r14,__ret_from_fork
32256e62a73SSven Schnelle	lctlg	%c1,%c1,__LC_USER_ASCE
32356e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
324f33f2d4cSHeiko Carstens	BPON
3253b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
32656e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
32756e62a73SSven Schnelle	stpt	__LC_EXIT_TIMER
3283b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__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	lghi	%r10,0
3404bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
34187d59863SHeiko Carstens	tmhh	%r8,0x0001		# coming from user space?
34287d59863SHeiko Carstens	jno	.Lpgm_skip_asce
34387d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_KERNEL_ASCE
34456e62a73SSven Schnelle	j	3f			# -> fault in user space
34587d59863SHeiko Carstens.Lpgm_skip_asce:
346d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
3476b33e68aSNico Boehr	# cleanup critical section for program checks in __sie64a
348b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f
349f33f2d4cSHeiko Carstens	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
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
361f33f2d4cSHeiko Carstens3:	lg	%r15,__LC_KERNEL_STACK
36256e62a73SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
36356e62a73SSven Schnelle	stg	%r10,__PT_FLAGS(%r11)
36456e62a73SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3654bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
36656e62a73SSven Schnelle	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3673b051e89SSven Schnelle	mvc	__PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK
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
383f33f2d4cSHeiko Carstens	BPON
3840cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
38556e62a73SSven Schnelle.Lpgm_exit_kernel:
38656e62a73SSven Schnelle	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
3873b051e89SSven Schnelle	LBEAR	STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
38856e62a73SSven Schnelle	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
3893b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE
3904bfc86ceSHeiko Carstens
3914bfc86ceSHeiko Carstens#
3924bfc86ceSHeiko Carstens# single stepped system call
3934bfc86ceSHeiko Carstens#
3944bfc86ceSHeiko Carstens.Lpgm_svcper:
3954bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
3964bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
3974bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
39856e62a73SSven Schnelle	lghi	%r14,1
3993b051e89SSven Schnelle	LBEAR	__LC_PGM_LAST_BREAK
4003b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per
40126a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
4024bfc86ceSHeiko Carstens
4034bfc86ceSHeiko Carstens/*
40456e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts.
4054bfc86ceSHeiko Carstens */
40656e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler
40756e62a73SSven SchnelleENTRY(\name)
40810bc15baSVasily Gorbik	stckf	__LC_INT_CLOCK
40956e62a73SSven Schnelle	stpt	__LC_SYS_ENTER_TIMER
4103b051e89SSven Schnelle	STBEAR	__LC_LAST_BREAK
411d768bd89SMartin Schwidefsky	BPOFF
4124bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
41356e62a73SSven Schnelle	lmg	%r8,%r9,\lc_old_psw
414b0d31159SSven Schnelle	tmhh	%r8,0x0001			# interrupting from user ?
415b0d31159SSven Schnelle	jnz	1f
416b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
417b5415c8fSAlexander Gordeev	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,0f
418f33f2d4cSHeiko Carstens	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
419fbbdfca5SAlexander Gordeev	SIEEXIT
420b0d31159SSven Schnelle#endif
421b0d31159SSven Schnelle0:	CHECK_STACK __LC_SAVE_AREA_ASYNC
422b0d31159SSven Schnelle	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
423b0d31159SSven Schnelle	j	2f
424f33f2d4cSHeiko Carstens1:	lctlg	%c1,%c1,__LC_KERNEL_ASCE
425b0d31159SSven Schnelle	lg	%r15,__LC_KERNEL_STACK
426b74e409eSVasily Gorbik2:	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
427b74e409eSVasily Gorbik	la	%r11,STACK_FRAME_OVERHEAD(%r15)
4284bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
4297041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
4307041d281SMartin Schwidefsky	xgr	%r0,%r0
4317041d281SMartin Schwidefsky	xgr	%r1,%r1
4327041d281SMartin Schwidefsky	xgr	%r3,%r3
4337041d281SMartin Schwidefsky	xgr	%r4,%r4
4347041d281SMartin Schwidefsky	xgr	%r5,%r5
4357041d281SMartin Schwidefsky	xgr	%r6,%r6
4367041d281SMartin Schwidefsky	xgr	%r7,%r7
4377041d281SMartin Schwidefsky	xgr	%r10,%r10
438ca1f4d70SSven Schnelle	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
4394bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
4403b051e89SSven Schnelle	MBEAR	%r11
4414bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
44229b06ad7SHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
44356e62a73SSven Schnelle	brasl	%r14,\handler
4444bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
44556e62a73SSven Schnelle	tmhh	%r8,0x0001		# returning to user ?
44656e62a73SSven Schnelle	jno	2f
44787d59863SHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE
448f33f2d4cSHeiko Carstens	BPON
4494bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4503b051e89SSven Schnelle2:	LBEAR	__PT_LAST_BREAK(%r11)
4513b051e89SSven Schnelle	lmg	%r0,%r15,__PT_R0(%r11)
4523b051e89SSven Schnelle	LPSWEY	__LC_RETURN_PSW,__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
47510bc15baSVasily Gorbik	stckf	__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)
48710bc15baSVasily Gorbik	stckf	__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
4913b051e89SSven Schnelle	LBEAR	__LC_LAST_BREAK_SAVE_AREA-4095(%r1)		# validate bear
492*385bf43cSVasily Gorbik	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA		# validate gprs
4934bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
49483abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
4954bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
4963037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
4973037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
498*385bf43cSVasily Gorbik	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA		# validate ctl regs
4993037a52fSMartin Schwidefsky	ptlb
5005fa2ea07SAlexander Gordeev	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
5014bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
50283abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
5034bfc86ceSHeiko Carstens	jo	3f
50456e62a73SSven Schnelle	la	%r14,__LC_SYS_ENTER_TIMER
50556e62a73SSven Schnelle	clc	0(8,%r14),__LC_EXIT_TIMER
5064bfc86ceSHeiko Carstens	jl	1f
5074bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
5084bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
5094bfc86ceSHeiko Carstens	jl	2f
5104bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
5114bfc86ceSHeiko Carstens2:	spt	0(%r14)
5124bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
5133037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
5143037a52fSMartin Schwidefsky	jno	.Lmcck_panic
5153037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
516742aed05SHeiko Carstens	jnz	.Lmcck_user
5173037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
5183037a52fSMartin Schwidefsky	jno	.Lmcck_panic
519b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
520f33f2d4cSHeiko Carstens	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,.Lmcck_user
52129ccaa4bSAlexander Gordeev	OUTSIDE	%r9,.Lsie_entry,.Lsie_leave,4f
52220232b18SAlexander Gordeev	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
523f33f2d4cSHeiko Carstens4:	BPENTER	__SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
524fbbdfca5SAlexander Gordeev	SIEEXIT
525e2c13d64SAlexander Gordeev#endif
526742aed05SHeiko Carstens.Lmcck_user:
527b61b1595SSven Schnelle	lg	%r15,__LC_MCCK_STACK
528b61b1595SSven Schnelle	la	%r11,STACK_FRAME_OVERHEAD(%r15)
52926521412SSven Schnelle	stctg	%c1,%c1,__PT_CR1(%r11)
530b61b1595SSven Schnelle	lctlg	%c1,%c1,__LC_KERNEL_ASCE
531b61b1595SSven Schnelle	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5324bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
5334bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
5347041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
5357041d281SMartin Schwidefsky	xgr	%r0,%r0
5367041d281SMartin Schwidefsky	xgr	%r1,%r1
5377041d281SMartin Schwidefsky	xgr	%r3,%r3
5387041d281SMartin Schwidefsky	xgr	%r4,%r4
5397041d281SMartin Schwidefsky	xgr	%r5,%r5
5407041d281SMartin Schwidefsky	xgr	%r6,%r6
5417041d281SMartin Schwidefsky	xgr	%r7,%r7
5427041d281SMartin Schwidefsky	xgr	%r10,%r10
5434bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
5444bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
5454bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
5464bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
5474bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5484bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
54987d59863SHeiko Carstens	lctlg	%c1,%c1,__PT_CR1(%r11)
5504bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
5514bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
5524bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
5534bfc86ceSHeiko Carstens	jno	0f
554f33f2d4cSHeiko Carstens	BPON
5554bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
556fad442d3SHeiko Carstens0:	ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
5573b051e89SSven Schnelle	LBEAR	0(%r12)
5583b051e89SSven Schnelle	lmg	%r11,%r15,__PT_R11(%r11)
5593b051e89SSven Schnelle	LPSWEY	__LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
5604bfc86ceSHeiko Carstens
5614bfc86ceSHeiko Carstens.Lmcck_panic:
5627f6dc8d4SAlexander Gordeev	/*
5637f6dc8d4SAlexander Gordeev	 * Iterate over all possible CPU addresses in the range 0..0xffff
5647f6dc8d4SAlexander Gordeev	 * and stop each CPU using signal processor. Use compare and swap
5657f6dc8d4SAlexander Gordeev	 * to allow just one CPU-stopper and prevent concurrent CPUs from
5667f6dc8d4SAlexander Gordeev	 * stopping each other while leaving the others running.
5677f6dc8d4SAlexander Gordeev	 */
5687f6dc8d4SAlexander Gordeev	lhi	%r5,0
5697f6dc8d4SAlexander Gordeev	lhi	%r6,1
5707f6dc8d4SAlexander Gordeev	larl	%r7,.Lstop_lock
5717f6dc8d4SAlexander Gordeev	cs	%r5,%r6,0(%r7)		# single CPU-stopper only
5727f6dc8d4SAlexander Gordeev	jnz	4f
5737f6dc8d4SAlexander Gordeev	larl	%r7,.Lthis_cpu
5747f6dc8d4SAlexander Gordeev	stap	0(%r7)			# this CPU address
5757f6dc8d4SAlexander Gordeev	lh	%r4,0(%r7)
5767f6dc8d4SAlexander Gordeev	nilh	%r4,0
5777f6dc8d4SAlexander Gordeev	lhi	%r0,1
5787f6dc8d4SAlexander Gordeev	sll	%r0,16			# CPU counter
5797f6dc8d4SAlexander Gordeev	lhi	%r3,0			# next CPU address
5807f6dc8d4SAlexander Gordeev0:	cr	%r3,%r4
5817f6dc8d4SAlexander Gordeev	je	2f
5827f6dc8d4SAlexander Gordeev1:	sigp	%r1,%r3,SIGP_STOP	# stop next CPU
5837f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,1b
5847f6dc8d4SAlexander Gordeev2:	ahi	%r3,1
5857f6dc8d4SAlexander Gordeev	brct	%r0,0b
5867f6dc8d4SAlexander Gordeev3:	sigp	%r1,%r4,SIGP_STOP	# stop this CPU
5877f6dc8d4SAlexander Gordeev	brc	SIGP_CC_BUSY,3b
5887f6dc8d4SAlexander Gordeev4:	j	4b
58926a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
5904bfc86ceSHeiko Carstens
5914bfc86ceSHeiko CarstensENTRY(restart_int_handler)
592fad442d3SHeiko Carstens	ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
593e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
594915fea04SAlexander Gordeev	TSTMSK	__LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
595915fea04SAlexander Gordeev	jz	0f
596*385bf43cSVasily Gorbik	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA
597915fea04SAlexander Gordeev0:	larl	%r15,.Lstosm_tmp
598915fea04SAlexander Gordeev	stosm	0(%r15),0x04			# turn dat on, keep irqs off
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
607915fea04SAlexander Gordeev	lgf	%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
6417f6dc8d4SAlexander Gordeev	.section .data, "aw"
6427f6dc8d4SAlexander Gordeev		.align	4
6437f6dc8d4SAlexander Gordeev.Lstop_lock:	.long	0
6447f6dc8d4SAlexander Gordeev.Lthis_cpu:	.short	0
645d35925b3SAlexander Gordeev.Lstosm_tmp:	.byte	0
6464bfc86ceSHeiko Carstens	.section .rodata, "a"
647ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
6484bfc86ceSHeiko Carstens	.globl	sys_call_table
6494bfc86ceSHeiko Carstenssys_call_table:
6504381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
6514bfc86ceSHeiko Carstens#undef SYSCALL
6524bfc86ceSHeiko Carstens
6534bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
6544bfc86ceSHeiko Carstens
655ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
6564bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
6574bfc86ceSHeiko Carstenssys_call_table_emu:
6584381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
6594bfc86ceSHeiko Carstens#undef SYSCALL
6604bfc86ceSHeiko Carstens#endif
661