xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 26a374ae7af8d7003ad28a962fba0141e68af5da)
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
544bfc86ceSHeiko Carstens_TIF_WORK	= (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
5576f1948aSLinus Torvalds		   _TIF_UPROBE | _TIF_GUARDED_STORAGE | _TIF_PATCH_PENDING)
564bfc86ceSHeiko Carstens_TIF_TRACE	= (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
574bfc86ceSHeiko Carstens		   _TIF_SYSCALL_TRACEPOINT)
58b5a882fcSHeiko Carstens_CIF_WORK	= (_CIF_MCCK_PENDING | _CIF_ASCE_PRIMARY | \
59b5a882fcSHeiko Carstens		   _CIF_ASCE_SECONDARY | _CIF_FPU)
6023fefe11SMartin Schwidefsky_PIF_WORK	= (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
614bfc86ceSHeiko Carstens
62e5b98199SMartin Schwidefsky_LPP_OFFSET	= __LC_LPP
63e5b98199SMartin Schwidefsky
649977e886SHendrik Brueckner#define BASED(name) name-cleanup_critical(%r13)
654bfc86ceSHeiko Carstens
664bfc86ceSHeiko Carstens	.macro	TRACE_IRQS_ON
674bfc86ceSHeiko Carstens#ifdef CONFIG_TRACE_IRQFLAGS
684bfc86ceSHeiko Carstens	basr	%r2,%r0
694bfc86ceSHeiko Carstens	brasl	%r14,trace_hardirqs_on_caller
704bfc86ceSHeiko Carstens#endif
714bfc86ceSHeiko Carstens	.endm
724bfc86ceSHeiko Carstens
734bfc86ceSHeiko Carstens	.macro	TRACE_IRQS_OFF
744bfc86ceSHeiko Carstens#ifdef CONFIG_TRACE_IRQFLAGS
754bfc86ceSHeiko Carstens	basr	%r2,%r0
764bfc86ceSHeiko Carstens	brasl	%r14,trace_hardirqs_off_caller
774bfc86ceSHeiko Carstens#endif
784bfc86ceSHeiko Carstens	.endm
794bfc86ceSHeiko Carstens
804bfc86ceSHeiko Carstens	.macro	LOCKDEP_SYS_EXIT
814bfc86ceSHeiko Carstens#ifdef CONFIG_LOCKDEP
824bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
834bfc86ceSHeiko Carstens	jz	.+10
844bfc86ceSHeiko Carstens	brasl	%r14,lockdep_sys_exit
854bfc86ceSHeiko Carstens#endif
864bfc86ceSHeiko Carstens	.endm
874bfc86ceSHeiko Carstens
88ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
894bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
90ce3dc447SMartin Schwidefsky	tml	%r15,STACK_SIZE - CONFIG_STACK_GUARD
914bfc86ceSHeiko Carstens	lghi	%r14,\savearea
924bfc86ceSHeiko Carstens	jz	stack_overflow
934bfc86ceSHeiko Carstens#endif
944bfc86ceSHeiko Carstens	.endm
954bfc86ceSHeiko Carstens
96ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
97ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
98ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
99ce3dc447SMartin Schwidefsky	nill	%r14,0x10000 - STACK_SIZE
100ce3dc447SMartin Schwidefsky	oill	%r14,STACK_INIT
101ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
102ce3dc447SMartin Schwidefsky	je	\oklabel
103ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
104ce3dc447SMartin Schwidefsky	je	\oklabel
105ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
106ce3dc447SMartin Schwidefsky	je	\oklabel
107ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
108ce3dc447SMartin Schwidefsky	je	\oklabel
109ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
110ce3dc447SMartin Schwidefsky	j	stack_overflow
111ce3dc447SMartin Schwidefsky#else
112ce3dc447SMartin Schwidefsky	j	\oklabel
113ce3dc447SMartin Schwidefsky#endif
114ce3dc447SMartin Schwidefsky	.endm
115ce3dc447SMartin Schwidefsky
1162acb94f4SMartin Schwidefsky	.macro	SWITCH_ASYNC savearea,timer
1174bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# interrupting from user ?
1184bfc86ceSHeiko Carstens	jnz	1f
1194bfc86ceSHeiko Carstens	lgr	%r14,%r9
1204bfc86ceSHeiko Carstens	slg	%r14,BASED(.Lcritical_start)
1214bfc86ceSHeiko Carstens	clg	%r14,BASED(.Lcritical_length)
1224bfc86ceSHeiko Carstens	jhe	0f
1234bfc86ceSHeiko Carstens	lghi	%r11,\savearea		# inside critical section, do cleanup
1244bfc86ceSHeiko Carstens	brasl	%r14,cleanup_critical
1254bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# retest problem state after cleanup
1264bfc86ceSHeiko Carstens	jnz	1f
127ce3dc447SMartin Schwidefsky0:	lg	%r14,__LC_ASYNC_STACK	# are we already on the target stack?
1284bfc86ceSHeiko Carstens	slgr	%r14,%r15
1292acb94f4SMartin Schwidefsky	srag	%r14,%r14,STACK_SHIFT
130a359bb11SMartin Schwidefsky	jnz	2f
131ce3dc447SMartin Schwidefsky	CHECK_STACK \savearea
1324bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
133a359bb11SMartin Schwidefsky	j	3f
13434525e1fSMartin Schwidefsky1:	UPDATE_VTIME %r14,%r15,\timer
1356b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
1362acb94f4SMartin Schwidefsky2:	lg	%r15,__LC_ASYNC_STACK	# load async stack
137a359bb11SMartin Schwidefsky3:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
1384bfc86ceSHeiko Carstens	.endm
1394bfc86ceSHeiko Carstens
140a359bb11SMartin Schwidefsky	.macro UPDATE_VTIME w1,w2,enter_timer
141a359bb11SMartin Schwidefsky	lg	\w1,__LC_EXIT_TIMER
142a359bb11SMartin Schwidefsky	lg	\w2,__LC_LAST_UPDATE_TIMER
143a359bb11SMartin Schwidefsky	slg	\w1,\enter_timer
144a359bb11SMartin Schwidefsky	slg	\w2,__LC_EXIT_TIMER
145a359bb11SMartin Schwidefsky	alg	\w1,__LC_USER_TIMER
146a359bb11SMartin Schwidefsky	alg	\w2,__LC_SYSTEM_TIMER
147a359bb11SMartin Schwidefsky	stg	\w1,__LC_USER_TIMER
148a359bb11SMartin Schwidefsky	stg	\w2,__LC_SYSTEM_TIMER
1494bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),\enter_timer
1504bfc86ceSHeiko Carstens	.endm
1514bfc86ceSHeiko Carstens
1524bfc86ceSHeiko Carstens	.macro REENABLE_IRQS
1534bfc86ceSHeiko Carstens	stg	%r8,__LC_RETURN_PSW
1544bfc86ceSHeiko Carstens	ni	__LC_RETURN_PSW,0xbf
1554bfc86ceSHeiko Carstens	ssm	__LC_RETURN_PSW
1564bfc86ceSHeiko Carstens	.endm
1574bfc86ceSHeiko Carstens
1584bfc86ceSHeiko Carstens	.macro STCK savearea
1594bfc86ceSHeiko Carstens#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
1604bfc86ceSHeiko Carstens	.insn	s,0xb27c0000,\savearea		# store clock fast
1614bfc86ceSHeiko Carstens#else
1624bfc86ceSHeiko Carstens	.insn	s,0xb2050000,\savearea		# store clock
1634bfc86ceSHeiko Carstens#endif
1644bfc86ceSHeiko Carstens	.endm
1654bfc86ceSHeiko Carstens
16683abeffbSHendrik Brueckner	/*
16783abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
16883abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
16983abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
17083abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
17183abeffbSHendrik Brueckner	 * instruction.
17283abeffbSHendrik Brueckner	 */
17383abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
17483abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
17583abeffbSHendrik Brueckner			.if (\mask & 0xff)
17683abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
17783abeffbSHendrik Brueckner			.endif
17883abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
17983abeffbSHendrik Brueckner			.exitm
18083abeffbSHendrik Brueckner		.endif
18183abeffbSHendrik Brueckner		.ifeq \mask
18283abeffbSHendrik Brueckner			.error "Mask must not be zero"
18383abeffbSHendrik Brueckner		.endif
18483abeffbSHendrik Brueckner		off = \size - \bytepos - 1
18583abeffbSHendrik Brueckner		tm	off+\addr, \mask
18683abeffbSHendrik Brueckner	.endm
18783abeffbSHendrik Brueckner
188d768bd89SMartin Schwidefsky	.macro BPOFF
189b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
190d768bd89SMartin Schwidefsky	.endm
191d768bd89SMartin Schwidefsky
192d768bd89SMartin Schwidefsky	.macro BPON
193b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
194d768bd89SMartin Schwidefsky	.endm
195d768bd89SMartin Schwidefsky
1966b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
197b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
198b058661aSMartin Schwidefsky		    "", 82
1996b73044bSMartin Schwidefsky	.endm
2006b73044bSMartin Schwidefsky
2016b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
2026b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
203b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
204b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
2056b73044bSMartin Schwidefsky	.endm
2066b73044bSMartin Schwidefsky
2076dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r9
2086dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
2096dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14,%r11
210f19fbd5eSMartin Schwidefsky
2114bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
21246210c44SHeiko Carstens.Ldummy:
21346210c44SHeiko Carstens	/*
21446210c44SHeiko Carstens	 * This nop exists only in order to avoid that __switch_to starts at
21546210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
21646210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
21746210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
21846210c44SHeiko Carstens	 * With the added nop in between the __switch_to symbol is unique
21946210c44SHeiko Carstens	 * again.
22046210c44SHeiko Carstens	 */
22146210c44SHeiko Carstens	nop	0
2224bfc86ceSHeiko Carstens
223d768bd89SMartin SchwidefskyENTRY(__bpon)
224d768bd89SMartin Schwidefsky	.globl __bpon
225d768bd89SMartin Schwidefsky	BPON
2266dd85fbbSMartin Schwidefsky	BR_EX	%r14
227*26a374aeSMartin SchwidefskyENDPROC(__bpon)
228d768bd89SMartin Schwidefsky
2294bfc86ceSHeiko Carstens/*
2304bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2314bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2324bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2334bfc86ceSHeiko Carstens * Returns:
2344bfc86ceSHeiko Carstens *  gpr2 = prev
2354bfc86ceSHeiko Carstens */
2364bfc86ceSHeiko CarstensENTRY(__switch_to)
2374bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2383241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2393241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2409fed920eSVasily Gorbik	llill	%r5,STACK_INIT
2413241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2429fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
2439fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
2444bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2454bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2463241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2473241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2483241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2494bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
250e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2516dd85fbbSMartin Schwidefsky	BR_EX	%r14
252*26a374aeSMartin SchwidefskyENDPROC(__switch_to)
2534bfc86ceSHeiko Carstens
2544bfc86ceSHeiko Carstens.L__critical_start:
255d0fc4107SMartin Schwidefsky
256d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
257d0fc4107SMartin Schwidefsky/*
258d0fc4107SMartin Schwidefsky * sie64a calling convention:
259d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
260d0fc4107SMartin Schwidefsky * %r3 guest register save area
261d0fc4107SMartin Schwidefsky */
262d0fc4107SMartin SchwidefskyENTRY(sie64a)
263d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2646b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
26592fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
26692fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
26792fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
26892fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
26983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU		# load guest fp/vx registers ?
270d0fc4107SMartin Schwidefsky	jno	.Lsie_load_guest_gprs
271d0fc4107SMartin Schwidefsky	brasl	%r14,load_fpu_regs		# load guest fp/vx regs
272d0fc4107SMartin Schwidefsky.Lsie_load_guest_gprs:
273d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
274d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
275d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
276d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
277d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
278d0fc4107SMartin Schwidefsky.Lsie_gmap:
27992fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
280d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
281d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
282d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
28383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
284d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
28592fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
286c929500dSQingFeng Hao.Lsie_entry:
287d0fc4107SMartin Schwidefsky	sie	0(%r14)
288d768bd89SMartin Schwidefsky.Lsie_exit:
289d768bd89SMartin Schwidefsky	BPOFF
29092fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
291d0fc4107SMartin Schwidefsky.Lsie_skip:
292d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
293d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
294d0fc4107SMartin Schwidefsky.Lsie_done:
295d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
296c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
297c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
298c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
299c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
300d0fc4107SMartin Schwidefsky# See also .Lcleanup_sie
301c0e7bb38SChristian Borntraeger.Lrewind_pad6:
302c0e7bb38SChristian Borntraeger	nopr	7
303c0e7bb38SChristian Borntraeger.Lrewind_pad4:
304c0e7bb38SChristian Borntraeger	nopr	7
305c0e7bb38SChristian Borntraeger.Lrewind_pad2:
306c0e7bb38SChristian Borntraeger	nopr	7
307d0fc4107SMartin Schwidefsky	.globl sie_exit
308d0fc4107SMartin Schwidefskysie_exit:
30992fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
310d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
3117041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
3127041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
3137041d281SMartin Schwidefsky	xgr	%r2,%r2
3147041d281SMartin Schwidefsky	xgr	%r3,%r3
3157041d281SMartin Schwidefsky	xgr	%r4,%r4
3167041d281SMartin Schwidefsky	xgr	%r5,%r5
317d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
31892fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
3196dd85fbbSMartin Schwidefsky	BR_EX	%r14
320d0fc4107SMartin Schwidefsky.Lsie_fault:
321d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
32292fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
323d0fc4107SMartin Schwidefsky	j	sie_exit
324d0fc4107SMartin Schwidefsky
325c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
326c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
327c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
328d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
329*26a374aeSMartin SchwidefskyENDPROC(sie64a)
330711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
331711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
332d0fc4107SMartin Schwidefsky#endif
333d0fc4107SMartin Schwidefsky
3344bfc86ceSHeiko Carstens/*
3354bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3364bfc86ceSHeiko Carstens * are executed with interrupts enabled.
3374bfc86ceSHeiko Carstens */
3384bfc86ceSHeiko Carstens
3394bfc86ceSHeiko CarstensENTRY(system_call)
3404bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
3414bfc86ceSHeiko Carstens.Lsysc_stmg:
3424bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
343d768bd89SMartin Schwidefsky	BPOFF
344d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
34534525e1fSMartin Schwidefsky	lghi	%r13,__TASK_thread
3464bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL
3474bfc86ceSHeiko Carstens.Lsysc_per:
3484bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3494bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
350a359bb11SMartin Schwidefsky.Lsysc_vtime:
35134525e1fSMartin Schwidefsky	UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
3526b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3534bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
3544bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3554bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r11),__LC_SVC_OLD_PSW
3564bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_SVC_ILC
3574bfc86ceSHeiko Carstens	stg	%r14,__PT_FLAGS(%r11)
3584bfc86ceSHeiko Carstens.Lsysc_do_svc:
359d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
360d3f46896SChristian Borntraeger	xgr	%r0,%r0
361ef280c85SMartin Schwidefsky	# load address of system call table
362ef280c85SMartin Schwidefsky	lg	%r10,__THREAD_sysc_table(%r13,%r12)
3634bfc86ceSHeiko Carstens	llgh	%r8,__PT_INT_CODE+2(%r11)
364ff4a742dSGerald Schaefer	slag	%r8,%r8,3			# shift and test for svc 0
3654bfc86ceSHeiko Carstens	jnz	.Lsysc_nr_ok
3664bfc86ceSHeiko Carstens	# svc 0: system call number in %r1
3674bfc86ceSHeiko Carstens	llgfr	%r1,%r1				# clear high word in r1
3684bfc86ceSHeiko Carstens	cghi	%r1,NR_syscalls
3694bfc86ceSHeiko Carstens	jnl	.Lsysc_nr_ok
3704bfc86ceSHeiko Carstens	sth	%r1,__PT_INT_CODE+2(%r11)
371ff4a742dSGerald Schaefer	slag	%r8,%r1,3
3724bfc86ceSHeiko Carstens.Lsysc_nr_ok:
3734bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3744bfc86ceSHeiko Carstens	stg	%r2,__PT_ORIG_GPR2(%r11)
3754bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
376ff4a742dSGerald Schaefer	lg	%r9,0(%r8,%r10)			# get system call add.
37783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
3784bfc86ceSHeiko Carstens	jnz	.Lsysc_tracesys
3796dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9			# call sys_xxxx
3804bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)		# store return value
3814bfc86ceSHeiko Carstens
3824bfc86ceSHeiko Carstens.Lsysc_return:
3839d6d99e3SHeiko Carstens#ifdef CONFIG_DEBUG_RSEQ
3849d6d99e3SHeiko Carstens	lgr	%r2,%r11
3859d6d99e3SHeiko Carstens	brasl	%r14,rseq_syscall
3869d6d99e3SHeiko Carstens#endif
3874bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
3884bfc86ceSHeiko Carstens.Lsysc_tif:
38983abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_WORK
3904bfc86ceSHeiko Carstens	jnz	.Lsysc_work
39183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
3924bfc86ceSHeiko Carstens	jnz	.Lsysc_work			# check for work
39383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
3944bfc86ceSHeiko Carstens	jnz	.Lsysc_work
3956b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
3964bfc86ceSHeiko Carstens.Lsysc_restore:
3974bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
3984bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
3994bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
40007a63cbeSMartin Schwidefsky.Lsysc_exit_timer:
4014bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4024bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
4034bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
4044bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW
4054bfc86ceSHeiko Carstens.Lsysc_done:
4064bfc86ceSHeiko Carstens
4074bfc86ceSHeiko Carstens#
4084bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
4094bfc86ceSHeiko Carstens#
4104bfc86ceSHeiko Carstens.Lsysc_work:
41183abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
4124bfc86ceSHeiko Carstens	jo	.Lsysc_mcck_pending
41383abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
4144bfc86ceSHeiko Carstens	jo	.Lsysc_reschedule
41523fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
41623fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
4174bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
41883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_UPROBE
4194bfc86ceSHeiko Carstens	jo	.Lsysc_uprobe_notify
4204bfc86ceSHeiko Carstens#endif
421916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
422916cda1aSMartin Schwidefsky	jo	.Lsysc_guarded_storage
42383abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_PER_TRAP
4244bfc86ceSHeiko Carstens	jo	.Lsysc_singlestep
4252f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
4262f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
4272f09ca60SMiroslav Benes	jo	.Lsysc_patch_pending	# handle live patching just before
4282f09ca60SMiroslav Benes					# signals and possible syscall restart
4292f09ca60SMiroslav Benes#endif
43023fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
43123fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
43283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
4334bfc86ceSHeiko Carstens	jo	.Lsysc_sigpending
43483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
4354bfc86ceSHeiko Carstens	jo	.Lsysc_notify_resume
43683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
4379977e886SHendrik Brueckner	jo	.Lsysc_vxrs
438b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
439b5a882fcSHeiko Carstens	jnz	.Lsysc_asce
4404bfc86ceSHeiko Carstens	j	.Lsysc_return		# beware of critical section cleanup
4414bfc86ceSHeiko Carstens
4424bfc86ceSHeiko Carstens#
4434bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
4444bfc86ceSHeiko Carstens#
4454bfc86ceSHeiko Carstens.Lsysc_reschedule:
4464bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4474bfc86ceSHeiko Carstens	jg	schedule
4484bfc86ceSHeiko Carstens
4494bfc86ceSHeiko Carstens#
4504bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
4514bfc86ceSHeiko Carstens#
4524bfc86ceSHeiko Carstens.Lsysc_mcck_pending:
4534bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4544bfc86ceSHeiko Carstens	jg	s390_handle_mcck	# TIF bit will be cleared by handler
4554bfc86ceSHeiko Carstens
4564bfc86ceSHeiko Carstens#
4570aaba41bSMartin Schwidefsky# _CIF_ASCE_PRIMARY and/or _CIF_ASCE_SECONDARY set, load user space asce
4584bfc86ceSHeiko Carstens#
459b5a882fcSHeiko Carstens.Lsysc_asce:
4600aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
4610aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
4620aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
4630aaba41bSMartin Schwidefsky	jz	.Lsysc_return
4640aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
4650aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
4660aaba41bSMartin Schwidefsky	jnz	.Lsysc_set_fs_fixup
467606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
4684bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
4690aaba41bSMartin Schwidefsky	j	.Lsysc_return
4700aaba41bSMartin Schwidefsky.Lsysc_set_fs_fixup:
4710aaba41bSMartin Schwidefsky#endif
472b5a882fcSHeiko Carstens	larl	%r14,.Lsysc_return
473b5a882fcSHeiko Carstens	jg	set_fs_fixup
4744bfc86ceSHeiko Carstens
4754bfc86ceSHeiko Carstens#
4769977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
4779977e886SHendrik Brueckner#
4789977e886SHendrik Brueckner.Lsysc_vxrs:
4799977e886SHendrik Brueckner	larl	%r14,.Lsysc_return
4809977e886SHendrik Brueckner	jg	load_fpu_regs
4819977e886SHendrik Brueckner
4829977e886SHendrik Brueckner#
4834bfc86ceSHeiko Carstens# _TIF_SIGPENDING is set, call do_signal
4844bfc86ceSHeiko Carstens#
4854bfc86ceSHeiko Carstens.Lsysc_sigpending:
4864bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
4874bfc86ceSHeiko Carstens	brasl	%r14,do_signal
48883abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
4894bfc86ceSHeiko Carstens	jno	.Lsysc_return
49057d7f939SMartin Schwidefsky.Lsysc_do_syscall:
49157d7f939SMartin Schwidefsky	lghi	%r13,__TASK_thread
4924bfc86ceSHeiko Carstens	lmg	%r2,%r7,__PT_R2(%r11)	# load svc arguments
49357d7f939SMartin Schwidefsky	lghi	%r1,0			# svc 0 returns -ENOSYS
49457d7f939SMartin Schwidefsky	j	.Lsysc_do_svc
4954bfc86ceSHeiko Carstens
4964bfc86ceSHeiko Carstens#
4974bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME is set, call do_notify_resume
4984bfc86ceSHeiko Carstens#
4994bfc86ceSHeiko Carstens.Lsysc_notify_resume:
5004bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5014bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5024bfc86ceSHeiko Carstens	jg	do_notify_resume
5034bfc86ceSHeiko Carstens
5044bfc86ceSHeiko Carstens#
5054bfc86ceSHeiko Carstens# _TIF_UPROBE is set, call uprobe_notify_resume
5064bfc86ceSHeiko Carstens#
5074bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
5084bfc86ceSHeiko Carstens.Lsysc_uprobe_notify:
5094bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5104bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5114bfc86ceSHeiko Carstens	jg	uprobe_notify_resume
5124bfc86ceSHeiko Carstens#endif
5134bfc86ceSHeiko Carstens
5144bfc86ceSHeiko Carstens#
515916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
516916cda1aSMartin Schwidefsky#
517916cda1aSMartin Schwidefsky.Lsysc_guarded_storage:
518916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
519916cda1aSMartin Schwidefsky	larl	%r14,.Lsysc_return
520916cda1aSMartin Schwidefsky	jg	gs_load_bc_cb
52176f1948aSLinus Torvalds#
5222f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
5232f09ca60SMiroslav Benes#
5242f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
5252f09ca60SMiroslav Benes.Lsysc_patch_pending:
5262f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
5272f09ca60SMiroslav Benes	larl	%r14,.Lsysc_return
5282f09ca60SMiroslav Benes	jg	klp_update_patch_state
5292f09ca60SMiroslav Benes#endif
530916cda1aSMartin Schwidefsky
531916cda1aSMartin Schwidefsky#
5324bfc86ceSHeiko Carstens# _PIF_PER_TRAP is set, call do_per_trap
5334bfc86ceSHeiko Carstens#
5344bfc86ceSHeiko Carstens.Lsysc_singlestep:
5354bfc86ceSHeiko Carstens	ni	__PT_FLAGS+7(%r11),255-_PIF_PER_TRAP
5364bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5374bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5384bfc86ceSHeiko Carstens	jg	do_per_trap
5394bfc86ceSHeiko Carstens
5404bfc86ceSHeiko Carstens#
54123fefe11SMartin Schwidefsky# _PIF_SYSCALL_RESTART is set, repeat the current system call
54223fefe11SMartin Schwidefsky#
54323fefe11SMartin Schwidefsky.Lsysc_syscall_restart:
54423fefe11SMartin Schwidefsky	ni	__PT_FLAGS+7(%r11),255-_PIF_SYSCALL_RESTART
54523fefe11SMartin Schwidefsky	lmg	%r1,%r7,__PT_R1(%r11)	# load svc arguments
54623fefe11SMartin Schwidefsky	lg	%r2,__PT_ORIG_GPR2(%r11)
54723fefe11SMartin Schwidefsky	j	.Lsysc_do_svc
54823fefe11SMartin Schwidefsky
54923fefe11SMartin Schwidefsky#
5504bfc86ceSHeiko Carstens# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
5514bfc86ceSHeiko Carstens# and after the system call
5524bfc86ceSHeiko Carstens#
5534bfc86ceSHeiko Carstens.Lsysc_tracesys:
5544bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5554bfc86ceSHeiko Carstens	la	%r3,0
5564bfc86ceSHeiko Carstens	llgh	%r0,__PT_INT_CODE+2(%r11)
5574bfc86ceSHeiko Carstens	stg	%r0,__PT_R2(%r11)
5584bfc86ceSHeiko Carstens	brasl	%r14,do_syscall_trace_enter
5594bfc86ceSHeiko Carstens	lghi	%r0,NR_syscalls
5604bfc86ceSHeiko Carstens	clgr	%r0,%r2
5614bfc86ceSHeiko Carstens	jnh	.Lsysc_tracenogo
562ff4a742dSGerald Schaefer	sllg	%r8,%r2,3
563ff4a742dSGerald Schaefer	lg	%r9,0(%r8,%r10)
5644bfc86ceSHeiko Carstens.Lsysc_tracego:
5654bfc86ceSHeiko Carstens	lmg	%r3,%r7,__PT_R3(%r11)
5664bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
5674bfc86ceSHeiko Carstens	lg	%r2,__PT_ORIG_GPR2(%r11)
5686dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# call sys_xxx
5694bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)	# store return value
5704bfc86ceSHeiko Carstens.Lsysc_tracenogo:
57183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
5724bfc86ceSHeiko Carstens	jz	.Lsysc_return
5734bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5744bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5754bfc86ceSHeiko Carstens	jg	do_syscall_trace_exit
576*26a374aeSMartin SchwidefskyENDPROC(system_call)
5774bfc86ceSHeiko Carstens
5784bfc86ceSHeiko Carstens#
5794bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
5804bfc86ceSHeiko Carstens#
5814bfc86ceSHeiko CarstensENTRY(ret_from_fork)
5824bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
583d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
5844bfc86ceSHeiko Carstens	brasl	%r14,schedule_tail
5854bfc86ceSHeiko Carstens	TRACE_IRQS_ON
5864bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
5874bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
5884bfc86ceSHeiko Carstens	jne	.Lsysc_tracenogo
5894bfc86ceSHeiko Carstens	# it's a kernel thread
5904bfc86ceSHeiko Carstens	lmg	%r9,%r10,__PT_R9(%r11)	# load gprs
591*26a374aeSMartin Schwidefsky	la	%r2,0(%r10)
592*26a374aeSMartin Schwidefsky	BASR_EX	%r14,%r9
593*26a374aeSMartin Schwidefsky	j	.Lsysc_tracenogo
594*26a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
595*26a374aeSMartin Schwidefsky
5964bfc86ceSHeiko CarstensENTRY(kernel_thread_starter)
5974bfc86ceSHeiko Carstens	la	%r2,0(%r10)
5986dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9
5994bfc86ceSHeiko Carstens	j	.Lsysc_tracenogo
600*26a374aeSMartin SchwidefskyENDPROC(kernel_thread_starter)
6014bfc86ceSHeiko Carstens
6024bfc86ceSHeiko Carstens/*
6034bfc86ceSHeiko Carstens * Program check handler routine
6044bfc86ceSHeiko Carstens */
6054bfc86ceSHeiko Carstens
6064bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
6074bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
608d768bd89SMartin Schwidefsky	BPOFF
6094bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
6104bfc86ceSHeiko Carstens	lg	%r10,__LC_LAST_BREAK
611d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
612c771320eSMartin Schwidefsky	lghi	%r11,0
6139977e886SHendrik Brueckner	larl	%r13,cleanup_critical
6144bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
6154bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# test problem state bit
616d0fc4107SMartin Schwidefsky	jnz	2f			# -> fault in user space
617d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
6180a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
619d0fc4107SMartin Schwidefsky	lgr	%r14,%r9
620d0fc4107SMartin Schwidefsky	slg	%r14,BASED(.Lsie_critical_start)
621d0fc4107SMartin Schwidefsky	clg	%r14,BASED(.Lsie_critical_length)
622d0fc4107SMartin Schwidefsky	jhe	0f
62392fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
6240a5e2ec2SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
6250a5e2ec2SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
6260a5e2ec2SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
627c771320eSMartin Schwidefsky	lghi	%r11,_PIF_GUEST_FAULT
628d0fc4107SMartin Schwidefsky#endif
629d0fc4107SMartin Schwidefsky0:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
630d0fc4107SMartin Schwidefsky	jnz	1f			# -> enabled, can't be a double fault
6314bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
6324bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
633ce3dc447SMartin Schwidefsky1:	CHECK_STACK __LC_SAVE_AREA_SYNC
6344bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
635ce3dc447SMartin Schwidefsky	# CHECK_VMAP_STACK branches to stack_overflow or 4f
636ce3dc447SMartin Schwidefsky	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
63734525e1fSMartin Schwidefsky2:	UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
6386b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
6394bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
640d5c352cdSHeiko Carstens	lgr	%r14,%r12
6413827ec3dSMartin Schwidefsky	aghi	%r14,__TASK_thread	# pointer to thread_struct
6424bfc86ceSHeiko Carstens	lghi	%r13,__LC_PGM_TDB
6434bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+2,0x02	# check for transaction abort
644d0fc4107SMartin Schwidefsky	jz	3f
6454bfc86ceSHeiko Carstens	mvc	__THREAD_trap_tdb(256,%r14),0(%r13)
646d9fcf2a1SMartin Schwidefsky3:	stg	%r10,__THREAD_last_break(%r14)
647c771320eSMartin Schwidefsky4:	lgr	%r13,%r11
648c771320eSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6494bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6507041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
6517041d281SMartin Schwidefsky	xgr	%r0,%r0
6527041d281SMartin Schwidefsky	xgr	%r1,%r1
6537041d281SMartin Schwidefsky	xgr	%r2,%r2
6547041d281SMartin Schwidefsky	xgr	%r3,%r3
6557041d281SMartin Schwidefsky	xgr	%r4,%r4
6567041d281SMartin Schwidefsky	xgr	%r5,%r5
6577041d281SMartin Schwidefsky	xgr	%r6,%r6
6587041d281SMartin Schwidefsky	xgr	%r7,%r7
6594bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
6604bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6614bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_PGM_ILC
6624bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
663c771320eSMartin Schwidefsky	stg	%r13,__PT_FLAGS(%r11)
6644bfc86ceSHeiko Carstens	stg	%r10,__PT_ARGS(%r11)
6654bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
666d9fcf2a1SMartin Schwidefsky	jz	5f
6674bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# kernel per event ?
6684bfc86ceSHeiko Carstens	jz	.Lpgm_kprobe
6694bfc86ceSHeiko Carstens	oi	__PT_FLAGS+7(%r11),_PIF_PER_TRAP
6704bfc86ceSHeiko Carstens	mvc	__THREAD_per_address(8,%r14),__LC_PER_ADDRESS
6714bfc86ceSHeiko Carstens	mvc	__THREAD_per_cause(2,%r14),__LC_PER_CODE
6724bfc86ceSHeiko Carstens	mvc	__THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
673d9fcf2a1SMartin Schwidefsky5:	REENABLE_IRQS
6744bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6754bfc86ceSHeiko Carstens	larl	%r1,pgm_check_table
6764bfc86ceSHeiko Carstens	llgh	%r10,__PT_INT_CODE+2(%r11)
6774bfc86ceSHeiko Carstens	nill	%r10,0x007f
678ff4a742dSGerald Schaefer	sll	%r10,3
679a359bb11SMartin Schwidefsky	je	.Lpgm_return
680ff4a742dSGerald Schaefer	lg	%r9,0(%r10,%r1)		# load address of handler routine
6814bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6826dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# branch to interrupt-handler
683a359bb11SMartin Schwidefsky.Lpgm_return:
684a359bb11SMartin Schwidefsky	LOCKDEP_SYS_EXIT
685a359bb11SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
686a359bb11SMartin Schwidefsky	jno	.Lsysc_restore
68757d7f939SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
68857d7f939SMartin Schwidefsky	jo	.Lsysc_do_syscall
689a359bb11SMartin Schwidefsky	j	.Lsysc_tif
6904bfc86ceSHeiko Carstens
6914bfc86ceSHeiko Carstens#
6924bfc86ceSHeiko Carstens# PER event in supervisor state, must be kprobes
6934bfc86ceSHeiko Carstens#
6944bfc86ceSHeiko Carstens.Lpgm_kprobe:
6954bfc86ceSHeiko Carstens	REENABLE_IRQS
6964bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6974bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6984bfc86ceSHeiko Carstens	brasl	%r14,do_per_trap
699a359bb11SMartin Schwidefsky	j	.Lpgm_return
7004bfc86ceSHeiko Carstens
7014bfc86ceSHeiko Carstens#
7024bfc86ceSHeiko Carstens# single stepped system call
7034bfc86ceSHeiko Carstens#
7044bfc86ceSHeiko Carstens.Lpgm_svcper:
7054bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
706d24b98e3SMartin Schwidefsky	lghi	%r13,__TASK_thread
7074bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
7084bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
7094bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL | _PIF_PER_TRAP
7104bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per and enable irqs
711*26a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
7124bfc86ceSHeiko Carstens
7134bfc86ceSHeiko Carstens/*
7144bfc86ceSHeiko Carstens * IO interrupt handler routine
7154bfc86ceSHeiko Carstens */
7164bfc86ceSHeiko CarstensENTRY(io_int_handler)
7174bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
7184bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
719d768bd89SMartin Schwidefsky	BPOFF
7204bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
721d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
7229977e886SHendrik Brueckner	larl	%r13,cleanup_critical
7234bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_IO_OLD_PSW
7242acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
7254bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
7267041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
7277041d281SMartin Schwidefsky	xgr	%r0,%r0
7287041d281SMartin Schwidefsky	xgr	%r1,%r1
7297041d281SMartin Schwidefsky	xgr	%r2,%r2
7307041d281SMartin Schwidefsky	xgr	%r3,%r3
7317041d281SMartin Schwidefsky	xgr	%r4,%r4
7327041d281SMartin Schwidefsky	xgr	%r5,%r5
7337041d281SMartin Schwidefsky	xgr	%r6,%r6
7347041d281SMartin Schwidefsky	xgr	%r7,%r7
7357041d281SMartin Schwidefsky	xgr	%r10,%r10
7364bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
7374bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
7384bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7394bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
740db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
741db7e007fSHeiko Carstens	jo	.Lio_restore
7424bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
7434bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7444bfc86ceSHeiko Carstens.Lio_loop:
7454bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7464bfc86ceSHeiko Carstens	lghi	%r3,IO_INTERRUPT
7474bfc86ceSHeiko Carstens	tm	__PT_INT_CODE+8(%r11),0x80	# adapter interrupt ?
7484bfc86ceSHeiko Carstens	jz	.Lio_call
7494bfc86ceSHeiko Carstens	lghi	%r3,THIN_INTERRUPT
7504bfc86ceSHeiko Carstens.Lio_call:
7514bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
75283abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
7534bfc86ceSHeiko Carstens	jz	.Lio_return
7544bfc86ceSHeiko Carstens	tpi	0
7554bfc86ceSHeiko Carstens	jz	.Lio_return
7564bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7574bfc86ceSHeiko Carstens	j	.Lio_loop
7584bfc86ceSHeiko Carstens.Lio_return:
7594bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
7604bfc86ceSHeiko Carstens	TRACE_IRQS_ON
7614bfc86ceSHeiko Carstens.Lio_tif:
76283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
7634bfc86ceSHeiko Carstens	jnz	.Lio_work		# there is work to do (signals etc.)
76483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
7654bfc86ceSHeiko Carstens	jnz	.Lio_work
7664bfc86ceSHeiko Carstens.Lio_restore:
7674bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
7684bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
7694bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
770d768bd89SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
771d768bd89SMartin Schwidefsky	jno	.Lio_exit_kernel
7726b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
77307a63cbeSMartin Schwidefsky.Lio_exit_timer:
7744bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
7754bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
776d768bd89SMartin Schwidefsky.Lio_exit_kernel:
7774bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
7784bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW
7794bfc86ceSHeiko Carstens.Lio_done:
7804bfc86ceSHeiko Carstens
7814bfc86ceSHeiko Carstens#
7824bfc86ceSHeiko Carstens# There is work todo, find out in which context we have been interrupted:
7834bfc86ceSHeiko Carstens# 1) if we return to user space we can do all _TIF_WORK work
7844bfc86ceSHeiko Carstens# 2) if we return to kernel code and kvm is enabled check if we need to
7854bfc86ceSHeiko Carstens#    modify the psw to leave SIE
7864bfc86ceSHeiko Carstens# 3) if we return to kernel code and preemptive scheduling is enabled check
7874bfc86ceSHeiko Carstens#    the preemption counter and if it is zero call preempt_schedule_irq
7884bfc86ceSHeiko Carstens# Before any work can be done, a switch to the kernel stack is required.
7894bfc86ceSHeiko Carstens#
7904bfc86ceSHeiko Carstens.Lio_work:
7914bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
7924bfc86ceSHeiko Carstens	jo	.Lio_work_user		# yes -> do resched & signal
7934bfc86ceSHeiko Carstens#ifdef CONFIG_PREEMPT
7944bfc86ceSHeiko Carstens	# check for preemptive scheduling
795c360192bSMartin Schwidefsky	icm	%r0,15,__LC_PREEMPT_COUNT
7964bfc86ceSHeiko Carstens	jnz	.Lio_restore		# preemption is disabled
79783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
7984bfc86ceSHeiko Carstens	jno	.Lio_restore
7994bfc86ceSHeiko Carstens	# switch to kernel stack
8004bfc86ceSHeiko Carstens	lg	%r1,__PT_R15(%r11)
8014bfc86ceSHeiko Carstens	aghi	%r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
8024bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8034bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8044bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8054bfc86ceSHeiko Carstens	lgr	%r15,%r1
8064bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return, call
8074bfc86ceSHeiko Carstens	# TRACE_IRQS_OFF to keep things symmetrical
8084bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8094bfc86ceSHeiko Carstens	brasl	%r14,preempt_schedule_irq
8104bfc86ceSHeiko Carstens	j	.Lio_return
8114bfc86ceSHeiko Carstens#else
8124bfc86ceSHeiko Carstens	j	.Lio_restore
8134bfc86ceSHeiko Carstens#endif
8144bfc86ceSHeiko Carstens
8154bfc86ceSHeiko Carstens#
8164bfc86ceSHeiko Carstens# Need to do work before returning to userspace, switch to kernel stack
8174bfc86ceSHeiko Carstens#
8184bfc86ceSHeiko Carstens.Lio_work_user:
8194bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK
8204bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8214bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8224bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8234bfc86ceSHeiko Carstens	lgr	%r15,%r1
8244bfc86ceSHeiko Carstens
8254bfc86ceSHeiko Carstens#
8264bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
8274bfc86ceSHeiko Carstens#
8284bfc86ceSHeiko Carstens.Lio_work_tif:
82983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
8304bfc86ceSHeiko Carstens	jo	.Lio_mcck_pending
83183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8324bfc86ceSHeiko Carstens	jo	.Lio_reschedule
8332f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
8342f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
8352f09ca60SMiroslav Benes	jo	.Lio_patch_pending
8362f09ca60SMiroslav Benes#endif
83783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
8384bfc86ceSHeiko Carstens	jo	.Lio_sigpending
83983abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
8404bfc86ceSHeiko Carstens	jo	.Lio_notify_resume
841916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
842916cda1aSMartin Schwidefsky	jo	.Lio_guarded_storage
84383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
8449977e886SHendrik Brueckner	jo	.Lio_vxrs
845b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
846b5a882fcSHeiko Carstens	jnz	.Lio_asce
8474bfc86ceSHeiko Carstens	j	.Lio_return		# beware of critical section cleanup
8484bfc86ceSHeiko Carstens
8494bfc86ceSHeiko Carstens#
8504bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
8514bfc86ceSHeiko Carstens#
8524bfc86ceSHeiko Carstens.Lio_mcck_pending:
8534bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8544bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck	# TIF bit will be cleared by handler
8554bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8564bfc86ceSHeiko Carstens	j	.Lio_return
8574bfc86ceSHeiko Carstens
8584bfc86ceSHeiko Carstens#
859b5a882fcSHeiko Carstens# _CIF_ASCE_PRIMARY and/or CIF_ASCE_SECONDARY set, load user space asce
8604bfc86ceSHeiko Carstens#
861b5a882fcSHeiko Carstens.Lio_asce:
8620aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
8630aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
8640aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
8650aaba41bSMartin Schwidefsky	jz	.Lio_return
8660aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
8670aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
8680aaba41bSMartin Schwidefsky	jnz	.Lio_set_fs_fixup
869606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
8704bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
8710aaba41bSMartin Schwidefsky	j	.Lio_return
8720aaba41bSMartin Schwidefsky.Lio_set_fs_fixup:
8730aaba41bSMartin Schwidefsky#endif
874b5a882fcSHeiko Carstens	larl	%r14,.Lio_return
875b5a882fcSHeiko Carstens	jg	set_fs_fixup
8764bfc86ceSHeiko Carstens
8774bfc86ceSHeiko Carstens#
8789977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
8799977e886SHendrik Brueckner#
8809977e886SHendrik Brueckner.Lio_vxrs:
8819977e886SHendrik Brueckner	larl	%r14,.Lio_return
8829977e886SHendrik Brueckner	jg	load_fpu_regs
8839977e886SHendrik Brueckner
8849977e886SHendrik Brueckner#
885916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
886916cda1aSMartin Schwidefsky#
887916cda1aSMartin Schwidefsky.Lio_guarded_storage:
888916cda1aSMartin Schwidefsky	# TRACE_IRQS_ON already done at .Lio_return
889916cda1aSMartin Schwidefsky	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
890916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
891916cda1aSMartin Schwidefsky	brasl	%r14,gs_load_bc_cb
892916cda1aSMartin Schwidefsky	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
893916cda1aSMartin Schwidefsky	TRACE_IRQS_OFF
894916cda1aSMartin Schwidefsky	j	.Lio_return
895916cda1aSMartin Schwidefsky
896916cda1aSMartin Schwidefsky#
8974bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
8984bfc86ceSHeiko Carstens#
8994bfc86ceSHeiko Carstens.Lio_reschedule:
9004bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9014bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9024bfc86ceSHeiko Carstens	brasl	%r14,schedule		# call scheduler
9034bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9044bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9054bfc86ceSHeiko Carstens	j	.Lio_return
9064bfc86ceSHeiko Carstens
9074bfc86ceSHeiko Carstens#
9082f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
9092f09ca60SMiroslav Benes#
9102f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
9112f09ca60SMiroslav Benes.Lio_patch_pending:
9122f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
9132f09ca60SMiroslav Benes	larl	%r14,.Lio_return
9142f09ca60SMiroslav Benes	jg	klp_update_patch_state
9152f09ca60SMiroslav Benes#endif
9162f09ca60SMiroslav Benes
9172f09ca60SMiroslav Benes#
9184bfc86ceSHeiko Carstens# _TIF_SIGPENDING or is set, call do_signal
9194bfc86ceSHeiko Carstens#
9204bfc86ceSHeiko Carstens.Lio_sigpending:
9214bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9224bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9234bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9244bfc86ceSHeiko Carstens	brasl	%r14,do_signal
9254bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9264bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9274bfc86ceSHeiko Carstens	j	.Lio_return
9284bfc86ceSHeiko Carstens
9294bfc86ceSHeiko Carstens#
9304bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
9314bfc86ceSHeiko Carstens#
9324bfc86ceSHeiko Carstens.Lio_notify_resume:
9334bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9344bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9354bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9364bfc86ceSHeiko Carstens	brasl	%r14,do_notify_resume
9374bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9384bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9394bfc86ceSHeiko Carstens	j	.Lio_return
940*26a374aeSMartin SchwidefskyENDPROC(io_int_handler)
9414bfc86ceSHeiko Carstens
9424bfc86ceSHeiko Carstens/*
9434bfc86ceSHeiko Carstens * External interrupt handler routine
9444bfc86ceSHeiko Carstens */
9454bfc86ceSHeiko CarstensENTRY(ext_int_handler)
9464bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
9474bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
948d768bd89SMartin Schwidefsky	BPOFF
9494bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
950d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
9519977e886SHendrik Brueckner	larl	%r13,cleanup_critical
9524bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_EXT_OLD_PSW
9532acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
9544bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
9557041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
9567041d281SMartin Schwidefsky	xgr	%r0,%r0
9577041d281SMartin Schwidefsky	xgr	%r1,%r1
9587041d281SMartin Schwidefsky	xgr	%r2,%r2
9597041d281SMartin Schwidefsky	xgr	%r3,%r3
9607041d281SMartin Schwidefsky	xgr	%r4,%r4
9617041d281SMartin Schwidefsky	xgr	%r5,%r5
9627041d281SMartin Schwidefsky	xgr	%r6,%r6
9637041d281SMartin Schwidefsky	xgr	%r7,%r7
9647041d281SMartin Schwidefsky	xgr	%r10,%r10
9654bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
9664bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
9674bfc86ceSHeiko Carstens	lghi	%r1,__LC_EXT_PARAMS2
9684bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
9694bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
9704bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),0(%r1)
9714bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
972db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
973db7e007fSHeiko Carstens	jo	.Lio_restore
9744bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9754bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
9764bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9774bfc86ceSHeiko Carstens	lghi	%r3,EXT_INTERRUPT
9784bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
9794bfc86ceSHeiko Carstens	j	.Lio_return
980*26a374aeSMartin SchwidefskyENDPROC(ext_int_handler)
9814bfc86ceSHeiko Carstens
9824bfc86ceSHeiko Carstens/*
9834bfc86ceSHeiko Carstens * Load idle PSW. The second "half" of this function is in .Lcleanup_idle.
9844bfc86ceSHeiko Carstens */
9854bfc86ceSHeiko CarstensENTRY(psw_idle)
9864bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
9874bfc86ceSHeiko Carstens	larl	%r1,.Lpsw_idle_lpsw+4
9884bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
98972d38b19SMartin Schwidefsky#ifdef CONFIG_SMP
99072d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
99172d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
99272d38b19SMartin Schwidefsky	ltgr	%r1,%r1
99372d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
99472d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
99572d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
99672d38b19SMartin Schwidefsky#endif
997419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
998d768bd89SMartin Schwidefsky	BPON
9994bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
10004bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
10014bfc86ceSHeiko Carstens.Lpsw_idle_lpsw:
10024bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
10036dd85fbbSMartin Schwidefsky	BR_EX	%r14
10044bfc86ceSHeiko Carstens.Lpsw_idle_end:
1005*26a374aeSMartin SchwidefskyENDPROC(psw_idle)
10064bfc86ceSHeiko Carstens
1007b5510d9bSHendrik Brueckner/*
1008b5510d9bSHendrik Brueckner * Store floating-point controls and floating-point or vector register
1009b5510d9bSHendrik Brueckner * depending whether the vector facility is available.	A critical section
1010b5510d9bSHendrik Brueckner * cleanup assures that the registers are stored even if interrupted for
1011b5510d9bSHendrik Brueckner * some other work.  The CIF_FPU flag is set to trigger a lazy restore
1012b5510d9bSHendrik Brueckner * of the register contents at return from io or a system call.
10139977e886SHendrik Brueckner */
10149977e886SHendrik BruecknerENTRY(save_fpu_regs)
1015d0164ee2SHendrik Brueckner	lg	%r2,__LC_CURRENT
1016d0164ee2SHendrik Brueckner	aghi	%r2,__TASK_thread
101783abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1018f19fbd5eSMartin Schwidefsky	jo	.Lsave_fpu_regs_exit
1019d0164ee2SHendrik Brueckner	stfpc	__THREAD_FPU_fpc(%r2)
1020d0164ee2SHendrik Brueckner	lg	%r3,__THREAD_FPU_regs(%r2)
102183abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
10229977e886SHendrik Brueckner	jz	.Lsave_fpu_regs_fp	  # no -> store FP regs
10239977e886SHendrik Brueckner	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
10249977e886SHendrik Brueckner	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
10259977e886SHendrik Brueckner	j	.Lsave_fpu_regs_done	  # -> set CIF_FPU flag
10269977e886SHendrik Brueckner.Lsave_fpu_regs_fp:
10279977e886SHendrik Brueckner	std	0,0(%r3)
10289977e886SHendrik Brueckner	std	1,8(%r3)
10299977e886SHendrik Brueckner	std	2,16(%r3)
10309977e886SHendrik Brueckner	std	3,24(%r3)
10319977e886SHendrik Brueckner	std	4,32(%r3)
10329977e886SHendrik Brueckner	std	5,40(%r3)
10339977e886SHendrik Brueckner	std	6,48(%r3)
10349977e886SHendrik Brueckner	std	7,56(%r3)
10359977e886SHendrik Brueckner	std	8,64(%r3)
10369977e886SHendrik Brueckner	std	9,72(%r3)
10379977e886SHendrik Brueckner	std	10,80(%r3)
10389977e886SHendrik Brueckner	std	11,88(%r3)
10399977e886SHendrik Brueckner	std	12,96(%r3)
10409977e886SHendrik Brueckner	std	13,104(%r3)
10419977e886SHendrik Brueckner	std	14,112(%r3)
10429977e886SHendrik Brueckner	std	15,120(%r3)
10439977e886SHendrik Brueckner.Lsave_fpu_regs_done:
10449977e886SHendrik Brueckner	oi	__LC_CPU_FLAGS+7,_CIF_FPU
1045f19fbd5eSMartin Schwidefsky.Lsave_fpu_regs_exit:
10466dd85fbbSMartin Schwidefsky	BR_EX	%r14
10479977e886SHendrik Brueckner.Lsave_fpu_regs_end:
1048*26a374aeSMartin SchwidefskyENDPROC(save_fpu_regs)
1049711f5df7SAl ViroEXPORT_SYMBOL(save_fpu_regs)
10509977e886SHendrik Brueckner
1051b5510d9bSHendrik Brueckner/*
1052b5510d9bSHendrik Brueckner * Load floating-point controls and floating-point or vector registers.
1053b5510d9bSHendrik Brueckner * A critical section cleanup assures that the register contents are
1054b5510d9bSHendrik Brueckner * loaded even if interrupted for some other work.
10559977e886SHendrik Brueckner *
10569977e886SHendrik Brueckner * There are special calling conventions to fit into sysc and io return work:
10579977e886SHendrik Brueckner *	%r15:	<kernel stack>
10589977e886SHendrik Brueckner * The function requires:
1059b5510d9bSHendrik Brueckner *	%r4
10609977e886SHendrik Brueckner */
10619977e886SHendrik Bruecknerload_fpu_regs:
1062d0164ee2SHendrik Brueckner	lg	%r4,__LC_CURRENT
1063d0164ee2SHendrik Brueckner	aghi	%r4,__TASK_thread
106483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1065f19fbd5eSMartin Schwidefsky	jno	.Lload_fpu_regs_exit
1066d0164ee2SHendrik Brueckner	lfpc	__THREAD_FPU_fpc(%r4)
106783abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
1068d0164ee2SHendrik Brueckner	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
1069b5510d9bSHendrik Brueckner	jz	.Lload_fpu_regs_fp		# -> no VX, load FP regs
10709977e886SHendrik Brueckner	VLM	%v0,%v15,0,%r4
10719977e886SHendrik Brueckner	VLM	%v16,%v31,256,%r4
10729977e886SHendrik Brueckner	j	.Lload_fpu_regs_done
10739977e886SHendrik Brueckner.Lload_fpu_regs_fp:
10749977e886SHendrik Brueckner	ld	0,0(%r4)
10759977e886SHendrik Brueckner	ld	1,8(%r4)
10769977e886SHendrik Brueckner	ld	2,16(%r4)
10779977e886SHendrik Brueckner	ld	3,24(%r4)
10789977e886SHendrik Brueckner	ld	4,32(%r4)
10799977e886SHendrik Brueckner	ld	5,40(%r4)
10809977e886SHendrik Brueckner	ld	6,48(%r4)
10819977e886SHendrik Brueckner	ld	7,56(%r4)
10829977e886SHendrik Brueckner	ld	8,64(%r4)
10839977e886SHendrik Brueckner	ld	9,72(%r4)
10849977e886SHendrik Brueckner	ld	10,80(%r4)
10859977e886SHendrik Brueckner	ld	11,88(%r4)
10869977e886SHendrik Brueckner	ld	12,96(%r4)
10879977e886SHendrik Brueckner	ld	13,104(%r4)
10889977e886SHendrik Brueckner	ld	14,112(%r4)
10899977e886SHendrik Brueckner	ld	15,120(%r4)
10909977e886SHendrik Brueckner.Lload_fpu_regs_done:
10919977e886SHendrik Brueckner	ni	__LC_CPU_FLAGS+7,255-_CIF_FPU
1092f19fbd5eSMartin Schwidefsky.Lload_fpu_regs_exit:
10936dd85fbbSMartin Schwidefsky	BR_EX	%r14
10949977e886SHendrik Brueckner.Lload_fpu_regs_end:
1095*26a374aeSMartin SchwidefskyENDPROC(load_fpu_regs)
10969977e886SHendrik Brueckner
10974bfc86ceSHeiko Carstens.L__critical_end:
10984bfc86ceSHeiko Carstens
10994bfc86ceSHeiko Carstens/*
11004bfc86ceSHeiko Carstens * Machine check handler routines
11014bfc86ceSHeiko Carstens */
11024bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
11034bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
1104d768bd89SMartin Schwidefsky	BPOFF
11053037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
11063037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
11073037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
11083037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
11093037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
1110d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
11119977e886SHendrik Brueckner	larl	%r13,cleanup_critical
11124bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
111383abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
11144bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
11153037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
11163037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
11173037a52fSMartin Schwidefsky	la	%r14,4095
11183037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
11193037a52fSMartin Schwidefsky	ptlb
11202a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
11213037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
11223037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
11233037a52fSMartin Schwidefsky	jno	0f
11243037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
11253037a52fSMartin Schwidefsky	jno	0f
11263037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
11273037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
11283037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
11293037a52fSMartin Schwidefsky	jo	0f
11303037a52fSMartin Schwidefsky	sr	%r14,%r14
11313037a52fSMartin Schwidefsky0:	sfpc	%r14
11323037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
11333037a52fSMartin Schwidefsky	jo	0f
11343037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
11353037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
11363037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
11373037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
11383037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
11393037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
11403037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
11413037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
11423037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
11433037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
11443037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
11453037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
11463037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
11473037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
11483037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
11493037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
11503037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
11513037a52fSMartin Schwidefsky	j	1f
11523037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
11533037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
11543037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
11554bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
115683abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
11574bfc86ceSHeiko Carstens	jo	3f
11584bfc86ceSHeiko Carstens	la	%r14,__LC_SYNC_ENTER_TIMER
11594bfc86ceSHeiko Carstens	clc	0(8,%r14),__LC_ASYNC_ENTER_TIMER
11604bfc86ceSHeiko Carstens	jl	0f
11614bfc86ceSHeiko Carstens	la	%r14,__LC_ASYNC_ENTER_TIMER
11624bfc86ceSHeiko Carstens0:	clc	0(8,%r14),__LC_EXIT_TIMER
11634bfc86ceSHeiko Carstens	jl	1f
11644bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
11654bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
11664bfc86ceSHeiko Carstens	jl	2f
11674bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
11684bfc86ceSHeiko Carstens2:	spt	0(%r14)
11694bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
11703037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
11713037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11723037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
11733037a52fSMartin Schwidefsky	jnz	4f
11743037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
11753037a52fSMartin Schwidefsky	jno	.Lmcck_panic
1176ce3dc447SMartin Schwidefsky4:	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
1177ce3dc447SMartin Schwidefsky	SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
11784bfc86ceSHeiko Carstens.Lmcck_skip:
11794bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
11804bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
11817041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
11827041d281SMartin Schwidefsky	xgr	%r0,%r0
11837041d281SMartin Schwidefsky	xgr	%r1,%r1
11847041d281SMartin Schwidefsky	xgr	%r2,%r2
11857041d281SMartin Schwidefsky	xgr	%r3,%r3
11867041d281SMartin Schwidefsky	xgr	%r4,%r4
11877041d281SMartin Schwidefsky	xgr	%r5,%r5
11887041d281SMartin Schwidefsky	xgr	%r6,%r6
11897041d281SMartin Schwidefsky	xgr	%r7,%r7
11907041d281SMartin Schwidefsky	xgr	%r10,%r10
11914bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
11924bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
11934bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
11944bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
11954bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
11964bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
11974bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
11984bfc86ceSHeiko Carstens	jno	.Lmcck_return
11994bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
12004bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
12014bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
12024bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
12034bfc86ceSHeiko Carstens	lgr	%r15,%r1
120483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
12054bfc86ceSHeiko Carstens	jno	.Lmcck_return
12064bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
12074bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
12084bfc86ceSHeiko Carstens	TRACE_IRQS_ON
12094bfc86ceSHeiko Carstens.Lmcck_return:
12104bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
12114bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
12124bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
12134bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
12144bfc86ceSHeiko Carstens	jno	0f
12156b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
12164bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
12174bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
12184bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
12194bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_MCCK_PSW
12204bfc86ceSHeiko Carstens
12214bfc86ceSHeiko Carstens.Lmcck_panic:
1222ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK
1223ce4dda3fSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12244bfc86ceSHeiko Carstens	j	.Lmcck_skip
1225*26a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
12264bfc86ceSHeiko Carstens
12274bfc86ceSHeiko Carstens#
12284bfc86ceSHeiko Carstens# PSW restart interrupt handler
12294bfc86ceSHeiko Carstens#
12304bfc86ceSHeiko CarstensENTRY(restart_int_handler)
1231e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
1232e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
12334bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
1234ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
1235ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
1236ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
1237ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
12384bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
12394bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
12404bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
12414bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
12424bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
12434bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
12444bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
12454bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
12464bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
12474bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
12484bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
12494bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
12504bfc86ceSHeiko Carstens	brc	2,2b
12514bfc86ceSHeiko Carstens3:	j	3b
1252*26a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
12534bfc86ceSHeiko Carstens
12544bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
12554bfc86ceSHeiko Carstens
1256ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
12574bfc86ceSHeiko Carstens/*
12584bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
12594bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
12604bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
12614bfc86ceSHeiko Carstens */
1262*26a374aeSMartin SchwidefskyENTRY(stack_overflow)
1263ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
12644bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12654bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
12664bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12674bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12684bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
12694bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12704bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12714bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
1272*26a374aeSMartin SchwidefskyENDPROC(stack_overflow)
12734bfc86ceSHeiko Carstens#endif
12744bfc86ceSHeiko Carstens
1275*26a374aeSMartin SchwidefskyENTRY(cleanup_critical)
1276d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1277d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie)	# .Lsie_gmap
1278d0fc4107SMartin Schwidefsky	jl	0f
1279d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie+8)# .Lsie_done
1280d0fc4107SMartin Schwidefsky	jl	.Lcleanup_sie
1281d0fc4107SMartin Schwidefsky#endif
12824bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table)	# system_call
12834bfc86ceSHeiko Carstens	jl	0f
12844bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+8)	# .Lsysc_do_svc
12854bfc86ceSHeiko Carstens	jl	.Lcleanup_system_call
12864bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+16)	# .Lsysc_tif
12874bfc86ceSHeiko Carstens	jl	0f
12884bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+24)	# .Lsysc_restore
12894bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_tif
12904bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+32)	# .Lsysc_done
12914bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_restore
12924bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+40)	# .Lio_tif
12934bfc86ceSHeiko Carstens	jl	0f
12944bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+48)	# .Lio_restore
12954bfc86ceSHeiko Carstens	jl	.Lcleanup_io_tif
12964bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+56)	# .Lio_done
12974bfc86ceSHeiko Carstens	jl	.Lcleanup_io_restore
12984bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+64)	# psw_idle
12994bfc86ceSHeiko Carstens	jl	0f
13004bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+72)	# .Lpsw_idle_end
13014bfc86ceSHeiko Carstens	jl	.Lcleanup_idle
13029977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+80)	# save_fpu_regs
13039977e886SHendrik Brueckner	jl	0f
13049977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+88)	# .Lsave_fpu_regs_end
13059977e886SHendrik Brueckner	jl	.Lcleanup_save_fpu_regs
13069977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+96)	# load_fpu_regs
13079977e886SHendrik Brueckner	jl	0f
13089977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+104)	# .Lload_fpu_regs_end
13099977e886SHendrik Brueckner	jl	.Lcleanup_load_fpu_regs
1310891f6a72SChristian Borntraeger0:	BR_EX	%r14,%r11
1311*26a374aeSMartin SchwidefskyENDPROC(cleanup_critical)
13124bfc86ceSHeiko Carstens
1313d0fc4107SMartin Schwidefsky	.align	8
1314d0fc4107SMartin Schwidefsky.Lcleanup_table:
1315d0fc4107SMartin Schwidefsky	.quad	system_call
1316d0fc4107SMartin Schwidefsky	.quad	.Lsysc_do_svc
1317d0fc4107SMartin Schwidefsky	.quad	.Lsysc_tif
1318d0fc4107SMartin Schwidefsky	.quad	.Lsysc_restore
1319d0fc4107SMartin Schwidefsky	.quad	.Lsysc_done
1320d0fc4107SMartin Schwidefsky	.quad	.Lio_tif
1321d0fc4107SMartin Schwidefsky	.quad	.Lio_restore
1322d0fc4107SMartin Schwidefsky	.quad	.Lio_done
1323d0fc4107SMartin Schwidefsky	.quad	psw_idle
1324d0fc4107SMartin Schwidefsky	.quad	.Lpsw_idle_end
1325d0fc4107SMartin Schwidefsky	.quad	save_fpu_regs
1326d0fc4107SMartin Schwidefsky	.quad	.Lsave_fpu_regs_end
1327d0fc4107SMartin Schwidefsky	.quad	load_fpu_regs
1328d0fc4107SMartin Schwidefsky	.quad	.Lload_fpu_regs_end
1329d0fc4107SMartin Schwidefsky
1330d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1331d0fc4107SMartin Schwidefsky.Lcleanup_table_sie:
1332d0fc4107SMartin Schwidefsky	.quad	.Lsie_gmap
1333d0fc4107SMartin Schwidefsky	.quad	.Lsie_done
1334d0fc4107SMartin Schwidefsky
1335d0fc4107SMartin Schwidefsky.Lcleanup_sie:
1336c929500dSQingFeng Hao	cghi    %r11,__LC_SAVE_AREA_ASYNC 	#Is this in normal interrupt?
1337c929500dSQingFeng Hao	je      1f
1338c929500dSQingFeng Hao	slg     %r9,BASED(.Lsie_crit_mcck_start)
1339c929500dSQingFeng Hao	clg     %r9,BASED(.Lsie_crit_mcck_length)
1340c929500dSQingFeng Hao	jh      1f
1341c929500dSQingFeng Hao	oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
134292fa7a13SMartin Schwidefsky1:	BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
134392fa7a13SMartin Schwidefsky	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
1344e22cf8caSChristian Borntraeger	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
1345d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
1346d0fc4107SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
1347891f6a72SChristian Borntraeger	BR_EX	%r14,%r11
1348d0fc4107SMartin Schwidefsky#endif
13494bfc86ceSHeiko Carstens
13504bfc86ceSHeiko Carstens.Lcleanup_system_call:
13514bfc86ceSHeiko Carstens	# check if stpt has been executed
13524bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn)
13534bfc86ceSHeiko Carstens	jh	0f
13544bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
13554bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
13564bfc86ceSHeiko Carstens	je	0f
13574bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
13584bfc86ceSHeiko Carstens0:	# check if stmg has been executed
13594bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+8)
13604bfc86ceSHeiko Carstens	jh	0f
13614bfc86ceSHeiko Carstens	mvc	__LC_SAVE_AREA_SYNC(64),0(%r11)
13624bfc86ceSHeiko Carstens0:	# check if base register setup + TIF bit load has been done
13634bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+16)
13644bfc86ceSHeiko Carstens	jhe	0f
136534525e1fSMartin Schwidefsky	# set up saved register r12 task struct pointer
136634525e1fSMartin Schwidefsky	stg	%r12,32(%r11)
136734525e1fSMartin Schwidefsky	# set up saved register r13 __TASK_thread offset
136834525e1fSMartin Schwidefsky	mvc	40(8,%r11),BASED(.Lcleanup_system_call_const)
13694bfc86ceSHeiko Carstens0:	# check if the user time update has been done
13704bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+24)
13714bfc86ceSHeiko Carstens	jh	0f
13724bfc86ceSHeiko Carstens	lg	%r15,__LC_EXIT_TIMER
13734bfc86ceSHeiko Carstens	slg	%r15,__LC_SYNC_ENTER_TIMER
13744bfc86ceSHeiko Carstens	alg	%r15,__LC_USER_TIMER
13754bfc86ceSHeiko Carstens	stg	%r15,__LC_USER_TIMER
13764bfc86ceSHeiko Carstens0:	# check if the system time update has been done
13774bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+32)
13784bfc86ceSHeiko Carstens	jh	0f
13794bfc86ceSHeiko Carstens	lg	%r15,__LC_LAST_UPDATE_TIMER
13804bfc86ceSHeiko Carstens	slg	%r15,__LC_EXIT_TIMER
13814bfc86ceSHeiko Carstens	alg	%r15,__LC_SYSTEM_TIMER
13824bfc86ceSHeiko Carstens	stg	%r15,__LC_SYSTEM_TIMER
13834bfc86ceSHeiko Carstens0:	# update accounting time stamp
13844bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
1385d5feec04SMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
138634525e1fSMartin Schwidefsky	# set up saved register r11
13874bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
13884bfc86ceSHeiko Carstens	la	%r9,STACK_FRAME_OVERHEAD(%r15)
13894bfc86ceSHeiko Carstens	stg	%r9,24(%r11)		# r11 pt_regs pointer
13904bfc86ceSHeiko Carstens	# fill pt_regs
13914bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r9),__LC_SAVE_AREA_SYNC
13924bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r9)
13934bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r9),__LC_SVC_OLD_PSW
13944bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r9),__LC_SVC_ILC
13954bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r9),__PT_FLAGS(%r9)
13964bfc86ceSHeiko Carstens	mvi	__PT_FLAGS+7(%r9),_PIF_SYSCALL
13974bfc86ceSHeiko Carstens	# setup saved register r15
13984bfc86ceSHeiko Carstens	stg	%r15,56(%r11)		# r15 stack pointer
13994bfc86ceSHeiko Carstens	# set new psw address and exit
14004bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_do_svc
14016dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14024bfc86ceSHeiko Carstens.Lcleanup_system_call_insn:
14034bfc86ceSHeiko Carstens	.quad	system_call
14044bfc86ceSHeiko Carstens	.quad	.Lsysc_stmg
14054bfc86ceSHeiko Carstens	.quad	.Lsysc_per
1406a359bb11SMartin Schwidefsky	.quad	.Lsysc_vtime+36
14074bfc86ceSHeiko Carstens	.quad	.Lsysc_vtime+42
140834525e1fSMartin Schwidefsky.Lcleanup_system_call_const:
140934525e1fSMartin Schwidefsky	.quad	__TASK_thread
14104bfc86ceSHeiko Carstens
14114bfc86ceSHeiko Carstens.Lcleanup_sysc_tif:
14124bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_tif
14136dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14144bfc86ceSHeiko Carstens
14154bfc86ceSHeiko Carstens.Lcleanup_sysc_restore:
141607a63cbeSMartin Schwidefsky	# check if stpt has been executed
14174bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_sysc_restore_insn)
141807a63cbeSMartin Schwidefsky	jh	0f
141907a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
142007a63cbeSMartin Schwidefsky	cghi	%r11,__LC_SAVE_AREA_ASYNC
14214bfc86ceSHeiko Carstens	je	0f
142207a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
142307a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_sysc_restore_insn+8)
142407a63cbeSMartin Schwidefsky	je	1f
14254bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved pointer to pt_regs
14264bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14274bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14284bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
142907a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
14306dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14314bfc86ceSHeiko Carstens.Lcleanup_sysc_restore_insn:
143207a63cbeSMartin Schwidefsky	.quad	.Lsysc_exit_timer
14334bfc86ceSHeiko Carstens	.quad	.Lsysc_done - 4
14344bfc86ceSHeiko Carstens
14354bfc86ceSHeiko Carstens.Lcleanup_io_tif:
14364bfc86ceSHeiko Carstens	larl	%r9,.Lio_tif
14376dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14384bfc86ceSHeiko Carstens
14394bfc86ceSHeiko Carstens.Lcleanup_io_restore:
144007a63cbeSMartin Schwidefsky	# check if stpt has been executed
14414bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_io_restore_insn)
144207a63cbeSMartin Schwidefsky	jh	0f
144307a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
144407a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_io_restore_insn+8)
144507a63cbeSMartin Schwidefsky	je	1f
14464bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved r11 pointer to pt_regs
14474bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14484bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14494bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
145007a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
14516dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14524bfc86ceSHeiko Carstens.Lcleanup_io_restore_insn:
145307a63cbeSMartin Schwidefsky	.quad	.Lio_exit_timer
14544bfc86ceSHeiko Carstens	.quad	.Lio_done - 4
14554bfc86ceSHeiko Carstens
14564bfc86ceSHeiko Carstens.Lcleanup_idle:
1457419123f9SMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
14584bfc86ceSHeiko Carstens	# copy interrupt clock & cpu timer
14594bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
14604bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
14614bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
14624bfc86ceSHeiko Carstens	je	0f
14634bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
14644bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
14654bfc86ceSHeiko Carstens0:	# check if stck & stpt have been executed
14664bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_idle_insn)
14674bfc86ceSHeiko Carstens	jhe	1f
14684bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
14694bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2)
147072d38b19SMartin Schwidefsky1:	# calculate idle cycles
147172d38b19SMartin Schwidefsky#ifdef CONFIG_SMP
147272d38b19SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_idle_insn)
147372d38b19SMartin Schwidefsky	jl	3f
147472d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
147572d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
147672d38b19SMartin Schwidefsky	ltgr	%r1,%r1
147772d38b19SMartin Schwidefsky	jz	3f
147872d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+80(%r15)
147972d38b19SMartin Schwidefsky	larl	%r3,mt_cycles
148072d38b19SMartin Schwidefsky	ag	%r3,__LC_PERCPU_OFFSET
148172d38b19SMartin Schwidefsky	la	%r4,__SF_EMPTY+16(%r15)
148272d38b19SMartin Schwidefsky2:	lg	%r0,0(%r3)
148372d38b19SMartin Schwidefsky	slg	%r0,0(%r4)
148472d38b19SMartin Schwidefsky	alg	%r0,64(%r4)
148572d38b19SMartin Schwidefsky	stg	%r0,0(%r3)
148672d38b19SMartin Schwidefsky	la	%r3,8(%r3)
148772d38b19SMartin Schwidefsky	la	%r4,8(%r4)
148872d38b19SMartin Schwidefsky	brct	%r1,2b
148972d38b19SMartin Schwidefsky#endif
149072d38b19SMartin Schwidefsky3:	# account system time going idle
14914bfc86ceSHeiko Carstens	lg	%r9,__LC_STEAL_TIMER
14924bfc86ceSHeiko Carstens	alg	%r9,__CLOCK_IDLE_ENTER(%r2)
14934bfc86ceSHeiko Carstens	slg	%r9,__LC_LAST_UPDATE_CLOCK
14944bfc86ceSHeiko Carstens	stg	%r9,__LC_STEAL_TIMER
14954bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2)
14964bfc86ceSHeiko Carstens	lg	%r9,__LC_SYSTEM_TIMER
14974bfc86ceSHeiko Carstens	alg	%r9,__LC_LAST_UPDATE_TIMER
14984bfc86ceSHeiko Carstens	slg	%r9,__TIMER_IDLE_ENTER(%r2)
14994bfc86ceSHeiko Carstens	stg	%r9,__LC_SYSTEM_TIMER
15004bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
15014bfc86ceSHeiko Carstens	# prepare return psw
15024bfc86ceSHeiko Carstens	nihh	%r8,0xfcfd		# clear irq & wait state bits
15034bfc86ceSHeiko Carstens	lg	%r9,48(%r11)		# return from psw_idle
15046dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
15054bfc86ceSHeiko Carstens.Lcleanup_idle_insn:
15064bfc86ceSHeiko Carstens	.quad	.Lpsw_idle_lpsw
15074bfc86ceSHeiko Carstens
15089977e886SHendrik Brueckner.Lcleanup_save_fpu_regs:
1509e370e476SMartin Schwidefsky	larl	%r9,save_fpu_regs
15106dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
15119977e886SHendrik Brueckner
15129977e886SHendrik Brueckner.Lcleanup_load_fpu_regs:
1513e370e476SMartin Schwidefsky	larl	%r9,load_fpu_regs
15146dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
15159977e886SHendrik Brueckner
15164bfc86ceSHeiko Carstens/*
15174bfc86ceSHeiko Carstens * Integer constants
15184bfc86ceSHeiko Carstens */
15194bfc86ceSHeiko Carstens	.align	8
15204bfc86ceSHeiko Carstens.Lcritical_start:
15214bfc86ceSHeiko Carstens	.quad	.L__critical_start
15224bfc86ceSHeiko Carstens.Lcritical_length:
15234bfc86ceSHeiko Carstens	.quad	.L__critical_end - .L__critical_start
15244bfc86ceSHeiko Carstens#if IS_ENABLED(CONFIG_KVM)
1525d0fc4107SMartin Schwidefsky.Lsie_critical_start:
15264bfc86ceSHeiko Carstens	.quad	.Lsie_gmap
15274bfc86ceSHeiko Carstens.Lsie_critical_length:
15284bfc86ceSHeiko Carstens	.quad	.Lsie_done - .Lsie_gmap
1529c929500dSQingFeng Hao.Lsie_crit_mcck_start:
1530c929500dSQingFeng Hao	.quad   .Lsie_entry
1531c929500dSQingFeng Hao.Lsie_crit_mcck_length:
1532c929500dSQingFeng Hao	.quad   .Lsie_skip - .Lsie_entry
15334bfc86ceSHeiko Carstens#endif
15344bfc86ceSHeiko Carstens	.section .rodata, "a"
1535ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
15364bfc86ceSHeiko Carstens	.globl	sys_call_table
15374bfc86ceSHeiko Carstenssys_call_table:
15384381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15394bfc86ceSHeiko Carstens#undef SYSCALL
15404bfc86ceSHeiko Carstens
15414bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
15424bfc86ceSHeiko Carstens
1543ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
15444bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
15454bfc86ceSHeiko Carstenssys_call_table_emu:
15464381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15474bfc86ceSHeiko Carstens#undef SYSCALL
15484bfc86ceSHeiko Carstens#endif
1549