xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 6dd85fbb87d1d6b87a3b1f02ca28d7b2abd2e7ba)
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>
31*6dd85fbbSMartin 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
884bfc86ceSHeiko Carstens	.macro	CHECK_STACK stacksize,savearea
894bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
904bfc86ceSHeiko Carstens	tml	%r15,\stacksize - CONFIG_STACK_GUARD
914bfc86ceSHeiko Carstens	lghi	%r14,\savearea
924bfc86ceSHeiko Carstens	jz	stack_overflow
934bfc86ceSHeiko Carstens#endif
944bfc86ceSHeiko Carstens	.endm
954bfc86ceSHeiko Carstens
962acb94f4SMartin Schwidefsky	.macro	SWITCH_ASYNC savearea,timer
974bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# interrupting from user ?
984bfc86ceSHeiko Carstens	jnz	1f
994bfc86ceSHeiko Carstens	lgr	%r14,%r9
1004bfc86ceSHeiko Carstens	slg	%r14,BASED(.Lcritical_start)
1014bfc86ceSHeiko Carstens	clg	%r14,BASED(.Lcritical_length)
1024bfc86ceSHeiko Carstens	jhe	0f
1034bfc86ceSHeiko Carstens	lghi	%r11,\savearea		# inside critical section, do cleanup
1044bfc86ceSHeiko Carstens	brasl	%r14,cleanup_critical
1054bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# retest problem state after cleanup
1064bfc86ceSHeiko Carstens	jnz	1f
1072acb94f4SMartin Schwidefsky0:	lg	%r14,__LC_ASYNC_STACK	# are we already on the async stack?
1084bfc86ceSHeiko Carstens	slgr	%r14,%r15
1092acb94f4SMartin Schwidefsky	srag	%r14,%r14,STACK_SHIFT
110a359bb11SMartin Schwidefsky	jnz	2f
1112acb94f4SMartin Schwidefsky	CHECK_STACK 1<<STACK_SHIFT,\savearea
1124bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
113a359bb11SMartin Schwidefsky	j	3f
11434525e1fSMartin Schwidefsky1:	UPDATE_VTIME %r14,%r15,\timer
1156b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
1162acb94f4SMartin Schwidefsky2:	lg	%r15,__LC_ASYNC_STACK	# load async stack
117a359bb11SMartin Schwidefsky3:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
1184bfc86ceSHeiko Carstens	.endm
1194bfc86ceSHeiko Carstens
120a359bb11SMartin Schwidefsky	.macro UPDATE_VTIME w1,w2,enter_timer
121a359bb11SMartin Schwidefsky	lg	\w1,__LC_EXIT_TIMER
122a359bb11SMartin Schwidefsky	lg	\w2,__LC_LAST_UPDATE_TIMER
123a359bb11SMartin Schwidefsky	slg	\w1,\enter_timer
124a359bb11SMartin Schwidefsky	slg	\w2,__LC_EXIT_TIMER
125a359bb11SMartin Schwidefsky	alg	\w1,__LC_USER_TIMER
126a359bb11SMartin Schwidefsky	alg	\w2,__LC_SYSTEM_TIMER
127a359bb11SMartin Schwidefsky	stg	\w1,__LC_USER_TIMER
128a359bb11SMartin Schwidefsky	stg	\w2,__LC_SYSTEM_TIMER
1294bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),\enter_timer
1304bfc86ceSHeiko Carstens	.endm
1314bfc86ceSHeiko Carstens
1324bfc86ceSHeiko Carstens	.macro REENABLE_IRQS
1334bfc86ceSHeiko Carstens	stg	%r8,__LC_RETURN_PSW
1344bfc86ceSHeiko Carstens	ni	__LC_RETURN_PSW,0xbf
1354bfc86ceSHeiko Carstens	ssm	__LC_RETURN_PSW
1364bfc86ceSHeiko Carstens	.endm
1374bfc86ceSHeiko Carstens
1384bfc86ceSHeiko Carstens	.macro STCK savearea
1394bfc86ceSHeiko Carstens#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
1404bfc86ceSHeiko Carstens	.insn	s,0xb27c0000,\savearea		# store clock fast
1414bfc86ceSHeiko Carstens#else
1424bfc86ceSHeiko Carstens	.insn	s,0xb2050000,\savearea		# store clock
1434bfc86ceSHeiko Carstens#endif
1444bfc86ceSHeiko Carstens	.endm
1454bfc86ceSHeiko Carstens
14683abeffbSHendrik Brueckner	/*
14783abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
14883abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
14983abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
15083abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
15183abeffbSHendrik Brueckner	 * instruction.
15283abeffbSHendrik Brueckner	 */
15383abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
15483abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
15583abeffbSHendrik Brueckner			.if (\mask & 0xff)
15683abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
15783abeffbSHendrik Brueckner			.endif
15883abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
15983abeffbSHendrik Brueckner			.exitm
16083abeffbSHendrik Brueckner		.endif
16183abeffbSHendrik Brueckner		.ifeq \mask
16283abeffbSHendrik Brueckner			.error "Mask must not be zero"
16383abeffbSHendrik Brueckner		.endif
16483abeffbSHendrik Brueckner		off = \size - \bytepos - 1
16583abeffbSHendrik Brueckner		tm	off+\addr, \mask
16683abeffbSHendrik Brueckner	.endm
16783abeffbSHendrik Brueckner
168d768bd89SMartin Schwidefsky	.macro BPOFF
169b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
170d768bd89SMartin Schwidefsky	.endm
171d768bd89SMartin Schwidefsky
172d768bd89SMartin Schwidefsky	.macro BPON
173b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
174d768bd89SMartin Schwidefsky	.endm
175d768bd89SMartin Schwidefsky
1766b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
177b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
178b058661aSMartin Schwidefsky		    "", 82
1796b73044bSMartin Schwidefsky	.endm
1806b73044bSMartin Schwidefsky
1816b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1826b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
183b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
184b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
1856b73044bSMartin Schwidefsky	.endm
1866b73044bSMartin Schwidefsky
187*6dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r9
188*6dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
189*6dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14,%r11
190f19fbd5eSMartin Schwidefsky
1914bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
19246210c44SHeiko Carstens.Ldummy:
19346210c44SHeiko Carstens	/*
19446210c44SHeiko Carstens	 * This nop exists only in order to avoid that __switch_to starts at
19546210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
19646210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
19746210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
19846210c44SHeiko Carstens	 * With the added nop in between the __switch_to symbol is unique
19946210c44SHeiko Carstens	 * again.
20046210c44SHeiko Carstens	 */
20146210c44SHeiko Carstens	nop	0
2024bfc86ceSHeiko Carstens
203d768bd89SMartin SchwidefskyENTRY(__bpon)
204d768bd89SMartin Schwidefsky	.globl __bpon
205d768bd89SMartin Schwidefsky	BPON
206*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
207d768bd89SMartin Schwidefsky
2084bfc86ceSHeiko Carstens/*
2094bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2104bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2114bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2124bfc86ceSHeiko Carstens * Returns:
2134bfc86ceSHeiko Carstens *  gpr2 = prev
2144bfc86ceSHeiko Carstens */
2154bfc86ceSHeiko CarstensENTRY(__switch_to)
2164bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2173241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2183241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2193241d3ebSHeiko Carstens	lg	%r5,0(%r4,%r3)			# start of kernel stack of next
2203241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2214bfc86ceSHeiko Carstens	lgr	%r15,%r5
2224bfc86ceSHeiko Carstens	aghi	%r15,STACK_INIT			# end of kernel stack of next
2234bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2244bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2253241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2263241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2273241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2284bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
229e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
230*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
2314bfc86ceSHeiko Carstens
2324bfc86ceSHeiko Carstens.L__critical_start:
233d0fc4107SMartin Schwidefsky
234d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
235d0fc4107SMartin Schwidefsky/*
236d0fc4107SMartin Schwidefsky * sie64a calling convention:
237d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
238d0fc4107SMartin Schwidefsky * %r3 guest register save area
239d0fc4107SMartin Schwidefsky */
240d0fc4107SMartin SchwidefskyENTRY(sie64a)
241d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2426b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
24392fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
24492fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
24592fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
24692fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
24783abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU		# load guest fp/vx registers ?
248d0fc4107SMartin Schwidefsky	jno	.Lsie_load_guest_gprs
249d0fc4107SMartin Schwidefsky	brasl	%r14,load_fpu_regs		# load guest fp/vx regs
250d0fc4107SMartin Schwidefsky.Lsie_load_guest_gprs:
251d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
252d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
253d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
254d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
255d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
256d0fc4107SMartin Schwidefsky.Lsie_gmap:
25792fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
258d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
259d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
260d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
26183abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
262d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
26392fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
264c929500dSQingFeng Hao.Lsie_entry:
265d0fc4107SMartin Schwidefsky	sie	0(%r14)
266d768bd89SMartin Schwidefsky.Lsie_exit:
267d768bd89SMartin Schwidefsky	BPOFF
26892fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
269d0fc4107SMartin Schwidefsky.Lsie_skip:
270d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
271d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
272d0fc4107SMartin Schwidefsky.Lsie_done:
273d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
274c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
275c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
276c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
277c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
278d0fc4107SMartin Schwidefsky# See also .Lcleanup_sie
279c0e7bb38SChristian Borntraeger.Lrewind_pad6:
280c0e7bb38SChristian Borntraeger	nopr	7
281c0e7bb38SChristian Borntraeger.Lrewind_pad4:
282c0e7bb38SChristian Borntraeger	nopr	7
283c0e7bb38SChristian Borntraeger.Lrewind_pad2:
284c0e7bb38SChristian Borntraeger	nopr	7
285d0fc4107SMartin Schwidefsky	.globl sie_exit
286d0fc4107SMartin Schwidefskysie_exit:
28792fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
288d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
2897041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
2907041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
2917041d281SMartin Schwidefsky	xgr	%r2,%r2
2927041d281SMartin Schwidefsky	xgr	%r3,%r3
2937041d281SMartin Schwidefsky	xgr	%r4,%r4
2947041d281SMartin Schwidefsky	xgr	%r5,%r5
295d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
29692fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
297*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
298d0fc4107SMartin Schwidefsky.Lsie_fault:
299d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
30092fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
301d0fc4107SMartin Schwidefsky	j	sie_exit
302d0fc4107SMartin Schwidefsky
303c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
304c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
305c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
306d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
307711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
308711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
309d0fc4107SMartin Schwidefsky#endif
310d0fc4107SMartin Schwidefsky
3114bfc86ceSHeiko Carstens/*
3124bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3134bfc86ceSHeiko Carstens * are executed with interrupts enabled.
3144bfc86ceSHeiko Carstens */
3154bfc86ceSHeiko Carstens
3164bfc86ceSHeiko CarstensENTRY(system_call)
3174bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
3184bfc86ceSHeiko Carstens.Lsysc_stmg:
3194bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
320d768bd89SMartin Schwidefsky	BPOFF
321d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
32234525e1fSMartin Schwidefsky	lghi	%r13,__TASK_thread
3234bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL
3244bfc86ceSHeiko Carstens.Lsysc_per:
3254bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3264bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
327a359bb11SMartin Schwidefsky.Lsysc_vtime:
32834525e1fSMartin Schwidefsky	UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
3296b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3304bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
3314bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3324bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r11),__LC_SVC_OLD_PSW
3334bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_SVC_ILC
3344bfc86ceSHeiko Carstens	stg	%r14,__PT_FLAGS(%r11)
3354bfc86ceSHeiko Carstens.Lsysc_do_svc:
336d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
337d3f46896SChristian Borntraeger	xgr	%r0,%r0
338ef280c85SMartin Schwidefsky	# load address of system call table
339ef280c85SMartin Schwidefsky	lg	%r10,__THREAD_sysc_table(%r13,%r12)
3404bfc86ceSHeiko Carstens	llgh	%r8,__PT_INT_CODE+2(%r11)
3414bfc86ceSHeiko Carstens	slag	%r8,%r8,2			# shift and test for svc 0
3424bfc86ceSHeiko Carstens	jnz	.Lsysc_nr_ok
3434bfc86ceSHeiko Carstens	# svc 0: system call number in %r1
3444bfc86ceSHeiko Carstens	llgfr	%r1,%r1				# clear high word in r1
3454bfc86ceSHeiko Carstens	cghi	%r1,NR_syscalls
3464bfc86ceSHeiko Carstens	jnl	.Lsysc_nr_ok
3474bfc86ceSHeiko Carstens	sth	%r1,__PT_INT_CODE+2(%r11)
3484bfc86ceSHeiko Carstens	slag	%r8,%r1,2
3494bfc86ceSHeiko Carstens.Lsysc_nr_ok:
3504bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
3514bfc86ceSHeiko Carstens	stg	%r2,__PT_ORIG_GPR2(%r11)
3524bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
3534bfc86ceSHeiko Carstens	lgf	%r9,0(%r8,%r10)			# get system call add.
35483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
3554bfc86ceSHeiko Carstens	jnz	.Lsysc_tracesys
356*6dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9			# call sys_xxxx
3574bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)		# store return value
3584bfc86ceSHeiko Carstens
3594bfc86ceSHeiko Carstens.Lsysc_return:
3604bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
3614bfc86ceSHeiko Carstens.Lsysc_tif:
36283abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_WORK
3634bfc86ceSHeiko Carstens	jnz	.Lsysc_work
36483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
3654bfc86ceSHeiko Carstens	jnz	.Lsysc_work			# check for work
36683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
3674bfc86ceSHeiko Carstens	jnz	.Lsysc_work
3686b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
3694bfc86ceSHeiko Carstens.Lsysc_restore:
3704bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
3714bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
3724bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
37307a63cbeSMartin Schwidefsky.Lsysc_exit_timer:
3744bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
3754bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
3764bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
3774bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW
3784bfc86ceSHeiko Carstens.Lsysc_done:
3794bfc86ceSHeiko Carstens
3804bfc86ceSHeiko Carstens#
3814bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
3824bfc86ceSHeiko Carstens#
3834bfc86ceSHeiko Carstens.Lsysc_work:
38483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
3854bfc86ceSHeiko Carstens	jo	.Lsysc_mcck_pending
38683abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
3874bfc86ceSHeiko Carstens	jo	.Lsysc_reschedule
38823fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
38923fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
3904bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
39183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_UPROBE
3924bfc86ceSHeiko Carstens	jo	.Lsysc_uprobe_notify
3934bfc86ceSHeiko Carstens#endif
394916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
395916cda1aSMartin Schwidefsky	jo	.Lsysc_guarded_storage
39683abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_PER_TRAP
3974bfc86ceSHeiko Carstens	jo	.Lsysc_singlestep
3982f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
3992f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
4002f09ca60SMiroslav Benes	jo	.Lsysc_patch_pending	# handle live patching just before
4012f09ca60SMiroslav Benes					# signals and possible syscall restart
4022f09ca60SMiroslav Benes#endif
40323fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
40423fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
40583abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
4064bfc86ceSHeiko Carstens	jo	.Lsysc_sigpending
40783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
4084bfc86ceSHeiko Carstens	jo	.Lsysc_notify_resume
40983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
4109977e886SHendrik Brueckner	jo	.Lsysc_vxrs
411b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
412b5a882fcSHeiko Carstens	jnz	.Lsysc_asce
4134bfc86ceSHeiko Carstens	j	.Lsysc_return		# beware of critical section cleanup
4144bfc86ceSHeiko Carstens
4154bfc86ceSHeiko Carstens#
4164bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
4174bfc86ceSHeiko Carstens#
4184bfc86ceSHeiko Carstens.Lsysc_reschedule:
4194bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4204bfc86ceSHeiko Carstens	jg	schedule
4214bfc86ceSHeiko Carstens
4224bfc86ceSHeiko Carstens#
4234bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
4244bfc86ceSHeiko Carstens#
4254bfc86ceSHeiko Carstens.Lsysc_mcck_pending:
4264bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4274bfc86ceSHeiko Carstens	jg	s390_handle_mcck	# TIF bit will be cleared by handler
4284bfc86ceSHeiko Carstens
4294bfc86ceSHeiko Carstens#
4300aaba41bSMartin Schwidefsky# _CIF_ASCE_PRIMARY and/or _CIF_ASCE_SECONDARY set, load user space asce
4314bfc86ceSHeiko Carstens#
432b5a882fcSHeiko Carstens.Lsysc_asce:
4330aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
4340aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
4350aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
4360aaba41bSMartin Schwidefsky	jz	.Lsysc_return
4370aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
4380aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
4390aaba41bSMartin Schwidefsky	jnz	.Lsysc_set_fs_fixup
440606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
4414bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
4420aaba41bSMartin Schwidefsky	j	.Lsysc_return
4430aaba41bSMartin Schwidefsky.Lsysc_set_fs_fixup:
4440aaba41bSMartin Schwidefsky#endif
445b5a882fcSHeiko Carstens	larl	%r14,.Lsysc_return
446b5a882fcSHeiko Carstens	jg	set_fs_fixup
4474bfc86ceSHeiko Carstens
4484bfc86ceSHeiko Carstens#
4499977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
4509977e886SHendrik Brueckner#
4519977e886SHendrik Brueckner.Lsysc_vxrs:
4529977e886SHendrik Brueckner	larl	%r14,.Lsysc_return
4539977e886SHendrik Brueckner	jg	load_fpu_regs
4549977e886SHendrik Brueckner
4559977e886SHendrik Brueckner#
4564bfc86ceSHeiko Carstens# _TIF_SIGPENDING is set, call do_signal
4574bfc86ceSHeiko Carstens#
4584bfc86ceSHeiko Carstens.Lsysc_sigpending:
4594bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
4604bfc86ceSHeiko Carstens	brasl	%r14,do_signal
46183abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
4624bfc86ceSHeiko Carstens	jno	.Lsysc_return
46357d7f939SMartin Schwidefsky.Lsysc_do_syscall:
46457d7f939SMartin Schwidefsky	lghi	%r13,__TASK_thread
4654bfc86ceSHeiko Carstens	lmg	%r2,%r7,__PT_R2(%r11)	# load svc arguments
46657d7f939SMartin Schwidefsky	lghi	%r1,0			# svc 0 returns -ENOSYS
46757d7f939SMartin Schwidefsky	j	.Lsysc_do_svc
4684bfc86ceSHeiko Carstens
4694bfc86ceSHeiko Carstens#
4704bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME is set, call do_notify_resume
4714bfc86ceSHeiko Carstens#
4724bfc86ceSHeiko Carstens.Lsysc_notify_resume:
4734bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
4744bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4754bfc86ceSHeiko Carstens	jg	do_notify_resume
4764bfc86ceSHeiko Carstens
4774bfc86ceSHeiko Carstens#
4784bfc86ceSHeiko Carstens# _TIF_UPROBE is set, call uprobe_notify_resume
4794bfc86ceSHeiko Carstens#
4804bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
4814bfc86ceSHeiko Carstens.Lsysc_uprobe_notify:
4824bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
4834bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4844bfc86ceSHeiko Carstens	jg	uprobe_notify_resume
4854bfc86ceSHeiko Carstens#endif
4864bfc86ceSHeiko Carstens
4874bfc86ceSHeiko Carstens#
488916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
489916cda1aSMartin Schwidefsky#
490916cda1aSMartin Schwidefsky.Lsysc_guarded_storage:
491916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
492916cda1aSMartin Schwidefsky	larl	%r14,.Lsysc_return
493916cda1aSMartin Schwidefsky	jg	gs_load_bc_cb
49476f1948aSLinus Torvalds#
4952f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
4962f09ca60SMiroslav Benes#
4972f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
4982f09ca60SMiroslav Benes.Lsysc_patch_pending:
4992f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
5002f09ca60SMiroslav Benes	larl	%r14,.Lsysc_return
5012f09ca60SMiroslav Benes	jg	klp_update_patch_state
5022f09ca60SMiroslav Benes#endif
503916cda1aSMartin Schwidefsky
504916cda1aSMartin Schwidefsky#
5054bfc86ceSHeiko Carstens# _PIF_PER_TRAP is set, call do_per_trap
5064bfc86ceSHeiko Carstens#
5074bfc86ceSHeiko Carstens.Lsysc_singlestep:
5084bfc86ceSHeiko Carstens	ni	__PT_FLAGS+7(%r11),255-_PIF_PER_TRAP
5094bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5104bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5114bfc86ceSHeiko Carstens	jg	do_per_trap
5124bfc86ceSHeiko Carstens
5134bfc86ceSHeiko Carstens#
51423fefe11SMartin Schwidefsky# _PIF_SYSCALL_RESTART is set, repeat the current system call
51523fefe11SMartin Schwidefsky#
51623fefe11SMartin Schwidefsky.Lsysc_syscall_restart:
51723fefe11SMartin Schwidefsky	ni	__PT_FLAGS+7(%r11),255-_PIF_SYSCALL_RESTART
51823fefe11SMartin Schwidefsky	lmg	%r1,%r7,__PT_R1(%r11)	# load svc arguments
51923fefe11SMartin Schwidefsky	lg	%r2,__PT_ORIG_GPR2(%r11)
52023fefe11SMartin Schwidefsky	j	.Lsysc_do_svc
52123fefe11SMartin Schwidefsky
52223fefe11SMartin Schwidefsky#
5234bfc86ceSHeiko Carstens# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
5244bfc86ceSHeiko Carstens# and after the system call
5254bfc86ceSHeiko Carstens#
5264bfc86ceSHeiko Carstens.Lsysc_tracesys:
5274bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5284bfc86ceSHeiko Carstens	la	%r3,0
5294bfc86ceSHeiko Carstens	llgh	%r0,__PT_INT_CODE+2(%r11)
5304bfc86ceSHeiko Carstens	stg	%r0,__PT_R2(%r11)
5314bfc86ceSHeiko Carstens	brasl	%r14,do_syscall_trace_enter
5324bfc86ceSHeiko Carstens	lghi	%r0,NR_syscalls
5334bfc86ceSHeiko Carstens	clgr	%r0,%r2
5344bfc86ceSHeiko Carstens	jnh	.Lsysc_tracenogo
5354bfc86ceSHeiko Carstens	sllg	%r8,%r2,2
5364bfc86ceSHeiko Carstens	lgf	%r9,0(%r8,%r10)
5374bfc86ceSHeiko Carstens.Lsysc_tracego:
5384bfc86ceSHeiko Carstens	lmg	%r3,%r7,__PT_R3(%r11)
5394bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
5404bfc86ceSHeiko Carstens	lg	%r2,__PT_ORIG_GPR2(%r11)
541*6dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# call sys_xxx
5424bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)	# store return value
5434bfc86ceSHeiko Carstens.Lsysc_tracenogo:
54483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
5454bfc86ceSHeiko Carstens	jz	.Lsysc_return
5464bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5474bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5484bfc86ceSHeiko Carstens	jg	do_syscall_trace_exit
5494bfc86ceSHeiko Carstens
5504bfc86ceSHeiko Carstens#
5514bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
5524bfc86ceSHeiko Carstens#
5534bfc86ceSHeiko CarstensENTRY(ret_from_fork)
5544bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
555d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
5564bfc86ceSHeiko Carstens	brasl	%r14,schedule_tail
5574bfc86ceSHeiko Carstens	TRACE_IRQS_ON
5584bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
5594bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
5604bfc86ceSHeiko Carstens	jne	.Lsysc_tracenogo
5614bfc86ceSHeiko Carstens	# it's a kernel thread
5624bfc86ceSHeiko Carstens	lmg	%r9,%r10,__PT_R9(%r11)	# load gprs
5634bfc86ceSHeiko CarstensENTRY(kernel_thread_starter)
5644bfc86ceSHeiko Carstens	la	%r2,0(%r10)
565*6dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9
5664bfc86ceSHeiko Carstens	j	.Lsysc_tracenogo
5674bfc86ceSHeiko Carstens
5684bfc86ceSHeiko Carstens/*
5694bfc86ceSHeiko Carstens * Program check handler routine
5704bfc86ceSHeiko Carstens */
5714bfc86ceSHeiko Carstens
5724bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
5734bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
574d768bd89SMartin Schwidefsky	BPOFF
5754bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
5764bfc86ceSHeiko Carstens	lg	%r10,__LC_LAST_BREAK
577d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
578c771320eSMartin Schwidefsky	lghi	%r11,0
5799977e886SHendrik Brueckner	larl	%r13,cleanup_critical
5804bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
5814bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# test problem state bit
582d0fc4107SMartin Schwidefsky	jnz	2f			# -> fault in user space
583d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
5840a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
585d0fc4107SMartin Schwidefsky	lgr	%r14,%r9
586d0fc4107SMartin Schwidefsky	slg	%r14,BASED(.Lsie_critical_start)
587d0fc4107SMartin Schwidefsky	clg	%r14,BASED(.Lsie_critical_length)
588d0fc4107SMartin Schwidefsky	jhe	0f
58992fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
5900a5e2ec2SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
5910a5e2ec2SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
5920a5e2ec2SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
593c771320eSMartin Schwidefsky	lghi	%r11,_PIF_GUEST_FAULT
594d0fc4107SMartin Schwidefsky#endif
595d0fc4107SMartin Schwidefsky0:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
596d0fc4107SMartin Schwidefsky	jnz	1f			# -> enabled, can't be a double fault
5974bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
5984bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
599d0fc4107SMartin Schwidefsky1:	CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
6004bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
601d9fcf2a1SMartin Schwidefsky	j	4f
60234525e1fSMartin Schwidefsky2:	UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
6036b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
6044bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
605d5c352cdSHeiko Carstens	lgr	%r14,%r12
6063827ec3dSMartin Schwidefsky	aghi	%r14,__TASK_thread	# pointer to thread_struct
6074bfc86ceSHeiko Carstens	lghi	%r13,__LC_PGM_TDB
6084bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+2,0x02	# check for transaction abort
609d0fc4107SMartin Schwidefsky	jz	3f
6104bfc86ceSHeiko Carstens	mvc	__THREAD_trap_tdb(256,%r14),0(%r13)
611d9fcf2a1SMartin Schwidefsky3:	stg	%r10,__THREAD_last_break(%r14)
612c771320eSMartin Schwidefsky4:	lgr	%r13,%r11
613c771320eSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6144bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6157041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
6167041d281SMartin Schwidefsky	xgr	%r0,%r0
6177041d281SMartin Schwidefsky	xgr	%r1,%r1
6187041d281SMartin Schwidefsky	xgr	%r2,%r2
6197041d281SMartin Schwidefsky	xgr	%r3,%r3
6207041d281SMartin Schwidefsky	xgr	%r4,%r4
6217041d281SMartin Schwidefsky	xgr	%r5,%r5
6227041d281SMartin Schwidefsky	xgr	%r6,%r6
6237041d281SMartin Schwidefsky	xgr	%r7,%r7
6244bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
6254bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6264bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_PGM_ILC
6274bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
628c771320eSMartin Schwidefsky	stg	%r13,__PT_FLAGS(%r11)
6294bfc86ceSHeiko Carstens	stg	%r10,__PT_ARGS(%r11)
6304bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
631d9fcf2a1SMartin Schwidefsky	jz	5f
6324bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# kernel per event ?
6334bfc86ceSHeiko Carstens	jz	.Lpgm_kprobe
6344bfc86ceSHeiko Carstens	oi	__PT_FLAGS+7(%r11),_PIF_PER_TRAP
6354bfc86ceSHeiko Carstens	mvc	__THREAD_per_address(8,%r14),__LC_PER_ADDRESS
6364bfc86ceSHeiko Carstens	mvc	__THREAD_per_cause(2,%r14),__LC_PER_CODE
6374bfc86ceSHeiko Carstens	mvc	__THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
638d9fcf2a1SMartin Schwidefsky5:	REENABLE_IRQS
6394bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6404bfc86ceSHeiko Carstens	larl	%r1,pgm_check_table
6414bfc86ceSHeiko Carstens	llgh	%r10,__PT_INT_CODE+2(%r11)
6424bfc86ceSHeiko Carstens	nill	%r10,0x007f
6434bfc86ceSHeiko Carstens	sll	%r10,2
644a359bb11SMartin Schwidefsky	je	.Lpgm_return
645f19fbd5eSMartin Schwidefsky	lgf	%r9,0(%r10,%r1)		# load address of handler routine
6464bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
647*6dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# branch to interrupt-handler
648a359bb11SMartin Schwidefsky.Lpgm_return:
649a359bb11SMartin Schwidefsky	LOCKDEP_SYS_EXIT
650a359bb11SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
651a359bb11SMartin Schwidefsky	jno	.Lsysc_restore
65257d7f939SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
65357d7f939SMartin Schwidefsky	jo	.Lsysc_do_syscall
654a359bb11SMartin Schwidefsky	j	.Lsysc_tif
6554bfc86ceSHeiko Carstens
6564bfc86ceSHeiko Carstens#
6574bfc86ceSHeiko Carstens# PER event in supervisor state, must be kprobes
6584bfc86ceSHeiko Carstens#
6594bfc86ceSHeiko Carstens.Lpgm_kprobe:
6604bfc86ceSHeiko Carstens	REENABLE_IRQS
6614bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6624bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6634bfc86ceSHeiko Carstens	brasl	%r14,do_per_trap
664a359bb11SMartin Schwidefsky	j	.Lpgm_return
6654bfc86ceSHeiko Carstens
6664bfc86ceSHeiko Carstens#
6674bfc86ceSHeiko Carstens# single stepped system call
6684bfc86ceSHeiko Carstens#
6694bfc86ceSHeiko Carstens.Lpgm_svcper:
6704bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
671d24b98e3SMartin Schwidefsky	lghi	%r13,__TASK_thread
6724bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
6734bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
6744bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL | _PIF_PER_TRAP
6754bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per and enable irqs
6764bfc86ceSHeiko Carstens
6774bfc86ceSHeiko Carstens/*
6784bfc86ceSHeiko Carstens * IO interrupt handler routine
6794bfc86ceSHeiko Carstens */
6804bfc86ceSHeiko CarstensENTRY(io_int_handler)
6814bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
6824bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
683d768bd89SMartin Schwidefsky	BPOFF
6844bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
685d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
6869977e886SHendrik Brueckner	larl	%r13,cleanup_critical
6874bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_IO_OLD_PSW
6882acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
6894bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6907041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
6917041d281SMartin Schwidefsky	xgr	%r0,%r0
6927041d281SMartin Schwidefsky	xgr	%r1,%r1
6937041d281SMartin Schwidefsky	xgr	%r2,%r2
6947041d281SMartin Schwidefsky	xgr	%r3,%r3
6957041d281SMartin Schwidefsky	xgr	%r4,%r4
6967041d281SMartin Schwidefsky	xgr	%r5,%r5
6977041d281SMartin Schwidefsky	xgr	%r6,%r6
6987041d281SMartin Schwidefsky	xgr	%r7,%r7
6997041d281SMartin Schwidefsky	xgr	%r10,%r10
7004bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
7014bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
7024bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7034bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
704db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
705db7e007fSHeiko Carstens	jo	.Lio_restore
7064bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
7074bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7084bfc86ceSHeiko Carstens.Lio_loop:
7094bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7104bfc86ceSHeiko Carstens	lghi	%r3,IO_INTERRUPT
7114bfc86ceSHeiko Carstens	tm	__PT_INT_CODE+8(%r11),0x80	# adapter interrupt ?
7124bfc86ceSHeiko Carstens	jz	.Lio_call
7134bfc86ceSHeiko Carstens	lghi	%r3,THIN_INTERRUPT
7144bfc86ceSHeiko Carstens.Lio_call:
7154bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
71683abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
7174bfc86ceSHeiko Carstens	jz	.Lio_return
7184bfc86ceSHeiko Carstens	tpi	0
7194bfc86ceSHeiko Carstens	jz	.Lio_return
7204bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7214bfc86ceSHeiko Carstens	j	.Lio_loop
7224bfc86ceSHeiko Carstens.Lio_return:
7234bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
7244bfc86ceSHeiko Carstens	TRACE_IRQS_ON
7254bfc86ceSHeiko Carstens.Lio_tif:
72683abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
7274bfc86ceSHeiko Carstens	jnz	.Lio_work		# there is work to do (signals etc.)
72883abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
7294bfc86ceSHeiko Carstens	jnz	.Lio_work
7304bfc86ceSHeiko Carstens.Lio_restore:
7314bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
7324bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
7334bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
734d768bd89SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
735d768bd89SMartin Schwidefsky	jno	.Lio_exit_kernel
7366b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
73707a63cbeSMartin Schwidefsky.Lio_exit_timer:
7384bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
7394bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
740d768bd89SMartin Schwidefsky.Lio_exit_kernel:
7414bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
7424bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW
7434bfc86ceSHeiko Carstens.Lio_done:
7444bfc86ceSHeiko Carstens
7454bfc86ceSHeiko Carstens#
7464bfc86ceSHeiko Carstens# There is work todo, find out in which context we have been interrupted:
7474bfc86ceSHeiko Carstens# 1) if we return to user space we can do all _TIF_WORK work
7484bfc86ceSHeiko Carstens# 2) if we return to kernel code and kvm is enabled check if we need to
7494bfc86ceSHeiko Carstens#    modify the psw to leave SIE
7504bfc86ceSHeiko Carstens# 3) if we return to kernel code and preemptive scheduling is enabled check
7514bfc86ceSHeiko Carstens#    the preemption counter and if it is zero call preempt_schedule_irq
7524bfc86ceSHeiko Carstens# Before any work can be done, a switch to the kernel stack is required.
7534bfc86ceSHeiko Carstens#
7544bfc86ceSHeiko Carstens.Lio_work:
7554bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
7564bfc86ceSHeiko Carstens	jo	.Lio_work_user		# yes -> do resched & signal
7574bfc86ceSHeiko Carstens#ifdef CONFIG_PREEMPT
7584bfc86ceSHeiko Carstens	# check for preemptive scheduling
759c360192bSMartin Schwidefsky	icm	%r0,15,__LC_PREEMPT_COUNT
7604bfc86ceSHeiko Carstens	jnz	.Lio_restore		# preemption is disabled
76183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
7624bfc86ceSHeiko Carstens	jno	.Lio_restore
7634bfc86ceSHeiko Carstens	# switch to kernel stack
7644bfc86ceSHeiko Carstens	lg	%r1,__PT_R15(%r11)
7654bfc86ceSHeiko Carstens	aghi	%r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
7664bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
7674bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
7684bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
7694bfc86ceSHeiko Carstens	lgr	%r15,%r1
7704bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return, call
7714bfc86ceSHeiko Carstens	# TRACE_IRQS_OFF to keep things symmetrical
7724bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
7734bfc86ceSHeiko Carstens	brasl	%r14,preempt_schedule_irq
7744bfc86ceSHeiko Carstens	j	.Lio_return
7754bfc86ceSHeiko Carstens#else
7764bfc86ceSHeiko Carstens	j	.Lio_restore
7774bfc86ceSHeiko Carstens#endif
7784bfc86ceSHeiko Carstens
7794bfc86ceSHeiko Carstens#
7804bfc86ceSHeiko Carstens# Need to do work before returning to userspace, switch to kernel stack
7814bfc86ceSHeiko Carstens#
7824bfc86ceSHeiko Carstens.Lio_work_user:
7834bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK
7844bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
7854bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
7864bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
7874bfc86ceSHeiko Carstens	lgr	%r15,%r1
7884bfc86ceSHeiko Carstens
7894bfc86ceSHeiko Carstens#
7904bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
7914bfc86ceSHeiko Carstens#
7924bfc86ceSHeiko Carstens.Lio_work_tif:
79383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
7944bfc86ceSHeiko Carstens	jo	.Lio_mcck_pending
79583abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
7964bfc86ceSHeiko Carstens	jo	.Lio_reschedule
7972f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
7982f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
7992f09ca60SMiroslav Benes	jo	.Lio_patch_pending
8002f09ca60SMiroslav Benes#endif
80183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
8024bfc86ceSHeiko Carstens	jo	.Lio_sigpending
80383abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
8044bfc86ceSHeiko Carstens	jo	.Lio_notify_resume
805916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
806916cda1aSMartin Schwidefsky	jo	.Lio_guarded_storage
80783abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
8089977e886SHendrik Brueckner	jo	.Lio_vxrs
809b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
810b5a882fcSHeiko Carstens	jnz	.Lio_asce
8114bfc86ceSHeiko Carstens	j	.Lio_return		# beware of critical section cleanup
8124bfc86ceSHeiko Carstens
8134bfc86ceSHeiko Carstens#
8144bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
8154bfc86ceSHeiko Carstens#
8164bfc86ceSHeiko Carstens.Lio_mcck_pending:
8174bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8184bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck	# TIF bit will be cleared by handler
8194bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8204bfc86ceSHeiko Carstens	j	.Lio_return
8214bfc86ceSHeiko Carstens
8224bfc86ceSHeiko Carstens#
823b5a882fcSHeiko Carstens# _CIF_ASCE_PRIMARY and/or CIF_ASCE_SECONDARY set, load user space asce
8244bfc86ceSHeiko Carstens#
825b5a882fcSHeiko Carstens.Lio_asce:
8260aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
8270aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
8280aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
8290aaba41bSMartin Schwidefsky	jz	.Lio_return
8300aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
8310aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
8320aaba41bSMartin Schwidefsky	jnz	.Lio_set_fs_fixup
833606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
8344bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
8350aaba41bSMartin Schwidefsky	j	.Lio_return
8360aaba41bSMartin Schwidefsky.Lio_set_fs_fixup:
8370aaba41bSMartin Schwidefsky#endif
838b5a882fcSHeiko Carstens	larl	%r14,.Lio_return
839b5a882fcSHeiko Carstens	jg	set_fs_fixup
8404bfc86ceSHeiko Carstens
8414bfc86ceSHeiko Carstens#
8429977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
8439977e886SHendrik Brueckner#
8449977e886SHendrik Brueckner.Lio_vxrs:
8459977e886SHendrik Brueckner	larl	%r14,.Lio_return
8469977e886SHendrik Brueckner	jg	load_fpu_regs
8479977e886SHendrik Brueckner
8489977e886SHendrik Brueckner#
849916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
850916cda1aSMartin Schwidefsky#
851916cda1aSMartin Schwidefsky.Lio_guarded_storage:
852916cda1aSMartin Schwidefsky	# TRACE_IRQS_ON already done at .Lio_return
853916cda1aSMartin Schwidefsky	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
854916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
855916cda1aSMartin Schwidefsky	brasl	%r14,gs_load_bc_cb
856916cda1aSMartin Schwidefsky	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
857916cda1aSMartin Schwidefsky	TRACE_IRQS_OFF
858916cda1aSMartin Schwidefsky	j	.Lio_return
859916cda1aSMartin Schwidefsky
860916cda1aSMartin Schwidefsky#
8614bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
8624bfc86ceSHeiko Carstens#
8634bfc86ceSHeiko Carstens.Lio_reschedule:
8644bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8654bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
8664bfc86ceSHeiko Carstens	brasl	%r14,schedule		# call scheduler
8674bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
8684bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8694bfc86ceSHeiko Carstens	j	.Lio_return
8704bfc86ceSHeiko Carstens
8714bfc86ceSHeiko Carstens#
8722f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
8732f09ca60SMiroslav Benes#
8742f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
8752f09ca60SMiroslav Benes.Lio_patch_pending:
8762f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
8772f09ca60SMiroslav Benes	larl	%r14,.Lio_return
8782f09ca60SMiroslav Benes	jg	klp_update_patch_state
8792f09ca60SMiroslav Benes#endif
8802f09ca60SMiroslav Benes
8812f09ca60SMiroslav Benes#
8824bfc86ceSHeiko Carstens# _TIF_SIGPENDING or is set, call do_signal
8834bfc86ceSHeiko Carstens#
8844bfc86ceSHeiko Carstens.Lio_sigpending:
8854bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8864bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
8874bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
8884bfc86ceSHeiko Carstens	brasl	%r14,do_signal
8894bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
8904bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8914bfc86ceSHeiko Carstens	j	.Lio_return
8924bfc86ceSHeiko Carstens
8934bfc86ceSHeiko Carstens#
8944bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
8954bfc86ceSHeiko Carstens#
8964bfc86ceSHeiko Carstens.Lio_notify_resume:
8974bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8984bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
8994bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9004bfc86ceSHeiko Carstens	brasl	%r14,do_notify_resume
9014bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9024bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9034bfc86ceSHeiko Carstens	j	.Lio_return
9044bfc86ceSHeiko Carstens
9054bfc86ceSHeiko Carstens/*
9064bfc86ceSHeiko Carstens * External interrupt handler routine
9074bfc86ceSHeiko Carstens */
9084bfc86ceSHeiko CarstensENTRY(ext_int_handler)
9094bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
9104bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
911d768bd89SMartin Schwidefsky	BPOFF
9124bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
913d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
9149977e886SHendrik Brueckner	larl	%r13,cleanup_critical
9154bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_EXT_OLD_PSW
9162acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
9174bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
9187041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
9197041d281SMartin Schwidefsky	xgr	%r0,%r0
9207041d281SMartin Schwidefsky	xgr	%r1,%r1
9217041d281SMartin Schwidefsky	xgr	%r2,%r2
9227041d281SMartin Schwidefsky	xgr	%r3,%r3
9237041d281SMartin Schwidefsky	xgr	%r4,%r4
9247041d281SMartin Schwidefsky	xgr	%r5,%r5
9257041d281SMartin Schwidefsky	xgr	%r6,%r6
9267041d281SMartin Schwidefsky	xgr	%r7,%r7
9277041d281SMartin Schwidefsky	xgr	%r10,%r10
9284bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
9294bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
9304bfc86ceSHeiko Carstens	lghi	%r1,__LC_EXT_PARAMS2
9314bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
9324bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
9334bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),0(%r1)
9344bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
935db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
936db7e007fSHeiko Carstens	jo	.Lio_restore
9374bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9384bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
9394bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9404bfc86ceSHeiko Carstens	lghi	%r3,EXT_INTERRUPT
9414bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
9424bfc86ceSHeiko Carstens	j	.Lio_return
9434bfc86ceSHeiko Carstens
9444bfc86ceSHeiko Carstens/*
9454bfc86ceSHeiko Carstens * Load idle PSW. The second "half" of this function is in .Lcleanup_idle.
9464bfc86ceSHeiko Carstens */
9474bfc86ceSHeiko CarstensENTRY(psw_idle)
9484bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
9494bfc86ceSHeiko Carstens	larl	%r1,.Lpsw_idle_lpsw+4
9504bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
95172d38b19SMartin Schwidefsky#ifdef CONFIG_SMP
95272d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
95372d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
95472d38b19SMartin Schwidefsky	ltgr	%r1,%r1
95572d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
95672d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
95772d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
95872d38b19SMartin Schwidefsky#endif
959419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
960d768bd89SMartin Schwidefsky	BPON
9614bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
9624bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
9634bfc86ceSHeiko Carstens.Lpsw_idle_lpsw:
9644bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
965*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
9664bfc86ceSHeiko Carstens.Lpsw_idle_end:
9674bfc86ceSHeiko Carstens
968b5510d9bSHendrik Brueckner/*
969b5510d9bSHendrik Brueckner * Store floating-point controls and floating-point or vector register
970b5510d9bSHendrik Brueckner * depending whether the vector facility is available.	A critical section
971b5510d9bSHendrik Brueckner * cleanup assures that the registers are stored even if interrupted for
972b5510d9bSHendrik Brueckner * some other work.  The CIF_FPU flag is set to trigger a lazy restore
973b5510d9bSHendrik Brueckner * of the register contents at return from io or a system call.
9749977e886SHendrik Brueckner */
9759977e886SHendrik BruecknerENTRY(save_fpu_regs)
976d0164ee2SHendrik Brueckner	lg	%r2,__LC_CURRENT
977d0164ee2SHendrik Brueckner	aghi	%r2,__TASK_thread
97883abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
979f19fbd5eSMartin Schwidefsky	jo	.Lsave_fpu_regs_exit
980d0164ee2SHendrik Brueckner	stfpc	__THREAD_FPU_fpc(%r2)
981d0164ee2SHendrik Brueckner	lg	%r3,__THREAD_FPU_regs(%r2)
98283abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
9839977e886SHendrik Brueckner	jz	.Lsave_fpu_regs_fp	  # no -> store FP regs
9849977e886SHendrik Brueckner	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
9859977e886SHendrik Brueckner	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
9869977e886SHendrik Brueckner	j	.Lsave_fpu_regs_done	  # -> set CIF_FPU flag
9879977e886SHendrik Brueckner.Lsave_fpu_regs_fp:
9889977e886SHendrik Brueckner	std	0,0(%r3)
9899977e886SHendrik Brueckner	std	1,8(%r3)
9909977e886SHendrik Brueckner	std	2,16(%r3)
9919977e886SHendrik Brueckner	std	3,24(%r3)
9929977e886SHendrik Brueckner	std	4,32(%r3)
9939977e886SHendrik Brueckner	std	5,40(%r3)
9949977e886SHendrik Brueckner	std	6,48(%r3)
9959977e886SHendrik Brueckner	std	7,56(%r3)
9969977e886SHendrik Brueckner	std	8,64(%r3)
9979977e886SHendrik Brueckner	std	9,72(%r3)
9989977e886SHendrik Brueckner	std	10,80(%r3)
9999977e886SHendrik Brueckner	std	11,88(%r3)
10009977e886SHendrik Brueckner	std	12,96(%r3)
10019977e886SHendrik Brueckner	std	13,104(%r3)
10029977e886SHendrik Brueckner	std	14,112(%r3)
10039977e886SHendrik Brueckner	std	15,120(%r3)
10049977e886SHendrik Brueckner.Lsave_fpu_regs_done:
10059977e886SHendrik Brueckner	oi	__LC_CPU_FLAGS+7,_CIF_FPU
1006f19fbd5eSMartin Schwidefsky.Lsave_fpu_regs_exit:
1007*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
10089977e886SHendrik Brueckner.Lsave_fpu_regs_end:
1009711f5df7SAl ViroEXPORT_SYMBOL(save_fpu_regs)
10109977e886SHendrik Brueckner
1011b5510d9bSHendrik Brueckner/*
1012b5510d9bSHendrik Brueckner * Load floating-point controls and floating-point or vector registers.
1013b5510d9bSHendrik Brueckner * A critical section cleanup assures that the register contents are
1014b5510d9bSHendrik Brueckner * loaded even if interrupted for some other work.
10159977e886SHendrik Brueckner *
10169977e886SHendrik Brueckner * There are special calling conventions to fit into sysc and io return work:
10179977e886SHendrik Brueckner *	%r15:	<kernel stack>
10189977e886SHendrik Brueckner * The function requires:
1019b5510d9bSHendrik Brueckner *	%r4
10209977e886SHendrik Brueckner */
10219977e886SHendrik Bruecknerload_fpu_regs:
1022d0164ee2SHendrik Brueckner	lg	%r4,__LC_CURRENT
1023d0164ee2SHendrik Brueckner	aghi	%r4,__TASK_thread
102483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1025f19fbd5eSMartin Schwidefsky	jno	.Lload_fpu_regs_exit
1026d0164ee2SHendrik Brueckner	lfpc	__THREAD_FPU_fpc(%r4)
102783abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
1028d0164ee2SHendrik Brueckner	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
1029b5510d9bSHendrik Brueckner	jz	.Lload_fpu_regs_fp		# -> no VX, load FP regs
10309977e886SHendrik Brueckner	VLM	%v0,%v15,0,%r4
10319977e886SHendrik Brueckner	VLM	%v16,%v31,256,%r4
10329977e886SHendrik Brueckner	j	.Lload_fpu_regs_done
10339977e886SHendrik Brueckner.Lload_fpu_regs_fp:
10349977e886SHendrik Brueckner	ld	0,0(%r4)
10359977e886SHendrik Brueckner	ld	1,8(%r4)
10369977e886SHendrik Brueckner	ld	2,16(%r4)
10379977e886SHendrik Brueckner	ld	3,24(%r4)
10389977e886SHendrik Brueckner	ld	4,32(%r4)
10399977e886SHendrik Brueckner	ld	5,40(%r4)
10409977e886SHendrik Brueckner	ld	6,48(%r4)
10419977e886SHendrik Brueckner	ld	7,56(%r4)
10429977e886SHendrik Brueckner	ld	8,64(%r4)
10439977e886SHendrik Brueckner	ld	9,72(%r4)
10449977e886SHendrik Brueckner	ld	10,80(%r4)
10459977e886SHendrik Brueckner	ld	11,88(%r4)
10469977e886SHendrik Brueckner	ld	12,96(%r4)
10479977e886SHendrik Brueckner	ld	13,104(%r4)
10489977e886SHendrik Brueckner	ld	14,112(%r4)
10499977e886SHendrik Brueckner	ld	15,120(%r4)
10509977e886SHendrik Brueckner.Lload_fpu_regs_done:
10519977e886SHendrik Brueckner	ni	__LC_CPU_FLAGS+7,255-_CIF_FPU
1052f19fbd5eSMartin Schwidefsky.Lload_fpu_regs_exit:
1053*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
10549977e886SHendrik Brueckner.Lload_fpu_regs_end:
10559977e886SHendrik Brueckner
10564bfc86ceSHeiko Carstens.L__critical_end:
10574bfc86ceSHeiko Carstens
10584bfc86ceSHeiko Carstens/*
10594bfc86ceSHeiko Carstens * Machine check handler routines
10604bfc86ceSHeiko Carstens */
10614bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
10624bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
1063d768bd89SMartin Schwidefsky	BPOFF
10643037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
10653037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
10663037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
10673037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
10683037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
1069d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
10709977e886SHendrik Brueckner	larl	%r13,cleanup_critical
10714bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
107283abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
10734bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
10743037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
10753037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
10763037a52fSMartin Schwidefsky	la	%r14,4095
10773037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
10783037a52fSMartin Schwidefsky	ptlb
10792a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
10803037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
10813037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
10823037a52fSMartin Schwidefsky	jno	0f
10833037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
10843037a52fSMartin Schwidefsky	jno	0f
10853037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
10863037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
10873037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
10883037a52fSMartin Schwidefsky	jo	0f
10893037a52fSMartin Schwidefsky	sr	%r14,%r14
10903037a52fSMartin Schwidefsky0:	sfpc	%r14
10913037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
10923037a52fSMartin Schwidefsky	jo	0f
10933037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
10943037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
10953037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
10963037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
10973037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
10983037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
10993037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
11003037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
11013037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
11023037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
11033037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
11043037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
11053037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
11063037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
11073037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
11083037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
11093037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
11103037a52fSMartin Schwidefsky	j	1f
11113037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
11123037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
11133037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
11144bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
111583abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
11164bfc86ceSHeiko Carstens	jo	3f
11174bfc86ceSHeiko Carstens	la	%r14,__LC_SYNC_ENTER_TIMER
11184bfc86ceSHeiko Carstens	clc	0(8,%r14),__LC_ASYNC_ENTER_TIMER
11194bfc86ceSHeiko Carstens	jl	0f
11204bfc86ceSHeiko Carstens	la	%r14,__LC_ASYNC_ENTER_TIMER
11214bfc86ceSHeiko Carstens0:	clc	0(8,%r14),__LC_EXIT_TIMER
11224bfc86ceSHeiko Carstens	jl	1f
11234bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
11244bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
11254bfc86ceSHeiko Carstens	jl	2f
11264bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
11274bfc86ceSHeiko Carstens2:	spt	0(%r14)
11284bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
11293037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
11303037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11313037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
11323037a52fSMartin Schwidefsky	jnz	4f
11333037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
11343037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11353037a52fSMartin Schwidefsky4:	SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
11364bfc86ceSHeiko Carstens.Lmcck_skip:
11374bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
11384bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
11397041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
11407041d281SMartin Schwidefsky	xgr	%r0,%r0
11417041d281SMartin Schwidefsky	xgr	%r1,%r1
11427041d281SMartin Schwidefsky	xgr	%r2,%r2
11437041d281SMartin Schwidefsky	xgr	%r3,%r3
11447041d281SMartin Schwidefsky	xgr	%r4,%r4
11457041d281SMartin Schwidefsky	xgr	%r5,%r5
11467041d281SMartin Schwidefsky	xgr	%r6,%r6
11477041d281SMartin Schwidefsky	xgr	%r7,%r7
11487041d281SMartin Schwidefsky	xgr	%r10,%r10
11494bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
11504bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
11514bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
11524bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
11534bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
11544bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
11554bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
11564bfc86ceSHeiko Carstens	jno	.Lmcck_return
11574bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
11584bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
11594bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
11604bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
11614bfc86ceSHeiko Carstens	lgr	%r15,%r1
11624bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
116383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
11644bfc86ceSHeiko Carstens	jno	.Lmcck_return
11654bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
11664bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
11674bfc86ceSHeiko Carstens	TRACE_IRQS_ON
11684bfc86ceSHeiko Carstens.Lmcck_return:
11694bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
11704bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
11714bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
11724bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
11734bfc86ceSHeiko Carstens	jno	0f
11746b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
11754bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
11764bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
11774bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
11784bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_MCCK_PSW
11794bfc86ceSHeiko Carstens
11804bfc86ceSHeiko Carstens.Lmcck_panic:
11814bfc86ceSHeiko Carstens	lg	%r15,__LC_PANIC_STACK
1182ce4dda3fSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
11834bfc86ceSHeiko Carstens	j	.Lmcck_skip
11844bfc86ceSHeiko Carstens
11854bfc86ceSHeiko Carstens#
11864bfc86ceSHeiko Carstens# PSW restart interrupt handler
11874bfc86ceSHeiko Carstens#
11884bfc86ceSHeiko CarstensENTRY(restart_int_handler)
1189e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
1190e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
11914bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
11924bfc86ceSHeiko Carstens	aghi	%r15,-__PT_SIZE			# create pt_regs on stack
11934bfc86ceSHeiko Carstens	xc	0(__PT_SIZE,%r15),0(%r15)
11944bfc86ceSHeiko Carstens	stmg	%r0,%r14,__PT_R0(%r15)
11954bfc86ceSHeiko Carstens	mvc	__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
11964bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
11974bfc86ceSHeiko Carstens	aghi	%r15,-STACK_FRAME_OVERHEAD	# create stack frame on stack
11984bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
11994bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
12004bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
12014bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
12024bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
12034bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
12044bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
12054bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
12064bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
12074bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
12084bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
12094bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
12104bfc86ceSHeiko Carstens	brc	2,2b
12114bfc86ceSHeiko Carstens3:	j	3b
12124bfc86ceSHeiko Carstens
12134bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
12144bfc86ceSHeiko Carstens
12154bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
12164bfc86ceSHeiko Carstens/*
12174bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
12184bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
12194bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
12204bfc86ceSHeiko Carstens */
12214bfc86ceSHeiko Carstensstack_overflow:
12224bfc86ceSHeiko Carstens	lg	%r15,__LC_PANIC_STACK	# change to panic stack
12234bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12244bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
12254bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12264bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12274bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
12284bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12294bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12304bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
12314bfc86ceSHeiko Carstens#endif
12324bfc86ceSHeiko Carstens
12334bfc86ceSHeiko Carstenscleanup_critical:
1234d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1235d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie)	# .Lsie_gmap
1236d0fc4107SMartin Schwidefsky	jl	0f
1237d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie+8)# .Lsie_done
1238d0fc4107SMartin Schwidefsky	jl	.Lcleanup_sie
1239d0fc4107SMartin Schwidefsky#endif
12404bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table)	# system_call
12414bfc86ceSHeiko Carstens	jl	0f
12424bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+8)	# .Lsysc_do_svc
12434bfc86ceSHeiko Carstens	jl	.Lcleanup_system_call
12444bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+16)	# .Lsysc_tif
12454bfc86ceSHeiko Carstens	jl	0f
12464bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+24)	# .Lsysc_restore
12474bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_tif
12484bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+32)	# .Lsysc_done
12494bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_restore
12504bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+40)	# .Lio_tif
12514bfc86ceSHeiko Carstens	jl	0f
12524bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+48)	# .Lio_restore
12534bfc86ceSHeiko Carstens	jl	.Lcleanup_io_tif
12544bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+56)	# .Lio_done
12554bfc86ceSHeiko Carstens	jl	.Lcleanup_io_restore
12564bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+64)	# psw_idle
12574bfc86ceSHeiko Carstens	jl	0f
12584bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+72)	# .Lpsw_idle_end
12594bfc86ceSHeiko Carstens	jl	.Lcleanup_idle
12609977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+80)	# save_fpu_regs
12619977e886SHendrik Brueckner	jl	0f
12629977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+88)	# .Lsave_fpu_regs_end
12639977e886SHendrik Brueckner	jl	.Lcleanup_save_fpu_regs
12649977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+96)	# load_fpu_regs
12659977e886SHendrik Brueckner	jl	0f
12669977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+104)	# .Lload_fpu_regs_end
12679977e886SHendrik Brueckner	jl	.Lcleanup_load_fpu_regs
1268*6dd85fbbSMartin Schwidefsky0:	BR_EX	%r14
12694bfc86ceSHeiko Carstens
1270d0fc4107SMartin Schwidefsky	.align	8
1271d0fc4107SMartin Schwidefsky.Lcleanup_table:
1272d0fc4107SMartin Schwidefsky	.quad	system_call
1273d0fc4107SMartin Schwidefsky	.quad	.Lsysc_do_svc
1274d0fc4107SMartin Schwidefsky	.quad	.Lsysc_tif
1275d0fc4107SMartin Schwidefsky	.quad	.Lsysc_restore
1276d0fc4107SMartin Schwidefsky	.quad	.Lsysc_done
1277d0fc4107SMartin Schwidefsky	.quad	.Lio_tif
1278d0fc4107SMartin Schwidefsky	.quad	.Lio_restore
1279d0fc4107SMartin Schwidefsky	.quad	.Lio_done
1280d0fc4107SMartin Schwidefsky	.quad	psw_idle
1281d0fc4107SMartin Schwidefsky	.quad	.Lpsw_idle_end
1282d0fc4107SMartin Schwidefsky	.quad	save_fpu_regs
1283d0fc4107SMartin Schwidefsky	.quad	.Lsave_fpu_regs_end
1284d0fc4107SMartin Schwidefsky	.quad	load_fpu_regs
1285d0fc4107SMartin Schwidefsky	.quad	.Lload_fpu_regs_end
1286d0fc4107SMartin Schwidefsky
1287d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1288d0fc4107SMartin Schwidefsky.Lcleanup_table_sie:
1289d0fc4107SMartin Schwidefsky	.quad	.Lsie_gmap
1290d0fc4107SMartin Schwidefsky	.quad	.Lsie_done
1291d0fc4107SMartin Schwidefsky
1292d0fc4107SMartin Schwidefsky.Lcleanup_sie:
1293c929500dSQingFeng Hao	cghi    %r11,__LC_SAVE_AREA_ASYNC 	#Is this in normal interrupt?
1294c929500dSQingFeng Hao	je      1f
1295c929500dSQingFeng Hao	slg     %r9,BASED(.Lsie_crit_mcck_start)
1296c929500dSQingFeng Hao	clg     %r9,BASED(.Lsie_crit_mcck_length)
1297c929500dSQingFeng Hao	jh      1f
1298c929500dSQingFeng Hao	oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
129992fa7a13SMartin Schwidefsky1:	BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
130092fa7a13SMartin Schwidefsky	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
1301e22cf8caSChristian Borntraeger	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
1302d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
1303d0fc4107SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
1304*6dd85fbbSMartin Schwidefsky	BR_EX	%r14
1305d0fc4107SMartin Schwidefsky#endif
13064bfc86ceSHeiko Carstens
13074bfc86ceSHeiko Carstens.Lcleanup_system_call:
13084bfc86ceSHeiko Carstens	# check if stpt has been executed
13094bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn)
13104bfc86ceSHeiko Carstens	jh	0f
13114bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
13124bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
13134bfc86ceSHeiko Carstens	je	0f
13144bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
13154bfc86ceSHeiko Carstens0:	# check if stmg has been executed
13164bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+8)
13174bfc86ceSHeiko Carstens	jh	0f
13184bfc86ceSHeiko Carstens	mvc	__LC_SAVE_AREA_SYNC(64),0(%r11)
13194bfc86ceSHeiko Carstens0:	# check if base register setup + TIF bit load has been done
13204bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+16)
13214bfc86ceSHeiko Carstens	jhe	0f
132234525e1fSMartin Schwidefsky	# set up saved register r12 task struct pointer
132334525e1fSMartin Schwidefsky	stg	%r12,32(%r11)
132434525e1fSMartin Schwidefsky	# set up saved register r13 __TASK_thread offset
132534525e1fSMartin Schwidefsky	mvc	40(8,%r11),BASED(.Lcleanup_system_call_const)
13264bfc86ceSHeiko Carstens0:	# check if the user time update has been done
13274bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+24)
13284bfc86ceSHeiko Carstens	jh	0f
13294bfc86ceSHeiko Carstens	lg	%r15,__LC_EXIT_TIMER
13304bfc86ceSHeiko Carstens	slg	%r15,__LC_SYNC_ENTER_TIMER
13314bfc86ceSHeiko Carstens	alg	%r15,__LC_USER_TIMER
13324bfc86ceSHeiko Carstens	stg	%r15,__LC_USER_TIMER
13334bfc86ceSHeiko Carstens0:	# check if the system time update has been done
13344bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+32)
13354bfc86ceSHeiko Carstens	jh	0f
13364bfc86ceSHeiko Carstens	lg	%r15,__LC_LAST_UPDATE_TIMER
13374bfc86ceSHeiko Carstens	slg	%r15,__LC_EXIT_TIMER
13384bfc86ceSHeiko Carstens	alg	%r15,__LC_SYSTEM_TIMER
13394bfc86ceSHeiko Carstens	stg	%r15,__LC_SYSTEM_TIMER
13404bfc86ceSHeiko Carstens0:	# update accounting time stamp
13414bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
1342d5feec04SMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
134334525e1fSMartin Schwidefsky	# set up saved register r11
13444bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
13454bfc86ceSHeiko Carstens	la	%r9,STACK_FRAME_OVERHEAD(%r15)
13464bfc86ceSHeiko Carstens	stg	%r9,24(%r11)		# r11 pt_regs pointer
13474bfc86ceSHeiko Carstens	# fill pt_regs
13484bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r9),__LC_SAVE_AREA_SYNC
13494bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r9)
13504bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r9),__LC_SVC_OLD_PSW
13514bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r9),__LC_SVC_ILC
13524bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r9),__PT_FLAGS(%r9)
13534bfc86ceSHeiko Carstens	mvi	__PT_FLAGS+7(%r9),_PIF_SYSCALL
13544bfc86ceSHeiko Carstens	# setup saved register r15
13554bfc86ceSHeiko Carstens	stg	%r15,56(%r11)		# r15 stack pointer
13564bfc86ceSHeiko Carstens	# set new psw address and exit
13574bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_do_svc
1358*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
13594bfc86ceSHeiko Carstens.Lcleanup_system_call_insn:
13604bfc86ceSHeiko Carstens	.quad	system_call
13614bfc86ceSHeiko Carstens	.quad	.Lsysc_stmg
13624bfc86ceSHeiko Carstens	.quad	.Lsysc_per
1363a359bb11SMartin Schwidefsky	.quad	.Lsysc_vtime+36
13644bfc86ceSHeiko Carstens	.quad	.Lsysc_vtime+42
136534525e1fSMartin Schwidefsky.Lcleanup_system_call_const:
136634525e1fSMartin Schwidefsky	.quad	__TASK_thread
13674bfc86ceSHeiko Carstens
13684bfc86ceSHeiko Carstens.Lcleanup_sysc_tif:
13694bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_tif
1370*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
13714bfc86ceSHeiko Carstens
13724bfc86ceSHeiko Carstens.Lcleanup_sysc_restore:
137307a63cbeSMartin Schwidefsky	# check if stpt has been executed
13744bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_sysc_restore_insn)
137507a63cbeSMartin Schwidefsky	jh	0f
137607a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
137707a63cbeSMartin Schwidefsky	cghi	%r11,__LC_SAVE_AREA_ASYNC
13784bfc86ceSHeiko Carstens	je	0f
137907a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
138007a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_sysc_restore_insn+8)
138107a63cbeSMartin Schwidefsky	je	1f
13824bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved pointer to pt_regs
13834bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
13844bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
13854bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
138607a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
1387*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
13884bfc86ceSHeiko Carstens.Lcleanup_sysc_restore_insn:
138907a63cbeSMartin Schwidefsky	.quad	.Lsysc_exit_timer
13904bfc86ceSHeiko Carstens	.quad	.Lsysc_done - 4
13914bfc86ceSHeiko Carstens
13924bfc86ceSHeiko Carstens.Lcleanup_io_tif:
13934bfc86ceSHeiko Carstens	larl	%r9,.Lio_tif
1394*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
13954bfc86ceSHeiko Carstens
13964bfc86ceSHeiko Carstens.Lcleanup_io_restore:
139707a63cbeSMartin Schwidefsky	# check if stpt has been executed
13984bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_io_restore_insn)
139907a63cbeSMartin Schwidefsky	jh	0f
140007a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
140107a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_io_restore_insn+8)
140207a63cbeSMartin Schwidefsky	je	1f
14034bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved r11 pointer to pt_regs
14044bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14054bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14064bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
140707a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
1408*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14094bfc86ceSHeiko Carstens.Lcleanup_io_restore_insn:
141007a63cbeSMartin Schwidefsky	.quad	.Lio_exit_timer
14114bfc86ceSHeiko Carstens	.quad	.Lio_done - 4
14124bfc86ceSHeiko Carstens
14134bfc86ceSHeiko Carstens.Lcleanup_idle:
1414419123f9SMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
14154bfc86ceSHeiko Carstens	# copy interrupt clock & cpu timer
14164bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
14174bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
14184bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
14194bfc86ceSHeiko Carstens	je	0f
14204bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
14214bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
14224bfc86ceSHeiko Carstens0:	# check if stck & stpt have been executed
14234bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_idle_insn)
14244bfc86ceSHeiko Carstens	jhe	1f
14254bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
14264bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2)
142772d38b19SMartin Schwidefsky1:	# calculate idle cycles
142872d38b19SMartin Schwidefsky#ifdef CONFIG_SMP
142972d38b19SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_idle_insn)
143072d38b19SMartin Schwidefsky	jl	3f
143172d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
143272d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
143372d38b19SMartin Schwidefsky	ltgr	%r1,%r1
143472d38b19SMartin Schwidefsky	jz	3f
143572d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+80(%r15)
143672d38b19SMartin Schwidefsky	larl	%r3,mt_cycles
143772d38b19SMartin Schwidefsky	ag	%r3,__LC_PERCPU_OFFSET
143872d38b19SMartin Schwidefsky	la	%r4,__SF_EMPTY+16(%r15)
143972d38b19SMartin Schwidefsky2:	lg	%r0,0(%r3)
144072d38b19SMartin Schwidefsky	slg	%r0,0(%r4)
144172d38b19SMartin Schwidefsky	alg	%r0,64(%r4)
144272d38b19SMartin Schwidefsky	stg	%r0,0(%r3)
144372d38b19SMartin Schwidefsky	la	%r3,8(%r3)
144472d38b19SMartin Schwidefsky	la	%r4,8(%r4)
144572d38b19SMartin Schwidefsky	brct	%r1,2b
144672d38b19SMartin Schwidefsky#endif
144772d38b19SMartin Schwidefsky3:	# account system time going idle
14484bfc86ceSHeiko Carstens	lg	%r9,__LC_STEAL_TIMER
14494bfc86ceSHeiko Carstens	alg	%r9,__CLOCK_IDLE_ENTER(%r2)
14504bfc86ceSHeiko Carstens	slg	%r9,__LC_LAST_UPDATE_CLOCK
14514bfc86ceSHeiko Carstens	stg	%r9,__LC_STEAL_TIMER
14524bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2)
14534bfc86ceSHeiko Carstens	lg	%r9,__LC_SYSTEM_TIMER
14544bfc86ceSHeiko Carstens	alg	%r9,__LC_LAST_UPDATE_TIMER
14554bfc86ceSHeiko Carstens	slg	%r9,__TIMER_IDLE_ENTER(%r2)
14564bfc86ceSHeiko Carstens	stg	%r9,__LC_SYSTEM_TIMER
14574bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
14584bfc86ceSHeiko Carstens	# prepare return psw
14594bfc86ceSHeiko Carstens	nihh	%r8,0xfcfd		# clear irq & wait state bits
14604bfc86ceSHeiko Carstens	lg	%r9,48(%r11)		# return from psw_idle
1461*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14624bfc86ceSHeiko Carstens.Lcleanup_idle_insn:
14634bfc86ceSHeiko Carstens	.quad	.Lpsw_idle_lpsw
14644bfc86ceSHeiko Carstens
14659977e886SHendrik Brueckner.Lcleanup_save_fpu_regs:
1466e370e476SMartin Schwidefsky	larl	%r9,save_fpu_regs
1467*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14689977e886SHendrik Brueckner
14699977e886SHendrik Brueckner.Lcleanup_load_fpu_regs:
1470e370e476SMartin Schwidefsky	larl	%r9,load_fpu_regs
1471*6dd85fbbSMartin Schwidefsky	BR_EX	%r14,%r11
14729977e886SHendrik Brueckner
14734bfc86ceSHeiko Carstens/*
14744bfc86ceSHeiko Carstens * Integer constants
14754bfc86ceSHeiko Carstens */
14764bfc86ceSHeiko Carstens	.align	8
14774bfc86ceSHeiko Carstens.Lcritical_start:
14784bfc86ceSHeiko Carstens	.quad	.L__critical_start
14794bfc86ceSHeiko Carstens.Lcritical_length:
14804bfc86ceSHeiko Carstens	.quad	.L__critical_end - .L__critical_start
14814bfc86ceSHeiko Carstens#if IS_ENABLED(CONFIG_KVM)
1482d0fc4107SMartin Schwidefsky.Lsie_critical_start:
14834bfc86ceSHeiko Carstens	.quad	.Lsie_gmap
14844bfc86ceSHeiko Carstens.Lsie_critical_length:
14854bfc86ceSHeiko Carstens	.quad	.Lsie_done - .Lsie_gmap
1486c929500dSQingFeng Hao.Lsie_crit_mcck_start:
1487c929500dSQingFeng Hao	.quad   .Lsie_entry
1488c929500dSQingFeng Hao.Lsie_crit_mcck_length:
1489c929500dSQingFeng Hao	.quad   .Lsie_skip - .Lsie_entry
14904bfc86ceSHeiko Carstens#endif
14914bfc86ceSHeiko Carstens	.section .rodata, "a"
1492a876cb3fSHeiko Carstens#define SYSCALL(esame,emu)	.long esame
14934bfc86ceSHeiko Carstens	.globl	sys_call_table
14944bfc86ceSHeiko Carstenssys_call_table:
14954381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
14964bfc86ceSHeiko Carstens#undef SYSCALL
14974bfc86ceSHeiko Carstens
14984bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
14994bfc86ceSHeiko Carstens
1500a876cb3fSHeiko Carstens#define SYSCALL(esame,emu)	.long emu
15014bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
15024bfc86ceSHeiko Carstenssys_call_table_emu:
15034381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15044bfc86ceSHeiko Carstens#undef SYSCALL
15054bfc86ceSHeiko Carstens#endif
1506