xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 0b38b5e1d0e2f361e418e05c179db05bb688bbd6)
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 ?
118*0b38b5e1SSven Schnelle	jnz	2f
1194bfc86ceSHeiko Carstens	lgr	%r14,%r9
120*0b38b5e1SSven Schnelle	cghi	%r14,__LC_RETURN_LPSWE
121*0b38b5e1SSven Schnelle	je	0f
1224bfc86ceSHeiko Carstens	slg	%r14,BASED(.Lcritical_start)
1234bfc86ceSHeiko Carstens	clg	%r14,BASED(.Lcritical_length)
124*0b38b5e1SSven Schnelle	jhe	1f
125*0b38b5e1SSven Schnelle0:
1264bfc86ceSHeiko Carstens	lghi	%r11,\savearea		# inside critical section, do cleanup
1274bfc86ceSHeiko Carstens	brasl	%r14,cleanup_critical
1284bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# retest problem state after cleanup
129*0b38b5e1SSven Schnelle	jnz	2f
130*0b38b5e1SSven Schnelle1:	lg	%r14,__LC_ASYNC_STACK	# are we already on the target stack?
1314bfc86ceSHeiko Carstens	slgr	%r14,%r15
1322acb94f4SMartin Schwidefsky	srag	%r14,%r14,STACK_SHIFT
133*0b38b5e1SSven Schnelle	jnz	3f
134ce3dc447SMartin Schwidefsky	CHECK_STACK \savearea
1354bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
136*0b38b5e1SSven Schnelle	j	4f
137*0b38b5e1SSven Schnelle2:	UPDATE_VTIME %r14,%r15,\timer
1386b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
139*0b38b5e1SSven Schnelle3:	lg	%r15,__LC_ASYNC_STACK	# load async stack
140*0b38b5e1SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
1414bfc86ceSHeiko Carstens	.endm
1424bfc86ceSHeiko Carstens
143a359bb11SMartin Schwidefsky	.macro UPDATE_VTIME w1,w2,enter_timer
144a359bb11SMartin Schwidefsky	lg	\w1,__LC_EXIT_TIMER
145a359bb11SMartin Schwidefsky	lg	\w2,__LC_LAST_UPDATE_TIMER
146a359bb11SMartin Schwidefsky	slg	\w1,\enter_timer
147a359bb11SMartin Schwidefsky	slg	\w2,__LC_EXIT_TIMER
148a359bb11SMartin Schwidefsky	alg	\w1,__LC_USER_TIMER
149a359bb11SMartin Schwidefsky	alg	\w2,__LC_SYSTEM_TIMER
150a359bb11SMartin Schwidefsky	stg	\w1,__LC_USER_TIMER
151a359bb11SMartin Schwidefsky	stg	\w2,__LC_SYSTEM_TIMER
1524bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),\enter_timer
1534bfc86ceSHeiko Carstens	.endm
1544bfc86ceSHeiko Carstens
1554bfc86ceSHeiko Carstens	.macro REENABLE_IRQS
1564bfc86ceSHeiko Carstens	stg	%r8,__LC_RETURN_PSW
1574bfc86ceSHeiko Carstens	ni	__LC_RETURN_PSW,0xbf
1584bfc86ceSHeiko Carstens	ssm	__LC_RETURN_PSW
1594bfc86ceSHeiko Carstens	.endm
1604bfc86ceSHeiko Carstens
1614bfc86ceSHeiko Carstens	.macro STCK savearea
1624bfc86ceSHeiko Carstens#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
1634bfc86ceSHeiko Carstens	.insn	s,0xb27c0000,\savearea		# store clock fast
1644bfc86ceSHeiko Carstens#else
1654bfc86ceSHeiko Carstens	.insn	s,0xb2050000,\savearea		# store clock
1664bfc86ceSHeiko Carstens#endif
1674bfc86ceSHeiko Carstens	.endm
1684bfc86ceSHeiko Carstens
16983abeffbSHendrik Brueckner	/*
17083abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
17183abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
17283abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
17383abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
17483abeffbSHendrik Brueckner	 * instruction.
17583abeffbSHendrik Brueckner	 */
17683abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
17783abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
17883abeffbSHendrik Brueckner			.if (\mask & 0xff)
17983abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
18083abeffbSHendrik Brueckner			.endif
18183abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
18283abeffbSHendrik Brueckner			.exitm
18383abeffbSHendrik Brueckner		.endif
18483abeffbSHendrik Brueckner		.ifeq \mask
18583abeffbSHendrik Brueckner			.error "Mask must not be zero"
18683abeffbSHendrik Brueckner		.endif
18783abeffbSHendrik Brueckner		off = \size - \bytepos - 1
18883abeffbSHendrik Brueckner		tm	off+\addr, \mask
18983abeffbSHendrik Brueckner	.endm
19083abeffbSHendrik Brueckner
191d768bd89SMartin Schwidefsky	.macro BPOFF
192b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
193d768bd89SMartin Schwidefsky	.endm
194d768bd89SMartin Schwidefsky
195d768bd89SMartin Schwidefsky	.macro BPON
196b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
197d768bd89SMartin Schwidefsky	.endm
198d768bd89SMartin Schwidefsky
1996b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
200b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
201b058661aSMartin Schwidefsky		    "", 82
2026b73044bSMartin Schwidefsky	.endm
2036b73044bSMartin Schwidefsky
2046b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
2056b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
206b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
207b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
2086b73044bSMartin Schwidefsky	.endm
2096b73044bSMartin Schwidefsky
2106dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r9
2116dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
2126dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14,%r11
213f19fbd5eSMartin Schwidefsky
2144bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
21546210c44SHeiko Carstens.Ldummy:
21646210c44SHeiko Carstens	/*
21746210c44SHeiko Carstens	 * This nop exists only in order to avoid that __switch_to starts at
21846210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
21946210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
22046210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
22146210c44SHeiko Carstens	 * With the added nop in between the __switch_to symbol is unique
22246210c44SHeiko Carstens	 * again.
22346210c44SHeiko Carstens	 */
22446210c44SHeiko Carstens	nop	0
2254bfc86ceSHeiko Carstens
226d768bd89SMartin SchwidefskyENTRY(__bpon)
227d768bd89SMartin Schwidefsky	.globl __bpon
228d768bd89SMartin Schwidefsky	BPON
2296dd85fbbSMartin Schwidefsky	BR_EX	%r14
23026a374aeSMartin SchwidefskyENDPROC(__bpon)
231d768bd89SMartin Schwidefsky
2324bfc86ceSHeiko Carstens/*
2334bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2344bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2354bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2364bfc86ceSHeiko Carstens * Returns:
2374bfc86ceSHeiko Carstens *  gpr2 = prev
2384bfc86ceSHeiko Carstens */
2394bfc86ceSHeiko CarstensENTRY(__switch_to)
2404bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2413241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2423241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2439fed920eSVasily Gorbik	llill	%r5,STACK_INIT
2443241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2459fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
2469fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
2474bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2484bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2493241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2503241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2513241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2524bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
253e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2546dd85fbbSMartin Schwidefsky	BR_EX	%r14
25526a374aeSMartin SchwidefskyENDPROC(__switch_to)
2564bfc86ceSHeiko Carstens
2574bfc86ceSHeiko Carstens.L__critical_start:
258d0fc4107SMartin Schwidefsky
259d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
260d0fc4107SMartin Schwidefsky/*
261d0fc4107SMartin Schwidefsky * sie64a calling convention:
262d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
263d0fc4107SMartin Schwidefsky * %r3 guest register save area
264d0fc4107SMartin Schwidefsky */
265d0fc4107SMartin SchwidefskyENTRY(sie64a)
266d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2676b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
26892fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
26992fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
27092fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
27192fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
27283abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU		# load guest fp/vx registers ?
273d0fc4107SMartin Schwidefsky	jno	.Lsie_load_guest_gprs
274d0fc4107SMartin Schwidefsky	brasl	%r14,load_fpu_regs		# load guest fp/vx regs
275d0fc4107SMartin Schwidefsky.Lsie_load_guest_gprs:
276d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
277d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
278d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
279d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
280d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
281d0fc4107SMartin Schwidefsky.Lsie_gmap:
28292fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
283d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
284d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
285d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
28683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
287d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
28892fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
289c929500dSQingFeng Hao.Lsie_entry:
290d0fc4107SMartin Schwidefsky	sie	0(%r14)
291d768bd89SMartin Schwidefsky.Lsie_exit:
292d768bd89SMartin Schwidefsky	BPOFF
29392fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
294d0fc4107SMartin Schwidefsky.Lsie_skip:
295d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
296d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
297d0fc4107SMartin Schwidefsky.Lsie_done:
298d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
299c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
300c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
301c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
302c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
303d0fc4107SMartin Schwidefsky# See also .Lcleanup_sie
304c0e7bb38SChristian Borntraeger.Lrewind_pad6:
305c0e7bb38SChristian Borntraeger	nopr	7
306c0e7bb38SChristian Borntraeger.Lrewind_pad4:
307c0e7bb38SChristian Borntraeger	nopr	7
308c0e7bb38SChristian Borntraeger.Lrewind_pad2:
309c0e7bb38SChristian Borntraeger	nopr	7
310d0fc4107SMartin Schwidefsky	.globl sie_exit
311d0fc4107SMartin Schwidefskysie_exit:
31292fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
313d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
3147041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
3157041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
3167041d281SMartin Schwidefsky	xgr	%r2,%r2
3177041d281SMartin Schwidefsky	xgr	%r3,%r3
3187041d281SMartin Schwidefsky	xgr	%r4,%r4
3197041d281SMartin Schwidefsky	xgr	%r5,%r5
320d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
32192fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
3226dd85fbbSMartin Schwidefsky	BR_EX	%r14
323d0fc4107SMartin Schwidefsky.Lsie_fault:
324d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
32592fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
326d0fc4107SMartin Schwidefsky	j	sie_exit
327d0fc4107SMartin Schwidefsky
328c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
329c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
330c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
331d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
33226a374aeSMartin SchwidefskyENDPROC(sie64a)
333711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
334711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
335d0fc4107SMartin Schwidefsky#endif
336d0fc4107SMartin Schwidefsky
3374bfc86ceSHeiko Carstens/*
3384bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3394bfc86ceSHeiko Carstens * are executed with interrupts enabled.
3404bfc86ceSHeiko Carstens */
3414bfc86ceSHeiko Carstens
3424bfc86ceSHeiko CarstensENTRY(system_call)
3434bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
3444bfc86ceSHeiko Carstens.Lsysc_stmg:
3454bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
346d768bd89SMartin Schwidefsky	BPOFF
347d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
34834525e1fSMartin Schwidefsky	lghi	%r13,__TASK_thread
3494bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL
3504bfc86ceSHeiko Carstens.Lsysc_per:
3514bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3524bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
353a359bb11SMartin Schwidefsky.Lsysc_vtime:
35434525e1fSMartin Schwidefsky	UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
3556b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3564bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
3574bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3584bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r11),__LC_SVC_OLD_PSW
3594bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_SVC_ILC
3604bfc86ceSHeiko Carstens	stg	%r14,__PT_FLAGS(%r11)
3614bfc86ceSHeiko Carstens.Lsysc_do_svc:
362d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
363d3f46896SChristian Borntraeger	xgr	%r0,%r0
364ef280c85SMartin Schwidefsky	# load address of system call table
365ef280c85SMartin Schwidefsky	lg	%r10,__THREAD_sysc_table(%r13,%r12)
3664bfc86ceSHeiko Carstens	llgh	%r8,__PT_INT_CODE+2(%r11)
367ff4a742dSGerald Schaefer	slag	%r8,%r8,3			# shift and test for svc 0
3684bfc86ceSHeiko Carstens	jnz	.Lsysc_nr_ok
3694bfc86ceSHeiko Carstens	# svc 0: system call number in %r1
3704bfc86ceSHeiko Carstens	llgfr	%r1,%r1				# clear high word in r1
3714bfc86ceSHeiko Carstens	cghi	%r1,NR_syscalls
3724bfc86ceSHeiko Carstens	jnl	.Lsysc_nr_ok
3734bfc86ceSHeiko Carstens	sth	%r1,__PT_INT_CODE+2(%r11)
374ff4a742dSGerald Schaefer	slag	%r8,%r1,3
3754bfc86ceSHeiko Carstens.Lsysc_nr_ok:
3764bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3774bfc86ceSHeiko Carstens	stg	%r2,__PT_ORIG_GPR2(%r11)
3784bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
379ff4a742dSGerald Schaefer	lg	%r9,0(%r8,%r10)			# get system call add.
38083abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
3814bfc86ceSHeiko Carstens	jnz	.Lsysc_tracesys
3826dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9			# call sys_xxxx
3834bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)		# store return value
3844bfc86ceSHeiko Carstens
3854bfc86ceSHeiko Carstens.Lsysc_return:
3869d6d99e3SHeiko Carstens#ifdef CONFIG_DEBUG_RSEQ
3879d6d99e3SHeiko Carstens	lgr	%r2,%r11
3889d6d99e3SHeiko Carstens	brasl	%r14,rseq_syscall
3899d6d99e3SHeiko Carstens#endif
3904bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
3914bfc86ceSHeiko Carstens.Lsysc_tif:
39283abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_WORK
3934bfc86ceSHeiko Carstens	jnz	.Lsysc_work
39483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
3954bfc86ceSHeiko Carstens	jnz	.Lsysc_work			# check for work
39683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
3974bfc86ceSHeiko Carstens	jnz	.Lsysc_work
3986b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
3994bfc86ceSHeiko Carstens.Lsysc_restore:
4004bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
4014bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
4024bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
40307a63cbeSMartin Schwidefsky.Lsysc_exit_timer:
4044bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4054bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
4064bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
407*0b38b5e1SSven Schnelle	b	__LC_RETURN_LPSWE(%r0)
4084bfc86ceSHeiko Carstens.Lsysc_done:
4094bfc86ceSHeiko Carstens
4104bfc86ceSHeiko Carstens#
4114bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
4124bfc86ceSHeiko Carstens#
4134bfc86ceSHeiko Carstens.Lsysc_work:
41483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
4154bfc86ceSHeiko Carstens	jo	.Lsysc_mcck_pending
41683abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
4174bfc86ceSHeiko Carstens	jo	.Lsysc_reschedule
41823fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
41923fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
4204bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
42183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_UPROBE
4224bfc86ceSHeiko Carstens	jo	.Lsysc_uprobe_notify
4234bfc86ceSHeiko Carstens#endif
424916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
425916cda1aSMartin Schwidefsky	jo	.Lsysc_guarded_storage
42683abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_PER_TRAP
4274bfc86ceSHeiko Carstens	jo	.Lsysc_singlestep
4282f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
4292f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
4302f09ca60SMiroslav Benes	jo	.Lsysc_patch_pending	# handle live patching just before
4312f09ca60SMiroslav Benes					# signals and possible syscall restart
4322f09ca60SMiroslav Benes#endif
43323fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
43423fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
43583abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
4364bfc86ceSHeiko Carstens	jo	.Lsysc_sigpending
43783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
4384bfc86ceSHeiko Carstens	jo	.Lsysc_notify_resume
43983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
4409977e886SHendrik Brueckner	jo	.Lsysc_vxrs
441b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
442b5a882fcSHeiko Carstens	jnz	.Lsysc_asce
4434bfc86ceSHeiko Carstens	j	.Lsysc_return		# beware of critical section cleanup
4444bfc86ceSHeiko Carstens
4454bfc86ceSHeiko Carstens#
4464bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
4474bfc86ceSHeiko Carstens#
4484bfc86ceSHeiko Carstens.Lsysc_reschedule:
4494bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4504bfc86ceSHeiko Carstens	jg	schedule
4514bfc86ceSHeiko Carstens
4524bfc86ceSHeiko Carstens#
4534bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
4544bfc86ceSHeiko Carstens#
4554bfc86ceSHeiko Carstens.Lsysc_mcck_pending:
4564bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4574bfc86ceSHeiko Carstens	jg	s390_handle_mcck	# TIF bit will be cleared by handler
4584bfc86ceSHeiko Carstens
4594bfc86ceSHeiko Carstens#
4600aaba41bSMartin Schwidefsky# _CIF_ASCE_PRIMARY and/or _CIF_ASCE_SECONDARY set, load user space asce
4614bfc86ceSHeiko Carstens#
462b5a882fcSHeiko Carstens.Lsysc_asce:
4630aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
4640aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
4650aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
4660aaba41bSMartin Schwidefsky	jz	.Lsysc_return
4670aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
4680aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
4690aaba41bSMartin Schwidefsky	jnz	.Lsysc_set_fs_fixup
470606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
4714bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
4720aaba41bSMartin Schwidefsky	j	.Lsysc_return
4730aaba41bSMartin Schwidefsky.Lsysc_set_fs_fixup:
4740aaba41bSMartin Schwidefsky#endif
475b5a882fcSHeiko Carstens	larl	%r14,.Lsysc_return
476b5a882fcSHeiko Carstens	jg	set_fs_fixup
4774bfc86ceSHeiko Carstens
4784bfc86ceSHeiko Carstens#
4799977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
4809977e886SHendrik Brueckner#
4819977e886SHendrik Brueckner.Lsysc_vxrs:
4829977e886SHendrik Brueckner	larl	%r14,.Lsysc_return
4839977e886SHendrik Brueckner	jg	load_fpu_regs
4849977e886SHendrik Brueckner
4859977e886SHendrik Brueckner#
4864bfc86ceSHeiko Carstens# _TIF_SIGPENDING is set, call do_signal
4874bfc86ceSHeiko Carstens#
4884bfc86ceSHeiko Carstens.Lsysc_sigpending:
4894bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
4904bfc86ceSHeiko Carstens	brasl	%r14,do_signal
49183abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
4924bfc86ceSHeiko Carstens	jno	.Lsysc_return
49357d7f939SMartin Schwidefsky.Lsysc_do_syscall:
49457d7f939SMartin Schwidefsky	lghi	%r13,__TASK_thread
4954bfc86ceSHeiko Carstens	lmg	%r2,%r7,__PT_R2(%r11)	# load svc arguments
49657d7f939SMartin Schwidefsky	lghi	%r1,0			# svc 0 returns -ENOSYS
49757d7f939SMartin Schwidefsky	j	.Lsysc_do_svc
4984bfc86ceSHeiko Carstens
4994bfc86ceSHeiko Carstens#
5004bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME is set, call do_notify_resume
5014bfc86ceSHeiko Carstens#
5024bfc86ceSHeiko Carstens.Lsysc_notify_resume:
5034bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5044bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5054bfc86ceSHeiko Carstens	jg	do_notify_resume
5064bfc86ceSHeiko Carstens
5074bfc86ceSHeiko Carstens#
5084bfc86ceSHeiko Carstens# _TIF_UPROBE is set, call uprobe_notify_resume
5094bfc86ceSHeiko Carstens#
5104bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
5114bfc86ceSHeiko Carstens.Lsysc_uprobe_notify:
5124bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5134bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5144bfc86ceSHeiko Carstens	jg	uprobe_notify_resume
5154bfc86ceSHeiko Carstens#endif
5164bfc86ceSHeiko Carstens
5174bfc86ceSHeiko Carstens#
518916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
519916cda1aSMartin Schwidefsky#
520916cda1aSMartin Schwidefsky.Lsysc_guarded_storage:
521916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
522916cda1aSMartin Schwidefsky	larl	%r14,.Lsysc_return
523916cda1aSMartin Schwidefsky	jg	gs_load_bc_cb
52476f1948aSLinus Torvalds#
5252f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
5262f09ca60SMiroslav Benes#
5272f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
5282f09ca60SMiroslav Benes.Lsysc_patch_pending:
5292f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
5302f09ca60SMiroslav Benes	larl	%r14,.Lsysc_return
5312f09ca60SMiroslav Benes	jg	klp_update_patch_state
5322f09ca60SMiroslav Benes#endif
533916cda1aSMartin Schwidefsky
534916cda1aSMartin Schwidefsky#
5354bfc86ceSHeiko Carstens# _PIF_PER_TRAP is set, call do_per_trap
5364bfc86ceSHeiko Carstens#
5374bfc86ceSHeiko Carstens.Lsysc_singlestep:
5384bfc86ceSHeiko Carstens	ni	__PT_FLAGS+7(%r11),255-_PIF_PER_TRAP
5394bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5404bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5414bfc86ceSHeiko Carstens	jg	do_per_trap
5424bfc86ceSHeiko Carstens
5434bfc86ceSHeiko Carstens#
54423fefe11SMartin Schwidefsky# _PIF_SYSCALL_RESTART is set, repeat the current system call
54523fefe11SMartin Schwidefsky#
54623fefe11SMartin Schwidefsky.Lsysc_syscall_restart:
54723fefe11SMartin Schwidefsky	ni	__PT_FLAGS+7(%r11),255-_PIF_SYSCALL_RESTART
54823fefe11SMartin Schwidefsky	lmg	%r1,%r7,__PT_R1(%r11)	# load svc arguments
54923fefe11SMartin Schwidefsky	lg	%r2,__PT_ORIG_GPR2(%r11)
55023fefe11SMartin Schwidefsky	j	.Lsysc_do_svc
55123fefe11SMartin Schwidefsky
55223fefe11SMartin Schwidefsky#
5534bfc86ceSHeiko Carstens# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
5544bfc86ceSHeiko Carstens# and after the system call
5554bfc86ceSHeiko Carstens#
5564bfc86ceSHeiko Carstens.Lsysc_tracesys:
5574bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5584bfc86ceSHeiko Carstens	la	%r3,0
5594bfc86ceSHeiko Carstens	llgh	%r0,__PT_INT_CODE+2(%r11)
5604bfc86ceSHeiko Carstens	stg	%r0,__PT_R2(%r11)
5614bfc86ceSHeiko Carstens	brasl	%r14,do_syscall_trace_enter
5624bfc86ceSHeiko Carstens	lghi	%r0,NR_syscalls
5634bfc86ceSHeiko Carstens	clgr	%r0,%r2
5644bfc86ceSHeiko Carstens	jnh	.Lsysc_tracenogo
565ff4a742dSGerald Schaefer	sllg	%r8,%r2,3
566ff4a742dSGerald Schaefer	lg	%r9,0(%r8,%r10)
5674bfc86ceSHeiko Carstens.Lsysc_tracego:
5684bfc86ceSHeiko Carstens	lmg	%r3,%r7,__PT_R3(%r11)
5694bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
5704bfc86ceSHeiko Carstens	lg	%r2,__PT_ORIG_GPR2(%r11)
5716dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# call sys_xxx
5724bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)	# store return value
5734bfc86ceSHeiko Carstens.Lsysc_tracenogo:
57483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
5754bfc86ceSHeiko Carstens	jz	.Lsysc_return
5764bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5774bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5784bfc86ceSHeiko Carstens	jg	do_syscall_trace_exit
57926a374aeSMartin SchwidefskyENDPROC(system_call)
5804bfc86ceSHeiko Carstens
5814bfc86ceSHeiko Carstens#
5824bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
5834bfc86ceSHeiko Carstens#
5844bfc86ceSHeiko CarstensENTRY(ret_from_fork)
5854bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
586d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
5874bfc86ceSHeiko Carstens	brasl	%r14,schedule_tail
5884bfc86ceSHeiko Carstens	TRACE_IRQS_ON
5894bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
5904bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
5914bfc86ceSHeiko Carstens	jne	.Lsysc_tracenogo
5924bfc86ceSHeiko Carstens	# it's a kernel thread
5934bfc86ceSHeiko Carstens	lmg	%r9,%r10,__PT_R9(%r11)	# load gprs
59426a374aeSMartin Schwidefsky	la	%r2,0(%r10)
59526a374aeSMartin Schwidefsky	BASR_EX	%r14,%r9
59626a374aeSMartin Schwidefsky	j	.Lsysc_tracenogo
59726a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
59826a374aeSMartin Schwidefsky
5994bfc86ceSHeiko CarstensENTRY(kernel_thread_starter)
6004bfc86ceSHeiko Carstens	la	%r2,0(%r10)
6016dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9
6024bfc86ceSHeiko Carstens	j	.Lsysc_tracenogo
60326a374aeSMartin SchwidefskyENDPROC(kernel_thread_starter)
6044bfc86ceSHeiko Carstens
6054bfc86ceSHeiko Carstens/*
6064bfc86ceSHeiko Carstens * Program check handler routine
6074bfc86ceSHeiko Carstens */
6084bfc86ceSHeiko Carstens
6094bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
6104bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
611d768bd89SMartin Schwidefsky	BPOFF
6124bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
6134bfc86ceSHeiko Carstens	lg	%r10,__LC_LAST_BREAK
614*0b38b5e1SSven Schnelle	srag	%r11,%r10,12
615*0b38b5e1SSven Schnelle	jnz	0f
616*0b38b5e1SSven Schnelle	/* if __LC_LAST_BREAK is < 4096, it contains one of
617*0b38b5e1SSven Schnelle	 * the lpswe addresses in lowcore. Set it to 1 (initial state)
618*0b38b5e1SSven Schnelle	 * to prevent leaking that address to userspace.
619*0b38b5e1SSven Schnelle	 */
620*0b38b5e1SSven Schnelle	lghi	%r10,1
621*0b38b5e1SSven Schnelle0:	lg	%r12,__LC_CURRENT
622c771320eSMartin Schwidefsky	lghi	%r11,0
6239977e886SHendrik Brueckner	larl	%r13,cleanup_critical
6244bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
6254bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# test problem state bit
626*0b38b5e1SSven Schnelle	jnz	3f			# -> fault in user space
627d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
6280a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
629d0fc4107SMartin Schwidefsky	lgr	%r14,%r9
630d0fc4107SMartin Schwidefsky	slg	%r14,BASED(.Lsie_critical_start)
631d0fc4107SMartin Schwidefsky	clg	%r14,BASED(.Lsie_critical_length)
632*0b38b5e1SSven Schnelle	jhe	1f
63392fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
6340a5e2ec2SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
6350a5e2ec2SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
6360a5e2ec2SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
637c771320eSMartin Schwidefsky	lghi	%r11,_PIF_GUEST_FAULT
638d0fc4107SMartin Schwidefsky#endif
639*0b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
640*0b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
6414bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
6424bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
643*0b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
6444bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
645*0b38b5e1SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 5f
646*0b38b5e1SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,5f
647*0b38b5e1SSven Schnelle3:	UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
6486b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
6494bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
650d5c352cdSHeiko Carstens	lgr	%r14,%r12
6513827ec3dSMartin Schwidefsky	aghi	%r14,__TASK_thread	# pointer to thread_struct
6524bfc86ceSHeiko Carstens	lghi	%r13,__LC_PGM_TDB
6534bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+2,0x02	# check for transaction abort
654*0b38b5e1SSven Schnelle	jz	4f
6554bfc86ceSHeiko Carstens	mvc	__THREAD_trap_tdb(256,%r14),0(%r13)
656*0b38b5e1SSven Schnelle4:	stg	%r10,__THREAD_last_break(%r14)
657*0b38b5e1SSven Schnelle5:	lgr	%r13,%r11
658c771320eSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6594bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6607041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
6617041d281SMartin Schwidefsky	xgr	%r0,%r0
6627041d281SMartin Schwidefsky	xgr	%r1,%r1
6637041d281SMartin Schwidefsky	xgr	%r2,%r2
6647041d281SMartin Schwidefsky	xgr	%r3,%r3
6657041d281SMartin Schwidefsky	xgr	%r4,%r4
6667041d281SMartin Schwidefsky	xgr	%r5,%r5
6677041d281SMartin Schwidefsky	xgr	%r6,%r6
6687041d281SMartin Schwidefsky	xgr	%r7,%r7
6694bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
6704bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6714bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_PGM_ILC
6724bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
673c771320eSMartin Schwidefsky	stg	%r13,__PT_FLAGS(%r11)
6744bfc86ceSHeiko Carstens	stg	%r10,__PT_ARGS(%r11)
6754bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
676*0b38b5e1SSven Schnelle	jz	6f
6774bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# kernel per event ?
6784bfc86ceSHeiko Carstens	jz	.Lpgm_kprobe
6794bfc86ceSHeiko Carstens	oi	__PT_FLAGS+7(%r11),_PIF_PER_TRAP
6804bfc86ceSHeiko Carstens	mvc	__THREAD_per_address(8,%r14),__LC_PER_ADDRESS
6814bfc86ceSHeiko Carstens	mvc	__THREAD_per_cause(2,%r14),__LC_PER_CODE
6824bfc86ceSHeiko Carstens	mvc	__THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
683*0b38b5e1SSven Schnelle6:	REENABLE_IRQS
6844bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6854bfc86ceSHeiko Carstens	larl	%r1,pgm_check_table
6864bfc86ceSHeiko Carstens	llgh	%r10,__PT_INT_CODE+2(%r11)
6874bfc86ceSHeiko Carstens	nill	%r10,0x007f
688ff4a742dSGerald Schaefer	sll	%r10,3
689a359bb11SMartin Schwidefsky	je	.Lpgm_return
690ff4a742dSGerald Schaefer	lg	%r9,0(%r10,%r1)		# load address of handler routine
6914bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6926dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# branch to interrupt-handler
693a359bb11SMartin Schwidefsky.Lpgm_return:
694a359bb11SMartin Schwidefsky	LOCKDEP_SYS_EXIT
695a359bb11SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
696a359bb11SMartin Schwidefsky	jno	.Lsysc_restore
69757d7f939SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
69857d7f939SMartin Schwidefsky	jo	.Lsysc_do_syscall
699a359bb11SMartin Schwidefsky	j	.Lsysc_tif
7004bfc86ceSHeiko Carstens
7014bfc86ceSHeiko Carstens#
7024bfc86ceSHeiko Carstens# PER event in supervisor state, must be kprobes
7034bfc86ceSHeiko Carstens#
7044bfc86ceSHeiko Carstens.Lpgm_kprobe:
7054bfc86ceSHeiko Carstens	REENABLE_IRQS
7064bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7074bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7084bfc86ceSHeiko Carstens	brasl	%r14,do_per_trap
709a359bb11SMartin Schwidefsky	j	.Lpgm_return
7104bfc86ceSHeiko Carstens
7114bfc86ceSHeiko Carstens#
7124bfc86ceSHeiko Carstens# single stepped system call
7134bfc86ceSHeiko Carstens#
7144bfc86ceSHeiko Carstens.Lpgm_svcper:
7154bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
716d24b98e3SMartin Schwidefsky	lghi	%r13,__TASK_thread
7174bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
7184bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
7194bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL | _PIF_PER_TRAP
7204bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per and enable irqs
72126a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
7224bfc86ceSHeiko Carstens
7234bfc86ceSHeiko Carstens/*
7244bfc86ceSHeiko Carstens * IO interrupt handler routine
7254bfc86ceSHeiko Carstens */
7264bfc86ceSHeiko CarstensENTRY(io_int_handler)
7274bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
7284bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
729d768bd89SMartin Schwidefsky	BPOFF
7304bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
731d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
7329977e886SHendrik Brueckner	larl	%r13,cleanup_critical
7334bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_IO_OLD_PSW
7342acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
7354bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
7367041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
7377041d281SMartin Schwidefsky	xgr	%r0,%r0
7387041d281SMartin Schwidefsky	xgr	%r1,%r1
7397041d281SMartin Schwidefsky	xgr	%r2,%r2
7407041d281SMartin Schwidefsky	xgr	%r3,%r3
7417041d281SMartin Schwidefsky	xgr	%r4,%r4
7427041d281SMartin Schwidefsky	xgr	%r5,%r5
7437041d281SMartin Schwidefsky	xgr	%r6,%r6
7447041d281SMartin Schwidefsky	xgr	%r7,%r7
7457041d281SMartin Schwidefsky	xgr	%r10,%r10
7464bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
7474bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
7484bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7494bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
750db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
751db7e007fSHeiko Carstens	jo	.Lio_restore
7524bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
7534bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7544bfc86ceSHeiko Carstens.Lio_loop:
7554bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7564bfc86ceSHeiko Carstens	lghi	%r3,IO_INTERRUPT
7574bfc86ceSHeiko Carstens	tm	__PT_INT_CODE+8(%r11),0x80	# adapter interrupt ?
7584bfc86ceSHeiko Carstens	jz	.Lio_call
7594bfc86ceSHeiko Carstens	lghi	%r3,THIN_INTERRUPT
7604bfc86ceSHeiko Carstens.Lio_call:
7614bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
76283abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
7634bfc86ceSHeiko Carstens	jz	.Lio_return
7644bfc86ceSHeiko Carstens	tpi	0
7654bfc86ceSHeiko Carstens	jz	.Lio_return
7664bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7674bfc86ceSHeiko Carstens	j	.Lio_loop
7684bfc86ceSHeiko Carstens.Lio_return:
7694bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
7704bfc86ceSHeiko Carstens	TRACE_IRQS_ON
7714bfc86ceSHeiko Carstens.Lio_tif:
77283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
7734bfc86ceSHeiko Carstens	jnz	.Lio_work		# there is work to do (signals etc.)
77483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
7754bfc86ceSHeiko Carstens	jnz	.Lio_work
7764bfc86ceSHeiko Carstens.Lio_restore:
7774bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
7784bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
7794bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
780d768bd89SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
781d768bd89SMartin Schwidefsky	jno	.Lio_exit_kernel
7826b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
78307a63cbeSMartin Schwidefsky.Lio_exit_timer:
7844bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
7854bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
786d768bd89SMartin Schwidefsky.Lio_exit_kernel:
7874bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
788*0b38b5e1SSven Schnelle	b	__LC_RETURN_LPSWE(%r0)
7894bfc86ceSHeiko Carstens.Lio_done:
7904bfc86ceSHeiko Carstens
7914bfc86ceSHeiko Carstens#
7924bfc86ceSHeiko Carstens# There is work todo, find out in which context we have been interrupted:
7934bfc86ceSHeiko Carstens# 1) if we return to user space we can do all _TIF_WORK work
7944bfc86ceSHeiko Carstens# 2) if we return to kernel code and kvm is enabled check if we need to
7954bfc86ceSHeiko Carstens#    modify the psw to leave SIE
7964bfc86ceSHeiko Carstens# 3) if we return to kernel code and preemptive scheduling is enabled check
7974bfc86ceSHeiko Carstens#    the preemption counter and if it is zero call preempt_schedule_irq
7984bfc86ceSHeiko Carstens# Before any work can be done, a switch to the kernel stack is required.
7994bfc86ceSHeiko Carstens#
8004bfc86ceSHeiko Carstens.Lio_work:
8014bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
8024bfc86ceSHeiko Carstens	jo	.Lio_work_user		# yes -> do resched & signal
803fa686453SThomas Gleixner#ifdef CONFIG_PREEMPTION
8044bfc86ceSHeiko Carstens	# check for preemptive scheduling
805c360192bSMartin Schwidefsky	icm	%r0,15,__LC_PREEMPT_COUNT
8064bfc86ceSHeiko Carstens	jnz	.Lio_restore		# preemption is disabled
80783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8084bfc86ceSHeiko Carstens	jno	.Lio_restore
8094bfc86ceSHeiko Carstens	# switch to kernel stack
8104bfc86ceSHeiko Carstens	lg	%r1,__PT_R15(%r11)
8114bfc86ceSHeiko Carstens	aghi	%r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
8124bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8134bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8144bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8154bfc86ceSHeiko Carstens	lgr	%r15,%r1
8164bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return, call
8174bfc86ceSHeiko Carstens	# TRACE_IRQS_OFF to keep things symmetrical
8184bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8194bfc86ceSHeiko Carstens	brasl	%r14,preempt_schedule_irq
8204bfc86ceSHeiko Carstens	j	.Lio_return
8214bfc86ceSHeiko Carstens#else
8224bfc86ceSHeiko Carstens	j	.Lio_restore
8234bfc86ceSHeiko Carstens#endif
8244bfc86ceSHeiko Carstens
8254bfc86ceSHeiko Carstens#
8264bfc86ceSHeiko Carstens# Need to do work before returning to userspace, switch to kernel stack
8274bfc86ceSHeiko Carstens#
8284bfc86ceSHeiko Carstens.Lio_work_user:
8294bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK
8304bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8314bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8324bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8334bfc86ceSHeiko Carstens	lgr	%r15,%r1
8344bfc86ceSHeiko Carstens
8354bfc86ceSHeiko Carstens#
8364bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
8374bfc86ceSHeiko Carstens#
8384bfc86ceSHeiko Carstens.Lio_work_tif:
83983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
8404bfc86ceSHeiko Carstens	jo	.Lio_mcck_pending
84183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8424bfc86ceSHeiko Carstens	jo	.Lio_reschedule
8432f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
8442f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
8452f09ca60SMiroslav Benes	jo	.Lio_patch_pending
8462f09ca60SMiroslav Benes#endif
84783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
8484bfc86ceSHeiko Carstens	jo	.Lio_sigpending
84983abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
8504bfc86ceSHeiko Carstens	jo	.Lio_notify_resume
851916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
852916cda1aSMartin Schwidefsky	jo	.Lio_guarded_storage
85383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
8549977e886SHendrik Brueckner	jo	.Lio_vxrs
855b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
856b5a882fcSHeiko Carstens	jnz	.Lio_asce
8574bfc86ceSHeiko Carstens	j	.Lio_return		# beware of critical section cleanup
8584bfc86ceSHeiko Carstens
8594bfc86ceSHeiko Carstens#
8604bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
8614bfc86ceSHeiko Carstens#
8624bfc86ceSHeiko Carstens.Lio_mcck_pending:
8634bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8644bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck	# TIF bit will be cleared by handler
8654bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8664bfc86ceSHeiko Carstens	j	.Lio_return
8674bfc86ceSHeiko Carstens
8684bfc86ceSHeiko Carstens#
869b5a882fcSHeiko Carstens# _CIF_ASCE_PRIMARY and/or CIF_ASCE_SECONDARY set, load user space asce
8704bfc86ceSHeiko Carstens#
871b5a882fcSHeiko Carstens.Lio_asce:
8720aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
8730aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
8740aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
8750aaba41bSMartin Schwidefsky	jz	.Lio_return
8760aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
8770aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
8780aaba41bSMartin Schwidefsky	jnz	.Lio_set_fs_fixup
879606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
8804bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
8810aaba41bSMartin Schwidefsky	j	.Lio_return
8820aaba41bSMartin Schwidefsky.Lio_set_fs_fixup:
8830aaba41bSMartin Schwidefsky#endif
884b5a882fcSHeiko Carstens	larl	%r14,.Lio_return
885b5a882fcSHeiko Carstens	jg	set_fs_fixup
8864bfc86ceSHeiko Carstens
8874bfc86ceSHeiko Carstens#
8889977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
8899977e886SHendrik Brueckner#
8909977e886SHendrik Brueckner.Lio_vxrs:
8919977e886SHendrik Brueckner	larl	%r14,.Lio_return
8929977e886SHendrik Brueckner	jg	load_fpu_regs
8939977e886SHendrik Brueckner
8949977e886SHendrik Brueckner#
895916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
896916cda1aSMartin Schwidefsky#
897916cda1aSMartin Schwidefsky.Lio_guarded_storage:
898916cda1aSMartin Schwidefsky	# TRACE_IRQS_ON already done at .Lio_return
899916cda1aSMartin Schwidefsky	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
900916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
901916cda1aSMartin Schwidefsky	brasl	%r14,gs_load_bc_cb
902916cda1aSMartin Schwidefsky	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
903916cda1aSMartin Schwidefsky	TRACE_IRQS_OFF
904916cda1aSMartin Schwidefsky	j	.Lio_return
905916cda1aSMartin Schwidefsky
906916cda1aSMartin Schwidefsky#
9074bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
9084bfc86ceSHeiko Carstens#
9094bfc86ceSHeiko Carstens.Lio_reschedule:
9104bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9114bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9124bfc86ceSHeiko Carstens	brasl	%r14,schedule		# call scheduler
9134bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9144bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9154bfc86ceSHeiko Carstens	j	.Lio_return
9164bfc86ceSHeiko Carstens
9174bfc86ceSHeiko Carstens#
9182f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
9192f09ca60SMiroslav Benes#
9202f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
9212f09ca60SMiroslav Benes.Lio_patch_pending:
9222f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
9232f09ca60SMiroslav Benes	larl	%r14,.Lio_return
9242f09ca60SMiroslav Benes	jg	klp_update_patch_state
9252f09ca60SMiroslav Benes#endif
9262f09ca60SMiroslav Benes
9272f09ca60SMiroslav Benes#
9284bfc86ceSHeiko Carstens# _TIF_SIGPENDING or is set, call do_signal
9294bfc86ceSHeiko Carstens#
9304bfc86ceSHeiko Carstens.Lio_sigpending:
9314bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9324bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9334bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9344bfc86ceSHeiko Carstens	brasl	%r14,do_signal
9354bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9364bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9374bfc86ceSHeiko Carstens	j	.Lio_return
9384bfc86ceSHeiko Carstens
9394bfc86ceSHeiko Carstens#
9404bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
9414bfc86ceSHeiko Carstens#
9424bfc86ceSHeiko Carstens.Lio_notify_resume:
9434bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9444bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9454bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9464bfc86ceSHeiko Carstens	brasl	%r14,do_notify_resume
9474bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9484bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9494bfc86ceSHeiko Carstens	j	.Lio_return
95026a374aeSMartin SchwidefskyENDPROC(io_int_handler)
9514bfc86ceSHeiko Carstens
9524bfc86ceSHeiko Carstens/*
9534bfc86ceSHeiko Carstens * External interrupt handler routine
9544bfc86ceSHeiko Carstens */
9554bfc86ceSHeiko CarstensENTRY(ext_int_handler)
9564bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
9574bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
958d768bd89SMartin Schwidefsky	BPOFF
9594bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
960d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
9619977e886SHendrik Brueckner	larl	%r13,cleanup_critical
9624bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_EXT_OLD_PSW
9632acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
9644bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
9657041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
9667041d281SMartin Schwidefsky	xgr	%r0,%r0
9677041d281SMartin Schwidefsky	xgr	%r1,%r1
9687041d281SMartin Schwidefsky	xgr	%r2,%r2
9697041d281SMartin Schwidefsky	xgr	%r3,%r3
9707041d281SMartin Schwidefsky	xgr	%r4,%r4
9717041d281SMartin Schwidefsky	xgr	%r5,%r5
9727041d281SMartin Schwidefsky	xgr	%r6,%r6
9737041d281SMartin Schwidefsky	xgr	%r7,%r7
9747041d281SMartin Schwidefsky	xgr	%r10,%r10
9754bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
9764bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
9774bfc86ceSHeiko Carstens	lghi	%r1,__LC_EXT_PARAMS2
9784bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
9794bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
9804bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),0(%r1)
9814bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
982db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
983db7e007fSHeiko Carstens	jo	.Lio_restore
9844bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9854bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
9864bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9874bfc86ceSHeiko Carstens	lghi	%r3,EXT_INTERRUPT
9884bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
9894bfc86ceSHeiko Carstens	j	.Lio_return
99026a374aeSMartin SchwidefskyENDPROC(ext_int_handler)
9914bfc86ceSHeiko Carstens
9924bfc86ceSHeiko Carstens/*
9934bfc86ceSHeiko Carstens * Load idle PSW. The second "half" of this function is in .Lcleanup_idle.
9944bfc86ceSHeiko Carstens */
9954bfc86ceSHeiko CarstensENTRY(psw_idle)
9964bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
9974bfc86ceSHeiko Carstens	larl	%r1,.Lpsw_idle_lpsw+4
9984bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
99972d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
100072d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
100172d38b19SMartin Schwidefsky	ltgr	%r1,%r1
100272d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
100372d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
100472d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
1005419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
1006d768bd89SMartin Schwidefsky	BPON
10074bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
10084bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
10094bfc86ceSHeiko Carstens.Lpsw_idle_lpsw:
10104bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
10116dd85fbbSMartin Schwidefsky	BR_EX	%r14
10124bfc86ceSHeiko Carstens.Lpsw_idle_end:
101326a374aeSMartin SchwidefskyENDPROC(psw_idle)
10144bfc86ceSHeiko Carstens
1015b5510d9bSHendrik Brueckner/*
1016b5510d9bSHendrik Brueckner * Store floating-point controls and floating-point or vector register
1017b5510d9bSHendrik Brueckner * depending whether the vector facility is available.	A critical section
1018b5510d9bSHendrik Brueckner * cleanup assures that the registers are stored even if interrupted for
1019b5510d9bSHendrik Brueckner * some other work.  The CIF_FPU flag is set to trigger a lazy restore
1020b5510d9bSHendrik Brueckner * of the register contents at return from io or a system call.
10219977e886SHendrik Brueckner */
10229977e886SHendrik BruecknerENTRY(save_fpu_regs)
1023d0164ee2SHendrik Brueckner	lg	%r2,__LC_CURRENT
1024d0164ee2SHendrik Brueckner	aghi	%r2,__TASK_thread
102583abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1026f19fbd5eSMartin Schwidefsky	jo	.Lsave_fpu_regs_exit
1027d0164ee2SHendrik Brueckner	stfpc	__THREAD_FPU_fpc(%r2)
1028d0164ee2SHendrik Brueckner	lg	%r3,__THREAD_FPU_regs(%r2)
102983abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
10309977e886SHendrik Brueckner	jz	.Lsave_fpu_regs_fp	  # no -> store FP regs
10319977e886SHendrik Brueckner	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
10329977e886SHendrik Brueckner	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
10339977e886SHendrik Brueckner	j	.Lsave_fpu_regs_done	  # -> set CIF_FPU flag
10349977e886SHendrik Brueckner.Lsave_fpu_regs_fp:
10359977e886SHendrik Brueckner	std	0,0(%r3)
10369977e886SHendrik Brueckner	std	1,8(%r3)
10379977e886SHendrik Brueckner	std	2,16(%r3)
10389977e886SHendrik Brueckner	std	3,24(%r3)
10399977e886SHendrik Brueckner	std	4,32(%r3)
10409977e886SHendrik Brueckner	std	5,40(%r3)
10419977e886SHendrik Brueckner	std	6,48(%r3)
10429977e886SHendrik Brueckner	std	7,56(%r3)
10439977e886SHendrik Brueckner	std	8,64(%r3)
10449977e886SHendrik Brueckner	std	9,72(%r3)
10459977e886SHendrik Brueckner	std	10,80(%r3)
10469977e886SHendrik Brueckner	std	11,88(%r3)
10479977e886SHendrik Brueckner	std	12,96(%r3)
10489977e886SHendrik Brueckner	std	13,104(%r3)
10499977e886SHendrik Brueckner	std	14,112(%r3)
10509977e886SHendrik Brueckner	std	15,120(%r3)
10519977e886SHendrik Brueckner.Lsave_fpu_regs_done:
10529977e886SHendrik Brueckner	oi	__LC_CPU_FLAGS+7,_CIF_FPU
1053f19fbd5eSMartin Schwidefsky.Lsave_fpu_regs_exit:
10546dd85fbbSMartin Schwidefsky	BR_EX	%r14
10559977e886SHendrik Brueckner.Lsave_fpu_regs_end:
105626a374aeSMartin SchwidefskyENDPROC(save_fpu_regs)
1057711f5df7SAl ViroEXPORT_SYMBOL(save_fpu_regs)
10589977e886SHendrik Brueckner
1059b5510d9bSHendrik Brueckner/*
1060b5510d9bSHendrik Brueckner * Load floating-point controls and floating-point or vector registers.
1061b5510d9bSHendrik Brueckner * A critical section cleanup assures that the register contents are
1062b5510d9bSHendrik Brueckner * loaded even if interrupted for some other work.
10639977e886SHendrik Brueckner *
10649977e886SHendrik Brueckner * There are special calling conventions to fit into sysc and io return work:
10659977e886SHendrik Brueckner *	%r15:	<kernel stack>
10669977e886SHendrik Brueckner * The function requires:
1067b5510d9bSHendrik Brueckner *	%r4
10689977e886SHendrik Brueckner */
10699977e886SHendrik Bruecknerload_fpu_regs:
1070d0164ee2SHendrik Brueckner	lg	%r4,__LC_CURRENT
1071d0164ee2SHendrik Brueckner	aghi	%r4,__TASK_thread
107283abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1073f19fbd5eSMartin Schwidefsky	jno	.Lload_fpu_regs_exit
1074d0164ee2SHendrik Brueckner	lfpc	__THREAD_FPU_fpc(%r4)
107583abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
1076d0164ee2SHendrik Brueckner	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
1077b5510d9bSHendrik Brueckner	jz	.Lload_fpu_regs_fp		# -> no VX, load FP regs
10789977e886SHendrik Brueckner	VLM	%v0,%v15,0,%r4
10799977e886SHendrik Brueckner	VLM	%v16,%v31,256,%r4
10809977e886SHendrik Brueckner	j	.Lload_fpu_regs_done
10819977e886SHendrik Brueckner.Lload_fpu_regs_fp:
10829977e886SHendrik Brueckner	ld	0,0(%r4)
10839977e886SHendrik Brueckner	ld	1,8(%r4)
10849977e886SHendrik Brueckner	ld	2,16(%r4)
10859977e886SHendrik Brueckner	ld	3,24(%r4)
10869977e886SHendrik Brueckner	ld	4,32(%r4)
10879977e886SHendrik Brueckner	ld	5,40(%r4)
10889977e886SHendrik Brueckner	ld	6,48(%r4)
10899977e886SHendrik Brueckner	ld	7,56(%r4)
10909977e886SHendrik Brueckner	ld	8,64(%r4)
10919977e886SHendrik Brueckner	ld	9,72(%r4)
10929977e886SHendrik Brueckner	ld	10,80(%r4)
10939977e886SHendrik Brueckner	ld	11,88(%r4)
10949977e886SHendrik Brueckner	ld	12,96(%r4)
10959977e886SHendrik Brueckner	ld	13,104(%r4)
10969977e886SHendrik Brueckner	ld	14,112(%r4)
10979977e886SHendrik Brueckner	ld	15,120(%r4)
10989977e886SHendrik Brueckner.Lload_fpu_regs_done:
10999977e886SHendrik Brueckner	ni	__LC_CPU_FLAGS+7,255-_CIF_FPU
1100f19fbd5eSMartin Schwidefsky.Lload_fpu_regs_exit:
11016dd85fbbSMartin Schwidefsky	BR_EX	%r14
11029977e886SHendrik Brueckner.Lload_fpu_regs_end:
110326a374aeSMartin SchwidefskyENDPROC(load_fpu_regs)
11049977e886SHendrik Brueckner
11054bfc86ceSHeiko Carstens.L__critical_end:
11064bfc86ceSHeiko Carstens
11074bfc86ceSHeiko Carstens/*
11084bfc86ceSHeiko Carstens * Machine check handler routines
11094bfc86ceSHeiko Carstens */
11104bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
11114bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
1112d768bd89SMartin Schwidefsky	BPOFF
11133037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
11143037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
11153037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
11163037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
11173037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
1118d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
11199977e886SHendrik Brueckner	larl	%r13,cleanup_critical
11204bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
112183abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
11224bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
11233037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
11243037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
11253037a52fSMartin Schwidefsky	la	%r14,4095
11263037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
11273037a52fSMartin Schwidefsky	ptlb
11282a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
11293037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
11303037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
11313037a52fSMartin Schwidefsky	jno	0f
11323037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
11333037a52fSMartin Schwidefsky	jno	0f
11343037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
11353037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
11363037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
11373037a52fSMartin Schwidefsky	jo	0f
11383037a52fSMartin Schwidefsky	sr	%r14,%r14
11393037a52fSMartin Schwidefsky0:	sfpc	%r14
11403037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
11413037a52fSMartin Schwidefsky	jo	0f
11423037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
11433037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
11443037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
11453037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
11463037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
11473037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
11483037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
11493037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
11503037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
11513037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
11523037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
11533037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
11543037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
11553037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
11563037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
11573037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
11583037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
11593037a52fSMartin Schwidefsky	j	1f
11603037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
11613037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
11623037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
11634bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
116483abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
11654bfc86ceSHeiko Carstens	jo	3f
11664bfc86ceSHeiko Carstens	la	%r14,__LC_SYNC_ENTER_TIMER
11674bfc86ceSHeiko Carstens	clc	0(8,%r14),__LC_ASYNC_ENTER_TIMER
11684bfc86ceSHeiko Carstens	jl	0f
11694bfc86ceSHeiko Carstens	la	%r14,__LC_ASYNC_ENTER_TIMER
11704bfc86ceSHeiko Carstens0:	clc	0(8,%r14),__LC_EXIT_TIMER
11714bfc86ceSHeiko Carstens	jl	1f
11724bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
11734bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
11744bfc86ceSHeiko Carstens	jl	2f
11754bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
11764bfc86ceSHeiko Carstens2:	spt	0(%r14)
11774bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
11783037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
11793037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11803037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
11813037a52fSMartin Schwidefsky	jnz	4f
11823037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
11833037a52fSMartin Schwidefsky	jno	.Lmcck_panic
1184ce3dc447SMartin Schwidefsky4:	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
1185ce3dc447SMartin Schwidefsky	SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
11864bfc86ceSHeiko Carstens.Lmcck_skip:
11874bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
11884bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
11897041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
11907041d281SMartin Schwidefsky	xgr	%r0,%r0
11917041d281SMartin Schwidefsky	xgr	%r1,%r1
11927041d281SMartin Schwidefsky	xgr	%r2,%r2
11937041d281SMartin Schwidefsky	xgr	%r3,%r3
11947041d281SMartin Schwidefsky	xgr	%r4,%r4
11957041d281SMartin Schwidefsky	xgr	%r5,%r5
11967041d281SMartin Schwidefsky	xgr	%r6,%r6
11977041d281SMartin Schwidefsky	xgr	%r7,%r7
11987041d281SMartin Schwidefsky	xgr	%r10,%r10
11994bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12004bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12014bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
12024bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12034bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12044bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
12054bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
12064bfc86ceSHeiko Carstens	jno	.Lmcck_return
12074bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
12084bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
12094bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
12104bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
12114bfc86ceSHeiko Carstens	lgr	%r15,%r1
121283abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
12134bfc86ceSHeiko Carstens	jno	.Lmcck_return
12144bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
12154bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
12164bfc86ceSHeiko Carstens	TRACE_IRQS_ON
12174bfc86ceSHeiko Carstens.Lmcck_return:
12184bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
12194bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
12204bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
12214bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
12224bfc86ceSHeiko Carstens	jno	0f
12236b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
12244bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
12254bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
12264bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
1227*0b38b5e1SSven Schnelle	b	__LC_RETURN_MCCK_LPSWE
12284bfc86ceSHeiko Carstens
12294bfc86ceSHeiko Carstens.Lmcck_panic:
1230ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK
1231ce4dda3fSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12324bfc86ceSHeiko Carstens	j	.Lmcck_skip
123326a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
12344bfc86ceSHeiko Carstens
12354bfc86ceSHeiko Carstens#
12364bfc86ceSHeiko Carstens# PSW restart interrupt handler
12374bfc86ceSHeiko Carstens#
12384bfc86ceSHeiko CarstensENTRY(restart_int_handler)
1239e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
1240e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
12414bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
1242ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
1243ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
1244ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
1245ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
12464bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
12474bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
12484bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
12494bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
12504bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
12514bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
12524bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
12534bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
12544bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
12554bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
12564bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
12574bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
12584bfc86ceSHeiko Carstens	brc	2,2b
12594bfc86ceSHeiko Carstens3:	j	3b
126026a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
12614bfc86ceSHeiko Carstens
12624bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
12634bfc86ceSHeiko Carstens
1264ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
12654bfc86ceSHeiko Carstens/*
12664bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
12674bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
12684bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
12694bfc86ceSHeiko Carstens */
127026a374aeSMartin SchwidefskyENTRY(stack_overflow)
1271ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
12724bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12734bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
12744bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12754bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12764bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
12774bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12784bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12794bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
128026a374aeSMartin SchwidefskyENDPROC(stack_overflow)
12814bfc86ceSHeiko Carstens#endif
12824bfc86ceSHeiko Carstens
128326a374aeSMartin SchwidefskyENTRY(cleanup_critical)
1284*0b38b5e1SSven Schnelle	cghi	%r9,__LC_RETURN_LPSWE
1285*0b38b5e1SSven Schnelle	je	.Lcleanup_lpswe
1286d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1287d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie)	# .Lsie_gmap
1288d0fc4107SMartin Schwidefsky	jl	0f
1289d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie+8)# .Lsie_done
1290d0fc4107SMartin Schwidefsky	jl	.Lcleanup_sie
1291d0fc4107SMartin Schwidefsky#endif
12924bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table)	# system_call
12934bfc86ceSHeiko Carstens	jl	0f
12944bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+8)	# .Lsysc_do_svc
12954bfc86ceSHeiko Carstens	jl	.Lcleanup_system_call
12964bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+16)	# .Lsysc_tif
12974bfc86ceSHeiko Carstens	jl	0f
12984bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+24)	# .Lsysc_restore
12994bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_tif
13004bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+32)	# .Lsysc_done
13014bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_restore
13024bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+40)	# .Lio_tif
13034bfc86ceSHeiko Carstens	jl	0f
13044bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+48)	# .Lio_restore
13054bfc86ceSHeiko Carstens	jl	.Lcleanup_io_tif
13064bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+56)	# .Lio_done
13074bfc86ceSHeiko Carstens	jl	.Lcleanup_io_restore
13084bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+64)	# psw_idle
13094bfc86ceSHeiko Carstens	jl	0f
13104bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+72)	# .Lpsw_idle_end
13114bfc86ceSHeiko Carstens	jl	.Lcleanup_idle
13129977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+80)	# save_fpu_regs
13139977e886SHendrik Brueckner	jl	0f
13149977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+88)	# .Lsave_fpu_regs_end
13159977e886SHendrik Brueckner	jl	.Lcleanup_save_fpu_regs
13169977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+96)	# load_fpu_regs
13179977e886SHendrik Brueckner	jl	0f
13189977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+104)	# .Lload_fpu_regs_end
13199977e886SHendrik Brueckner	jl	.Lcleanup_load_fpu_regs
1320891f6a72SChristian Borntraeger0:	BR_EX	%r14,%r11
132126a374aeSMartin SchwidefskyENDPROC(cleanup_critical)
13224bfc86ceSHeiko Carstens
1323d0fc4107SMartin Schwidefsky	.align	8
1324d0fc4107SMartin Schwidefsky.Lcleanup_table:
1325d0fc4107SMartin Schwidefsky	.quad	system_call
1326d0fc4107SMartin Schwidefsky	.quad	.Lsysc_do_svc
1327d0fc4107SMartin Schwidefsky	.quad	.Lsysc_tif
1328d0fc4107SMartin Schwidefsky	.quad	.Lsysc_restore
1329d0fc4107SMartin Schwidefsky	.quad	.Lsysc_done
1330d0fc4107SMartin Schwidefsky	.quad	.Lio_tif
1331d0fc4107SMartin Schwidefsky	.quad	.Lio_restore
1332d0fc4107SMartin Schwidefsky	.quad	.Lio_done
1333d0fc4107SMartin Schwidefsky	.quad	psw_idle
1334d0fc4107SMartin Schwidefsky	.quad	.Lpsw_idle_end
1335d0fc4107SMartin Schwidefsky	.quad	save_fpu_regs
1336d0fc4107SMartin Schwidefsky	.quad	.Lsave_fpu_regs_end
1337d0fc4107SMartin Schwidefsky	.quad	load_fpu_regs
1338d0fc4107SMartin Schwidefsky	.quad	.Lload_fpu_regs_end
1339d0fc4107SMartin Schwidefsky
1340d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1341d0fc4107SMartin Schwidefsky.Lcleanup_table_sie:
1342d0fc4107SMartin Schwidefsky	.quad	.Lsie_gmap
1343d0fc4107SMartin Schwidefsky	.quad	.Lsie_done
1344d0fc4107SMartin Schwidefsky
1345d0fc4107SMartin Schwidefsky.Lcleanup_sie:
1346c929500dSQingFeng Hao	cghi    %r11,__LC_SAVE_AREA_ASYNC 	#Is this in normal interrupt?
1347c929500dSQingFeng Hao	je      1f
1348c929500dSQingFeng Hao	slg     %r9,BASED(.Lsie_crit_mcck_start)
1349c929500dSQingFeng Hao	clg     %r9,BASED(.Lsie_crit_mcck_length)
1350c929500dSQingFeng Hao	jh      1f
1351c929500dSQingFeng Hao	oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
135292fa7a13SMartin Schwidefsky1:	BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
135392fa7a13SMartin Schwidefsky	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
1354e22cf8caSChristian Borntraeger	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
1355d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
1356d0fc4107SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
1357891f6a72SChristian Borntraeger	BR_EX	%r14,%r11
1358d0fc4107SMartin Schwidefsky#endif
13594bfc86ceSHeiko Carstens
13604bfc86ceSHeiko Carstens.Lcleanup_system_call:
13614bfc86ceSHeiko Carstens	# check if stpt has been executed
13624bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn)
13634bfc86ceSHeiko Carstens	jh	0f
13644bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
13654bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
13664bfc86ceSHeiko Carstens	je	0f
13674bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
13684bfc86ceSHeiko Carstens0:	# check if stmg has been executed
13694bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+8)
13704bfc86ceSHeiko Carstens	jh	0f
13714bfc86ceSHeiko Carstens	mvc	__LC_SAVE_AREA_SYNC(64),0(%r11)
13724bfc86ceSHeiko Carstens0:	# check if base register setup + TIF bit load has been done
13734bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+16)
13744bfc86ceSHeiko Carstens	jhe	0f
137534525e1fSMartin Schwidefsky	# set up saved register r12 task struct pointer
137634525e1fSMartin Schwidefsky	stg	%r12,32(%r11)
137734525e1fSMartin Schwidefsky	# set up saved register r13 __TASK_thread offset
137834525e1fSMartin Schwidefsky	mvc	40(8,%r11),BASED(.Lcleanup_system_call_const)
13794bfc86ceSHeiko Carstens0:	# check if the user time update has been done
13804bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+24)
13814bfc86ceSHeiko Carstens	jh	0f
13824bfc86ceSHeiko Carstens	lg	%r15,__LC_EXIT_TIMER
13834bfc86ceSHeiko Carstens	slg	%r15,__LC_SYNC_ENTER_TIMER
13844bfc86ceSHeiko Carstens	alg	%r15,__LC_USER_TIMER
13854bfc86ceSHeiko Carstens	stg	%r15,__LC_USER_TIMER
13864bfc86ceSHeiko Carstens0:	# check if the system time update has been done
13874bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+32)
13884bfc86ceSHeiko Carstens	jh	0f
13894bfc86ceSHeiko Carstens	lg	%r15,__LC_LAST_UPDATE_TIMER
13904bfc86ceSHeiko Carstens	slg	%r15,__LC_EXIT_TIMER
13914bfc86ceSHeiko Carstens	alg	%r15,__LC_SYSTEM_TIMER
13924bfc86ceSHeiko Carstens	stg	%r15,__LC_SYSTEM_TIMER
13934bfc86ceSHeiko Carstens0:	# update accounting time stamp
13944bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
1395d5feec04SMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
139634525e1fSMartin Schwidefsky	# set up saved register r11
13974bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
13984bfc86ceSHeiko Carstens	la	%r9,STACK_FRAME_OVERHEAD(%r15)
13994bfc86ceSHeiko Carstens	stg	%r9,24(%r11)		# r11 pt_regs pointer
14004bfc86ceSHeiko Carstens	# fill pt_regs
14014bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r9),__LC_SAVE_AREA_SYNC
14024bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r9)
14034bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r9),__LC_SVC_OLD_PSW
14044bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r9),__LC_SVC_ILC
14054bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r9),__PT_FLAGS(%r9)
14064bfc86ceSHeiko Carstens	mvi	__PT_FLAGS+7(%r9),_PIF_SYSCALL
14074bfc86ceSHeiko Carstens	# setup saved register r15
14084bfc86ceSHeiko Carstens	stg	%r15,56(%r11)		# r15 stack pointer
14094bfc86ceSHeiko Carstens	# set new psw address and exit
14104bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_do_svc
14116dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14124bfc86ceSHeiko Carstens.Lcleanup_system_call_insn:
14134bfc86ceSHeiko Carstens	.quad	system_call
14144bfc86ceSHeiko Carstens	.quad	.Lsysc_stmg
14154bfc86ceSHeiko Carstens	.quad	.Lsysc_per
1416a359bb11SMartin Schwidefsky	.quad	.Lsysc_vtime+36
14174bfc86ceSHeiko Carstens	.quad	.Lsysc_vtime+42
141834525e1fSMartin Schwidefsky.Lcleanup_system_call_const:
141934525e1fSMartin Schwidefsky	.quad	__TASK_thread
14204bfc86ceSHeiko Carstens
14214bfc86ceSHeiko Carstens.Lcleanup_sysc_tif:
14224bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_tif
14236dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14244bfc86ceSHeiko Carstens
14254bfc86ceSHeiko Carstens.Lcleanup_sysc_restore:
142607a63cbeSMartin Schwidefsky	# check if stpt has been executed
14274bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_sysc_restore_insn)
142807a63cbeSMartin Schwidefsky	jh	0f
142907a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
143007a63cbeSMartin Schwidefsky	cghi	%r11,__LC_SAVE_AREA_ASYNC
14314bfc86ceSHeiko Carstens	je	0f
143207a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
143307a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_sysc_restore_insn+8)
143407a63cbeSMartin Schwidefsky	je	1f
14354bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved pointer to pt_regs
14364bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14374bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14384bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
1439*0b38b5e1SSven Schnelle.Lcleanup_lpswe:
144007a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
14416dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14424bfc86ceSHeiko Carstens.Lcleanup_sysc_restore_insn:
144307a63cbeSMartin Schwidefsky	.quad	.Lsysc_exit_timer
14444bfc86ceSHeiko Carstens	.quad	.Lsysc_done - 4
14454bfc86ceSHeiko Carstens
14464bfc86ceSHeiko Carstens.Lcleanup_io_tif:
14474bfc86ceSHeiko Carstens	larl	%r9,.Lio_tif
14486dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14494bfc86ceSHeiko Carstens
14504bfc86ceSHeiko Carstens.Lcleanup_io_restore:
145107a63cbeSMartin Schwidefsky	# check if stpt has been executed
14524bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_io_restore_insn)
145307a63cbeSMartin Schwidefsky	jh	0f
145407a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
145507a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_io_restore_insn+8)
145607a63cbeSMartin Schwidefsky	je	1f
14574bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved r11 pointer to pt_regs
14584bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14594bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14604bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
146107a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
14626dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14634bfc86ceSHeiko Carstens.Lcleanup_io_restore_insn:
146407a63cbeSMartin Schwidefsky	.quad	.Lio_exit_timer
14654bfc86ceSHeiko Carstens	.quad	.Lio_done - 4
14664bfc86ceSHeiko Carstens
14674bfc86ceSHeiko Carstens.Lcleanup_idle:
1468419123f9SMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
14694bfc86ceSHeiko Carstens	# copy interrupt clock & cpu timer
14704bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
14714bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
14724bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
14734bfc86ceSHeiko Carstens	je	0f
14744bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
14754bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
14764bfc86ceSHeiko Carstens0:	# check if stck & stpt have been executed
14774bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_idle_insn)
14784bfc86ceSHeiko Carstens	jhe	1f
14794bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
14804bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2)
148172d38b19SMartin Schwidefsky1:	# calculate idle cycles
148272d38b19SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_idle_insn)
148372d38b19SMartin Schwidefsky	jl	3f
148472d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
148572d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
148672d38b19SMartin Schwidefsky	ltgr	%r1,%r1
148772d38b19SMartin Schwidefsky	jz	3f
148872d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+80(%r15)
148972d38b19SMartin Schwidefsky	larl	%r3,mt_cycles
149072d38b19SMartin Schwidefsky	ag	%r3,__LC_PERCPU_OFFSET
149172d38b19SMartin Schwidefsky	la	%r4,__SF_EMPTY+16(%r15)
149272d38b19SMartin Schwidefsky2:	lg	%r0,0(%r3)
149372d38b19SMartin Schwidefsky	slg	%r0,0(%r4)
149472d38b19SMartin Schwidefsky	alg	%r0,64(%r4)
149572d38b19SMartin Schwidefsky	stg	%r0,0(%r3)
149672d38b19SMartin Schwidefsky	la	%r3,8(%r3)
149772d38b19SMartin Schwidefsky	la	%r4,8(%r4)
149872d38b19SMartin Schwidefsky	brct	%r1,2b
149972d38b19SMartin Schwidefsky3:	# account system time going idle
15004bfc86ceSHeiko Carstens	lg	%r9,__LC_STEAL_TIMER
15014bfc86ceSHeiko Carstens	alg	%r9,__CLOCK_IDLE_ENTER(%r2)
15024bfc86ceSHeiko Carstens	slg	%r9,__LC_LAST_UPDATE_CLOCK
15034bfc86ceSHeiko Carstens	stg	%r9,__LC_STEAL_TIMER
15044bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2)
15054bfc86ceSHeiko Carstens	lg	%r9,__LC_SYSTEM_TIMER
15064bfc86ceSHeiko Carstens	alg	%r9,__LC_LAST_UPDATE_TIMER
15074bfc86ceSHeiko Carstens	slg	%r9,__TIMER_IDLE_ENTER(%r2)
15084bfc86ceSHeiko Carstens	stg	%r9,__LC_SYSTEM_TIMER
15094bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
15104bfc86ceSHeiko Carstens	# prepare return psw
15114bfc86ceSHeiko Carstens	nihh	%r8,0xfcfd		# clear irq & wait state bits
15124bfc86ceSHeiko Carstens	lg	%r9,48(%r11)		# return from psw_idle
15136dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
15144bfc86ceSHeiko Carstens.Lcleanup_idle_insn:
15154bfc86ceSHeiko Carstens	.quad	.Lpsw_idle_lpsw
15164bfc86ceSHeiko Carstens
15179977e886SHendrik Brueckner.Lcleanup_save_fpu_regs:
1518e370e476SMartin Schwidefsky	larl	%r9,save_fpu_regs
15196dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
15209977e886SHendrik Brueckner
15219977e886SHendrik Brueckner.Lcleanup_load_fpu_regs:
1522e370e476SMartin Schwidefsky	larl	%r9,load_fpu_regs
15236dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
15249977e886SHendrik Brueckner
15254bfc86ceSHeiko Carstens/*
15264bfc86ceSHeiko Carstens * Integer constants
15274bfc86ceSHeiko Carstens */
15284bfc86ceSHeiko Carstens	.align	8
15294bfc86ceSHeiko Carstens.Lcritical_start:
15304bfc86ceSHeiko Carstens	.quad	.L__critical_start
15314bfc86ceSHeiko Carstens.Lcritical_length:
15324bfc86ceSHeiko Carstens	.quad	.L__critical_end - .L__critical_start
15334bfc86ceSHeiko Carstens#if IS_ENABLED(CONFIG_KVM)
1534d0fc4107SMartin Schwidefsky.Lsie_critical_start:
15354bfc86ceSHeiko Carstens	.quad	.Lsie_gmap
15364bfc86ceSHeiko Carstens.Lsie_critical_length:
15374bfc86ceSHeiko Carstens	.quad	.Lsie_done - .Lsie_gmap
1538c929500dSQingFeng Hao.Lsie_crit_mcck_start:
1539c929500dSQingFeng Hao	.quad   .Lsie_entry
1540c929500dSQingFeng Hao.Lsie_crit_mcck_length:
1541c929500dSQingFeng Hao	.quad   .Lsie_skip - .Lsie_entry
15424bfc86ceSHeiko Carstens#endif
15434bfc86ceSHeiko Carstens	.section .rodata, "a"
1544ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
15454bfc86ceSHeiko Carstens	.globl	sys_call_table
15464bfc86ceSHeiko Carstenssys_call_table:
15474381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15484bfc86ceSHeiko Carstens#undef SYSCALL
15494bfc86ceSHeiko Carstens
15504bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
15514bfc86ceSHeiko Carstens
1552ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
15534bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
15544bfc86ceSHeiko Carstenssys_call_table_emu:
15554381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15564bfc86ceSHeiko Carstens#undef SYSCALL
15574bfc86ceSHeiko Carstens#endif
1558