xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 92fa7a13c845c91f6a8177250474bbcab7fcf45e)
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>
314bfc86ceSHeiko Carstens
324bfc86ceSHeiko Carstens__PT_R0      =	__PT_GPRS
334bfc86ceSHeiko Carstens__PT_R1      =	__PT_GPRS + 8
344bfc86ceSHeiko Carstens__PT_R2      =	__PT_GPRS + 16
354bfc86ceSHeiko Carstens__PT_R3      =	__PT_GPRS + 24
364bfc86ceSHeiko Carstens__PT_R4      =	__PT_GPRS + 32
374bfc86ceSHeiko Carstens__PT_R5      =	__PT_GPRS + 40
384bfc86ceSHeiko Carstens__PT_R6      =	__PT_GPRS + 48
394bfc86ceSHeiko Carstens__PT_R7      =	__PT_GPRS + 56
404bfc86ceSHeiko Carstens__PT_R8      =	__PT_GPRS + 64
414bfc86ceSHeiko Carstens__PT_R9      =	__PT_GPRS + 72
424bfc86ceSHeiko Carstens__PT_R10     =	__PT_GPRS + 80
434bfc86ceSHeiko Carstens__PT_R11     =	__PT_GPRS + 88
444bfc86ceSHeiko Carstens__PT_R12     =	__PT_GPRS + 96
454bfc86ceSHeiko Carstens__PT_R13     =	__PT_GPRS + 104
464bfc86ceSHeiko Carstens__PT_R14     =	__PT_GPRS + 112
474bfc86ceSHeiko Carstens__PT_R15     =	__PT_GPRS + 120
484bfc86ceSHeiko Carstens
493a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER
504bfc86ceSHeiko CarstensSTACK_SIZE  = 1 << STACK_SHIFT
514bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
524bfc86ceSHeiko Carstens
534bfc86ceSHeiko Carstens_TIF_WORK	= (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
5476f1948aSLinus Torvalds		   _TIF_UPROBE | _TIF_GUARDED_STORAGE | _TIF_PATCH_PENDING)
554bfc86ceSHeiko Carstens_TIF_TRACE	= (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
564bfc86ceSHeiko Carstens		   _TIF_SYSCALL_TRACEPOINT)
57b5a882fcSHeiko Carstens_CIF_WORK	= (_CIF_MCCK_PENDING | _CIF_ASCE_PRIMARY | \
58b5a882fcSHeiko Carstens		   _CIF_ASCE_SECONDARY | _CIF_FPU)
5923fefe11SMartin Schwidefsky_PIF_WORK	= (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
604bfc86ceSHeiko Carstens
61e5b98199SMartin Schwidefsky_LPP_OFFSET	= __LC_LPP
62e5b98199SMartin Schwidefsky
639977e886SHendrik Brueckner#define BASED(name) name-cleanup_critical(%r13)
644bfc86ceSHeiko Carstens
654bfc86ceSHeiko Carstens	.macro	TRACE_IRQS_ON
664bfc86ceSHeiko Carstens#ifdef CONFIG_TRACE_IRQFLAGS
674bfc86ceSHeiko Carstens	basr	%r2,%r0
684bfc86ceSHeiko Carstens	brasl	%r14,trace_hardirqs_on_caller
694bfc86ceSHeiko Carstens#endif
704bfc86ceSHeiko Carstens	.endm
714bfc86ceSHeiko Carstens
724bfc86ceSHeiko Carstens	.macro	TRACE_IRQS_OFF
734bfc86ceSHeiko Carstens#ifdef CONFIG_TRACE_IRQFLAGS
744bfc86ceSHeiko Carstens	basr	%r2,%r0
754bfc86ceSHeiko Carstens	brasl	%r14,trace_hardirqs_off_caller
764bfc86ceSHeiko Carstens#endif
774bfc86ceSHeiko Carstens	.endm
784bfc86ceSHeiko Carstens
794bfc86ceSHeiko Carstens	.macro	LOCKDEP_SYS_EXIT
804bfc86ceSHeiko Carstens#ifdef CONFIG_LOCKDEP
814bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
824bfc86ceSHeiko Carstens	jz	.+10
834bfc86ceSHeiko Carstens	brasl	%r14,lockdep_sys_exit
844bfc86ceSHeiko Carstens#endif
854bfc86ceSHeiko Carstens	.endm
864bfc86ceSHeiko Carstens
874bfc86ceSHeiko Carstens	.macro	CHECK_STACK stacksize,savearea
884bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
894bfc86ceSHeiko Carstens	tml	%r15,\stacksize - CONFIG_STACK_GUARD
904bfc86ceSHeiko Carstens	lghi	%r14,\savearea
914bfc86ceSHeiko Carstens	jz	stack_overflow
924bfc86ceSHeiko Carstens#endif
934bfc86ceSHeiko Carstens	.endm
944bfc86ceSHeiko Carstens
952acb94f4SMartin Schwidefsky	.macro	SWITCH_ASYNC savearea,timer
964bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# interrupting from user ?
974bfc86ceSHeiko Carstens	jnz	1f
984bfc86ceSHeiko Carstens	lgr	%r14,%r9
994bfc86ceSHeiko Carstens	slg	%r14,BASED(.Lcritical_start)
1004bfc86ceSHeiko Carstens	clg	%r14,BASED(.Lcritical_length)
1014bfc86ceSHeiko Carstens	jhe	0f
1024bfc86ceSHeiko Carstens	lghi	%r11,\savearea		# inside critical section, do cleanup
1034bfc86ceSHeiko Carstens	brasl	%r14,cleanup_critical
1044bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# retest problem state after cleanup
1054bfc86ceSHeiko Carstens	jnz	1f
1062acb94f4SMartin Schwidefsky0:	lg	%r14,__LC_ASYNC_STACK	# are we already on the async stack?
1074bfc86ceSHeiko Carstens	slgr	%r14,%r15
1082acb94f4SMartin Schwidefsky	srag	%r14,%r14,STACK_SHIFT
109a359bb11SMartin Schwidefsky	jnz	2f
1102acb94f4SMartin Schwidefsky	CHECK_STACK 1<<STACK_SHIFT,\savearea
1114bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
112a359bb11SMartin Schwidefsky	j	3f
11334525e1fSMartin Schwidefsky1:	UPDATE_VTIME %r14,%r15,\timer
1146b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
1152acb94f4SMartin Schwidefsky2:	lg	%r15,__LC_ASYNC_STACK	# load async stack
116a359bb11SMartin Schwidefsky3:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
1174bfc86ceSHeiko Carstens	.endm
1184bfc86ceSHeiko Carstens
119a359bb11SMartin Schwidefsky	.macro UPDATE_VTIME w1,w2,enter_timer
120a359bb11SMartin Schwidefsky	lg	\w1,__LC_EXIT_TIMER
121a359bb11SMartin Schwidefsky	lg	\w2,__LC_LAST_UPDATE_TIMER
122a359bb11SMartin Schwidefsky	slg	\w1,\enter_timer
123a359bb11SMartin Schwidefsky	slg	\w2,__LC_EXIT_TIMER
124a359bb11SMartin Schwidefsky	alg	\w1,__LC_USER_TIMER
125a359bb11SMartin Schwidefsky	alg	\w2,__LC_SYSTEM_TIMER
126a359bb11SMartin Schwidefsky	stg	\w1,__LC_USER_TIMER
127a359bb11SMartin Schwidefsky	stg	\w2,__LC_SYSTEM_TIMER
1284bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),\enter_timer
1294bfc86ceSHeiko Carstens	.endm
1304bfc86ceSHeiko Carstens
1314bfc86ceSHeiko Carstens	.macro REENABLE_IRQS
1324bfc86ceSHeiko Carstens	stg	%r8,__LC_RETURN_PSW
1334bfc86ceSHeiko Carstens	ni	__LC_RETURN_PSW,0xbf
1344bfc86ceSHeiko Carstens	ssm	__LC_RETURN_PSW
1354bfc86ceSHeiko Carstens	.endm
1364bfc86ceSHeiko Carstens
1374bfc86ceSHeiko Carstens	.macro STCK savearea
1384bfc86ceSHeiko Carstens#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
1394bfc86ceSHeiko Carstens	.insn	s,0xb27c0000,\savearea		# store clock fast
1404bfc86ceSHeiko Carstens#else
1414bfc86ceSHeiko Carstens	.insn	s,0xb2050000,\savearea		# store clock
1424bfc86ceSHeiko Carstens#endif
1434bfc86ceSHeiko Carstens	.endm
1444bfc86ceSHeiko Carstens
14583abeffbSHendrik Brueckner	/*
14683abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
14783abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
14883abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
14983abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
15083abeffbSHendrik Brueckner	 * instruction.
15183abeffbSHendrik Brueckner	 */
15283abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
15383abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
15483abeffbSHendrik Brueckner			.if (\mask & 0xff)
15583abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
15683abeffbSHendrik Brueckner			.endif
15783abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
15883abeffbSHendrik Brueckner			.exitm
15983abeffbSHendrik Brueckner		.endif
16083abeffbSHendrik Brueckner		.ifeq \mask
16183abeffbSHendrik Brueckner			.error "Mask must not be zero"
16283abeffbSHendrik Brueckner		.endif
16383abeffbSHendrik Brueckner		off = \size - \bytepos - 1
16483abeffbSHendrik Brueckner		tm	off+\addr, \mask
16583abeffbSHendrik Brueckner	.endm
16683abeffbSHendrik Brueckner
167d768bd89SMartin Schwidefsky	.macro BPOFF
168b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
169d768bd89SMartin Schwidefsky	.endm
170d768bd89SMartin Schwidefsky
171d768bd89SMartin Schwidefsky	.macro BPON
172b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
173d768bd89SMartin Schwidefsky	.endm
174d768bd89SMartin Schwidefsky
1756b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
176b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
177b058661aSMartin Schwidefsky		    "", 82
1786b73044bSMartin Schwidefsky	.endm
1796b73044bSMartin Schwidefsky
1806b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
1816b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
182b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
183b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
1846b73044bSMartin Schwidefsky	.endm
1856b73044bSMartin Schwidefsky
186f19fbd5eSMartin Schwidefsky#ifdef CONFIG_EXPOLINE
187f19fbd5eSMartin Schwidefsky
188f19fbd5eSMartin Schwidefsky	.macro GEN_BR_THUNK name,reg,tmp
189f19fbd5eSMartin Schwidefsky	.section .text.\name,"axG",@progbits,\name,comdat
190f19fbd5eSMartin Schwidefsky	.globl \name
191f19fbd5eSMartin Schwidefsky	.hidden \name
192f19fbd5eSMartin Schwidefsky	.type \name,@function
193f19fbd5eSMartin Schwidefsky\name:
194dc24b7b4SHendrik Brueckner	CFI_STARTPROC
195f19fbd5eSMartin Schwidefsky#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
196f19fbd5eSMartin Schwidefsky	exrl	0,0f
197f19fbd5eSMartin Schwidefsky#else
198f19fbd5eSMartin Schwidefsky	larl	\tmp,0f
199f19fbd5eSMartin Schwidefsky	ex	0,0(\tmp)
200f19fbd5eSMartin Schwidefsky#endif
201f19fbd5eSMartin Schwidefsky	j	.
202f19fbd5eSMartin Schwidefsky0:	br	\reg
203dc24b7b4SHendrik Brueckner	CFI_ENDPROC
204f19fbd5eSMartin Schwidefsky	.endm
205f19fbd5eSMartin Schwidefsky
206f19fbd5eSMartin Schwidefsky	GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
207f19fbd5eSMartin Schwidefsky	GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1
208f19fbd5eSMartin Schwidefsky	GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11
209f19fbd5eSMartin Schwidefsky
210f19fbd5eSMartin Schwidefsky	.macro BASR_R14_R9
211f19fbd5eSMartin Schwidefsky0:	brasl	%r14,__s390x_indirect_jump_r1use_r9
212f19fbd5eSMartin Schwidefsky	.pushsection .s390_indirect_branches,"a",@progbits
213f19fbd5eSMartin Schwidefsky	.long	0b-.
214f19fbd5eSMartin Schwidefsky	.popsection
215f19fbd5eSMartin Schwidefsky	.endm
216f19fbd5eSMartin Schwidefsky
217f19fbd5eSMartin Schwidefsky	.macro BR_R1USE_R14
218f19fbd5eSMartin Schwidefsky0:	jg	__s390x_indirect_jump_r1use_r14
219f19fbd5eSMartin Schwidefsky	.pushsection .s390_indirect_branches,"a",@progbits
220f19fbd5eSMartin Schwidefsky	.long	0b-.
221f19fbd5eSMartin Schwidefsky	.popsection
222f19fbd5eSMartin Schwidefsky	.endm
223f19fbd5eSMartin Schwidefsky
224f19fbd5eSMartin Schwidefsky	.macro BR_R11USE_R14
225f19fbd5eSMartin Schwidefsky0:	jg	__s390x_indirect_jump_r11use_r14
226f19fbd5eSMartin Schwidefsky	.pushsection .s390_indirect_branches,"a",@progbits
227f19fbd5eSMartin Schwidefsky	.long	0b-.
228f19fbd5eSMartin Schwidefsky	.popsection
229f19fbd5eSMartin Schwidefsky	.endm
230f19fbd5eSMartin Schwidefsky
231f19fbd5eSMartin Schwidefsky#else	/* CONFIG_EXPOLINE */
232f19fbd5eSMartin Schwidefsky
233f19fbd5eSMartin Schwidefsky	.macro BASR_R14_R9
234f19fbd5eSMartin Schwidefsky	basr	%r14,%r9
235f19fbd5eSMartin Schwidefsky	.endm
236f19fbd5eSMartin Schwidefsky
237f19fbd5eSMartin Schwidefsky	.macro BR_R1USE_R14
238f19fbd5eSMartin Schwidefsky	br	%r14
239f19fbd5eSMartin Schwidefsky	.endm
240f19fbd5eSMartin Schwidefsky
241f19fbd5eSMartin Schwidefsky	.macro BR_R11USE_R14
242f19fbd5eSMartin Schwidefsky	br	%r14
243f19fbd5eSMartin Schwidefsky	.endm
244f19fbd5eSMartin Schwidefsky
245f19fbd5eSMartin Schwidefsky#endif /* CONFIG_EXPOLINE */
246f19fbd5eSMartin Schwidefsky
247f19fbd5eSMartin Schwidefsky
2484bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
24946210c44SHeiko Carstens.Ldummy:
25046210c44SHeiko Carstens	/*
25146210c44SHeiko Carstens	 * This nop exists only in order to avoid that __switch_to starts at
25246210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
25346210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
25446210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
25546210c44SHeiko Carstens	 * With the added nop in between the __switch_to symbol is unique
25646210c44SHeiko Carstens	 * again.
25746210c44SHeiko Carstens	 */
25846210c44SHeiko Carstens	nop	0
2594bfc86ceSHeiko Carstens
260d768bd89SMartin SchwidefskyENTRY(__bpon)
261d768bd89SMartin Schwidefsky	.globl __bpon
262d768bd89SMartin Schwidefsky	BPON
263f19fbd5eSMartin Schwidefsky	BR_R1USE_R14
264d768bd89SMartin Schwidefsky
2654bfc86ceSHeiko Carstens/*
2664bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2674bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2684bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2694bfc86ceSHeiko Carstens * Returns:
2704bfc86ceSHeiko Carstens *  gpr2 = prev
2714bfc86ceSHeiko Carstens */
2724bfc86ceSHeiko CarstensENTRY(__switch_to)
2734bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2743241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2753241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2763241d3ebSHeiko Carstens	lg	%r5,0(%r4,%r3)			# start of kernel stack of next
2773241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2784bfc86ceSHeiko Carstens	lgr	%r15,%r5
2794bfc86ceSHeiko Carstens	aghi	%r15,STACK_INIT			# end of kernel stack of next
2804bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2814bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2823241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2833241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2843241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2854bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
286e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
287e5b98199SMartin Schwidefsky	BR_R1USE_R14
2884bfc86ceSHeiko Carstens
2894bfc86ceSHeiko Carstens.L__critical_start:
290d0fc4107SMartin Schwidefsky
291d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
292d0fc4107SMartin Schwidefsky/*
293d0fc4107SMartin Schwidefsky * sie64a calling convention:
294d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
295d0fc4107SMartin Schwidefsky * %r3 guest register save area
296d0fc4107SMartin Schwidefsky */
297d0fc4107SMartin SchwidefskyENTRY(sie64a)
298d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
2996b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
300*92fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
301*92fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
302*92fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
303*92fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
30483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU		# load guest fp/vx registers ?
305d0fc4107SMartin Schwidefsky	jno	.Lsie_load_guest_gprs
306d0fc4107SMartin Schwidefsky	brasl	%r14,load_fpu_regs		# load guest fp/vx regs
307d0fc4107SMartin Schwidefsky.Lsie_load_guest_gprs:
308d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
309d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
310d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
311d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
312d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
313d0fc4107SMartin Schwidefsky.Lsie_gmap:
314*92fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
315d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
316d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
317d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
31883abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
319d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
320*92fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
321c929500dSQingFeng Hao.Lsie_entry:
322d0fc4107SMartin Schwidefsky	sie	0(%r14)
323d768bd89SMartin Schwidefsky.Lsie_exit:
324d768bd89SMartin Schwidefsky	BPOFF
325*92fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
326d0fc4107SMartin Schwidefsky.Lsie_skip:
327d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
328d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
329d0fc4107SMartin Schwidefsky.Lsie_done:
330d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
331c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
332c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
333c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
334c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
335d0fc4107SMartin Schwidefsky# See also .Lcleanup_sie
336c0e7bb38SChristian Borntraeger.Lrewind_pad6:
337c0e7bb38SChristian Borntraeger	nopr	7
338c0e7bb38SChristian Borntraeger.Lrewind_pad4:
339c0e7bb38SChristian Borntraeger	nopr	7
340c0e7bb38SChristian Borntraeger.Lrewind_pad2:
341c0e7bb38SChristian Borntraeger	nopr	7
342d0fc4107SMartin Schwidefsky	.globl sie_exit
343d0fc4107SMartin Schwidefskysie_exit:
344*92fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
345d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
3467041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
3477041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
3487041d281SMartin Schwidefsky	xgr	%r2,%r2
3497041d281SMartin Schwidefsky	xgr	%r3,%r3
3507041d281SMartin Schwidefsky	xgr	%r4,%r4
3517041d281SMartin Schwidefsky	xgr	%r5,%r5
352d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
353*92fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
354f19fbd5eSMartin Schwidefsky	BR_R1USE_R14
355d0fc4107SMartin Schwidefsky.Lsie_fault:
356d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
357*92fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
358d0fc4107SMartin Schwidefsky	j	sie_exit
359d0fc4107SMartin Schwidefsky
360c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
361c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
362c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
363d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
364711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
365711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
366d0fc4107SMartin Schwidefsky#endif
367d0fc4107SMartin Schwidefsky
3684bfc86ceSHeiko Carstens/*
3694bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3704bfc86ceSHeiko Carstens * are executed with interrupts enabled.
3714bfc86ceSHeiko Carstens */
3724bfc86ceSHeiko Carstens
3734bfc86ceSHeiko CarstensENTRY(system_call)
3744bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
3754bfc86ceSHeiko Carstens.Lsysc_stmg:
3764bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
377d768bd89SMartin Schwidefsky	BPOFF
378d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
37934525e1fSMartin Schwidefsky	lghi	%r13,__TASK_thread
3804bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL
3814bfc86ceSHeiko Carstens.Lsysc_per:
3824bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3834bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
384a359bb11SMartin Schwidefsky.Lsysc_vtime:
38534525e1fSMartin Schwidefsky	UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
3866b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3874bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
3887041d281SMartin Schwidefsky	# clear user controlled register to prevent speculative use
3897041d281SMartin Schwidefsky	xgr	%r0,%r0
3904bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3914bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r11),__LC_SVC_OLD_PSW
3924bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_SVC_ILC
3934bfc86ceSHeiko Carstens	stg	%r14,__PT_FLAGS(%r11)
3944bfc86ceSHeiko Carstens.Lsysc_do_svc:
395ef280c85SMartin Schwidefsky	# load address of system call table
396ef280c85SMartin Schwidefsky	lg	%r10,__THREAD_sysc_table(%r13,%r12)
3974bfc86ceSHeiko Carstens	llgh	%r8,__PT_INT_CODE+2(%r11)
3984bfc86ceSHeiko Carstens	slag	%r8,%r8,2			# shift and test for svc 0
3994bfc86ceSHeiko Carstens	jnz	.Lsysc_nr_ok
4004bfc86ceSHeiko Carstens	# svc 0: system call number in %r1
4014bfc86ceSHeiko Carstens	llgfr	%r1,%r1				# clear high word in r1
4024bfc86ceSHeiko Carstens	cghi	%r1,NR_syscalls
4034bfc86ceSHeiko Carstens	jnl	.Lsysc_nr_ok
4044bfc86ceSHeiko Carstens	sth	%r1,__PT_INT_CODE+2(%r11)
4054bfc86ceSHeiko Carstens	slag	%r8,%r1,2
4064bfc86ceSHeiko Carstens.Lsysc_nr_ok:
4074bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
4084bfc86ceSHeiko Carstens	stg	%r2,__PT_ORIG_GPR2(%r11)
4094bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
4104bfc86ceSHeiko Carstens	lgf	%r9,0(%r8,%r10)			# get system call add.
41183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
4124bfc86ceSHeiko Carstens	jnz	.Lsysc_tracesys
413f19fbd5eSMartin Schwidefsky	BASR_R14_R9				# call sys_xxxx
4144bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)		# store return value
4154bfc86ceSHeiko Carstens
4164bfc86ceSHeiko Carstens.Lsysc_return:
4174bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
4184bfc86ceSHeiko Carstens.Lsysc_tif:
41983abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_WORK
4204bfc86ceSHeiko Carstens	jnz	.Lsysc_work
42183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
4224bfc86ceSHeiko Carstens	jnz	.Lsysc_work			# check for work
42383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
4244bfc86ceSHeiko Carstens	jnz	.Lsysc_work
4256b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4264bfc86ceSHeiko Carstens.Lsysc_restore:
4274bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
4284bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
4294bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
43007a63cbeSMartin Schwidefsky.Lsysc_exit_timer:
4314bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4324bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
4334bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
4344bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW
4354bfc86ceSHeiko Carstens.Lsysc_done:
4364bfc86ceSHeiko Carstens
4374bfc86ceSHeiko Carstens#
4384bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
4394bfc86ceSHeiko Carstens#
4404bfc86ceSHeiko Carstens.Lsysc_work:
44183abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
4424bfc86ceSHeiko Carstens	jo	.Lsysc_mcck_pending
44383abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
4444bfc86ceSHeiko Carstens	jo	.Lsysc_reschedule
44523fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
44623fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
4474bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
44883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_UPROBE
4494bfc86ceSHeiko Carstens	jo	.Lsysc_uprobe_notify
4504bfc86ceSHeiko Carstens#endif
451916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
452916cda1aSMartin Schwidefsky	jo	.Lsysc_guarded_storage
45383abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_PER_TRAP
4544bfc86ceSHeiko Carstens	jo	.Lsysc_singlestep
4552f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
4562f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
4572f09ca60SMiroslav Benes	jo	.Lsysc_patch_pending	# handle live patching just before
4582f09ca60SMiroslav Benes					# signals and possible syscall restart
4592f09ca60SMiroslav Benes#endif
46023fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
46123fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
46283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
4634bfc86ceSHeiko Carstens	jo	.Lsysc_sigpending
46483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
4654bfc86ceSHeiko Carstens	jo	.Lsysc_notify_resume
46683abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
4679977e886SHendrik Brueckner	jo	.Lsysc_vxrs
468b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
469b5a882fcSHeiko Carstens	jnz	.Lsysc_asce
4704bfc86ceSHeiko Carstens	j	.Lsysc_return		# beware of critical section cleanup
4714bfc86ceSHeiko Carstens
4724bfc86ceSHeiko Carstens#
4734bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
4744bfc86ceSHeiko Carstens#
4754bfc86ceSHeiko Carstens.Lsysc_reschedule:
4764bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4774bfc86ceSHeiko Carstens	jg	schedule
4784bfc86ceSHeiko Carstens
4794bfc86ceSHeiko Carstens#
4804bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
4814bfc86ceSHeiko Carstens#
4824bfc86ceSHeiko Carstens.Lsysc_mcck_pending:
4834bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4844bfc86ceSHeiko Carstens	jg	s390_handle_mcck	# TIF bit will be cleared by handler
4854bfc86ceSHeiko Carstens
4864bfc86ceSHeiko Carstens#
4870aaba41bSMartin Schwidefsky# _CIF_ASCE_PRIMARY and/or _CIF_ASCE_SECONDARY set, load user space asce
4884bfc86ceSHeiko Carstens#
489b5a882fcSHeiko Carstens.Lsysc_asce:
4900aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
4910aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
4920aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
4930aaba41bSMartin Schwidefsky	jz	.Lsysc_return
4940aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
4950aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
4960aaba41bSMartin Schwidefsky	jnz	.Lsysc_set_fs_fixup
497606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
4984bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
4990aaba41bSMartin Schwidefsky	j	.Lsysc_return
5000aaba41bSMartin Schwidefsky.Lsysc_set_fs_fixup:
5010aaba41bSMartin Schwidefsky#endif
502b5a882fcSHeiko Carstens	larl	%r14,.Lsysc_return
503b5a882fcSHeiko Carstens	jg	set_fs_fixup
5044bfc86ceSHeiko Carstens
5054bfc86ceSHeiko Carstens#
5069977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
5079977e886SHendrik Brueckner#
5089977e886SHendrik Brueckner.Lsysc_vxrs:
5099977e886SHendrik Brueckner	larl	%r14,.Lsysc_return
5109977e886SHendrik Brueckner	jg	load_fpu_regs
5119977e886SHendrik Brueckner
5129977e886SHendrik Brueckner#
5134bfc86ceSHeiko Carstens# _TIF_SIGPENDING is set, call do_signal
5144bfc86ceSHeiko Carstens#
5154bfc86ceSHeiko Carstens.Lsysc_sigpending:
5164bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5174bfc86ceSHeiko Carstens	brasl	%r14,do_signal
51883abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
5194bfc86ceSHeiko Carstens	jno	.Lsysc_return
52057d7f939SMartin Schwidefsky.Lsysc_do_syscall:
52157d7f939SMartin Schwidefsky	lghi	%r13,__TASK_thread
5224bfc86ceSHeiko Carstens	lmg	%r2,%r7,__PT_R2(%r11)	# load svc arguments
52357d7f939SMartin Schwidefsky	lghi	%r1,0			# svc 0 returns -ENOSYS
52457d7f939SMartin Schwidefsky	j	.Lsysc_do_svc
5254bfc86ceSHeiko Carstens
5264bfc86ceSHeiko Carstens#
5274bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME is set, call do_notify_resume
5284bfc86ceSHeiko Carstens#
5294bfc86ceSHeiko Carstens.Lsysc_notify_resume:
5304bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5314bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5324bfc86ceSHeiko Carstens	jg	do_notify_resume
5334bfc86ceSHeiko Carstens
5344bfc86ceSHeiko Carstens#
5354bfc86ceSHeiko Carstens# _TIF_UPROBE is set, call uprobe_notify_resume
5364bfc86ceSHeiko Carstens#
5374bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
5384bfc86ceSHeiko Carstens.Lsysc_uprobe_notify:
5394bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5404bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5414bfc86ceSHeiko Carstens	jg	uprobe_notify_resume
5424bfc86ceSHeiko Carstens#endif
5434bfc86ceSHeiko Carstens
5444bfc86ceSHeiko Carstens#
545916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
546916cda1aSMartin Schwidefsky#
547916cda1aSMartin Schwidefsky.Lsysc_guarded_storage:
548916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
549916cda1aSMartin Schwidefsky	larl	%r14,.Lsysc_return
550916cda1aSMartin Schwidefsky	jg	gs_load_bc_cb
55176f1948aSLinus Torvalds#
5522f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
5532f09ca60SMiroslav Benes#
5542f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
5552f09ca60SMiroslav Benes.Lsysc_patch_pending:
5562f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
5572f09ca60SMiroslav Benes	larl	%r14,.Lsysc_return
5582f09ca60SMiroslav Benes	jg	klp_update_patch_state
5592f09ca60SMiroslav Benes#endif
560916cda1aSMartin Schwidefsky
561916cda1aSMartin Schwidefsky#
5624bfc86ceSHeiko Carstens# _PIF_PER_TRAP is set, call do_per_trap
5634bfc86ceSHeiko Carstens#
5644bfc86ceSHeiko Carstens.Lsysc_singlestep:
5654bfc86ceSHeiko Carstens	ni	__PT_FLAGS+7(%r11),255-_PIF_PER_TRAP
5664bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5674bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5684bfc86ceSHeiko Carstens	jg	do_per_trap
5694bfc86ceSHeiko Carstens
5704bfc86ceSHeiko Carstens#
57123fefe11SMartin Schwidefsky# _PIF_SYSCALL_RESTART is set, repeat the current system call
57223fefe11SMartin Schwidefsky#
57323fefe11SMartin Schwidefsky.Lsysc_syscall_restart:
57423fefe11SMartin Schwidefsky	ni	__PT_FLAGS+7(%r11),255-_PIF_SYSCALL_RESTART
57523fefe11SMartin Schwidefsky	lmg	%r1,%r7,__PT_R1(%r11)	# load svc arguments
57623fefe11SMartin Schwidefsky	lg	%r2,__PT_ORIG_GPR2(%r11)
57723fefe11SMartin Schwidefsky	j	.Lsysc_do_svc
57823fefe11SMartin Schwidefsky
57923fefe11SMartin Schwidefsky#
5804bfc86ceSHeiko Carstens# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
5814bfc86ceSHeiko Carstens# and after the system call
5824bfc86ceSHeiko Carstens#
5834bfc86ceSHeiko Carstens.Lsysc_tracesys:
5844bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5854bfc86ceSHeiko Carstens	la	%r3,0
5864bfc86ceSHeiko Carstens	llgh	%r0,__PT_INT_CODE+2(%r11)
5874bfc86ceSHeiko Carstens	stg	%r0,__PT_R2(%r11)
5884bfc86ceSHeiko Carstens	brasl	%r14,do_syscall_trace_enter
5894bfc86ceSHeiko Carstens	lghi	%r0,NR_syscalls
5904bfc86ceSHeiko Carstens	clgr	%r0,%r2
5914bfc86ceSHeiko Carstens	jnh	.Lsysc_tracenogo
5924bfc86ceSHeiko Carstens	sllg	%r8,%r2,2
5934bfc86ceSHeiko Carstens	lgf	%r9,0(%r8,%r10)
5944bfc86ceSHeiko Carstens.Lsysc_tracego:
5954bfc86ceSHeiko Carstens	lmg	%r3,%r7,__PT_R3(%r11)
5964bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
5974bfc86ceSHeiko Carstens	lg	%r2,__PT_ORIG_GPR2(%r11)
598f19fbd5eSMartin Schwidefsky	BASR_R14_R9			# call sys_xxx
5994bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)	# store return value
6004bfc86ceSHeiko Carstens.Lsysc_tracenogo:
60183abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
6024bfc86ceSHeiko Carstens	jz	.Lsysc_return
6034bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
6044bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
6054bfc86ceSHeiko Carstens	jg	do_syscall_trace_exit
6064bfc86ceSHeiko Carstens
6074bfc86ceSHeiko Carstens#
6084bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
6094bfc86ceSHeiko Carstens#
6104bfc86ceSHeiko CarstensENTRY(ret_from_fork)
6114bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
612d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
6134bfc86ceSHeiko Carstens	brasl	%r14,schedule_tail
6144bfc86ceSHeiko Carstens	TRACE_IRQS_ON
6154bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
6164bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
6174bfc86ceSHeiko Carstens	jne	.Lsysc_tracenogo
6184bfc86ceSHeiko Carstens	# it's a kernel thread
6194bfc86ceSHeiko Carstens	lmg	%r9,%r10,__PT_R9(%r11)	# load gprs
6204bfc86ceSHeiko CarstensENTRY(kernel_thread_starter)
6214bfc86ceSHeiko Carstens	la	%r2,0(%r10)
622f19fbd5eSMartin Schwidefsky	BASR_R14_R9
6234bfc86ceSHeiko Carstens	j	.Lsysc_tracenogo
6244bfc86ceSHeiko Carstens
6254bfc86ceSHeiko Carstens/*
6264bfc86ceSHeiko Carstens * Program check handler routine
6274bfc86ceSHeiko Carstens */
6284bfc86ceSHeiko Carstens
6294bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
6304bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
631d768bd89SMartin Schwidefsky	BPOFF
6324bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
6334bfc86ceSHeiko Carstens	lg	%r10,__LC_LAST_BREAK
634d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
635c771320eSMartin Schwidefsky	lghi	%r11,0
6369977e886SHendrik Brueckner	larl	%r13,cleanup_critical
6374bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
6384bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# test problem state bit
639d0fc4107SMartin Schwidefsky	jnz	2f			# -> fault in user space
640d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
6410a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
642d0fc4107SMartin Schwidefsky	lgr	%r14,%r9
643d0fc4107SMartin Schwidefsky	slg	%r14,BASED(.Lsie_critical_start)
644d0fc4107SMartin Schwidefsky	clg	%r14,BASED(.Lsie_critical_length)
645d0fc4107SMartin Schwidefsky	jhe	0f
646*92fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
6470a5e2ec2SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
6480a5e2ec2SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
6490a5e2ec2SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
650c771320eSMartin Schwidefsky	lghi	%r11,_PIF_GUEST_FAULT
651d0fc4107SMartin Schwidefsky#endif
652d0fc4107SMartin Schwidefsky0:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
653d0fc4107SMartin Schwidefsky	jnz	1f			# -> enabled, can't be a double fault
6544bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
6554bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
656d0fc4107SMartin Schwidefsky1:	CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
6574bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
658d9fcf2a1SMartin Schwidefsky	j	4f
65934525e1fSMartin Schwidefsky2:	UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
6606b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
6614bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
662d5c352cdSHeiko Carstens	lgr	%r14,%r12
6633827ec3dSMartin Schwidefsky	aghi	%r14,__TASK_thread	# pointer to thread_struct
6644bfc86ceSHeiko Carstens	lghi	%r13,__LC_PGM_TDB
6654bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+2,0x02	# check for transaction abort
666d0fc4107SMartin Schwidefsky	jz	3f
6674bfc86ceSHeiko Carstens	mvc	__THREAD_trap_tdb(256,%r14),0(%r13)
668d9fcf2a1SMartin Schwidefsky3:	stg	%r10,__THREAD_last_break(%r14)
669c771320eSMartin Schwidefsky4:	lgr	%r13,%r11
670c771320eSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6714bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6727041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
6737041d281SMartin Schwidefsky	xgr	%r0,%r0
6747041d281SMartin Schwidefsky	xgr	%r1,%r1
6757041d281SMartin Schwidefsky	xgr	%r2,%r2
6767041d281SMartin Schwidefsky	xgr	%r3,%r3
6777041d281SMartin Schwidefsky	xgr	%r4,%r4
6787041d281SMartin Schwidefsky	xgr	%r5,%r5
6797041d281SMartin Schwidefsky	xgr	%r6,%r6
6807041d281SMartin Schwidefsky	xgr	%r7,%r7
6814bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
6824bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6834bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_PGM_ILC
6844bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
685c771320eSMartin Schwidefsky	stg	%r13,__PT_FLAGS(%r11)
6864bfc86ceSHeiko Carstens	stg	%r10,__PT_ARGS(%r11)
6874bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
688d9fcf2a1SMartin Schwidefsky	jz	5f
6894bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# kernel per event ?
6904bfc86ceSHeiko Carstens	jz	.Lpgm_kprobe
6914bfc86ceSHeiko Carstens	oi	__PT_FLAGS+7(%r11),_PIF_PER_TRAP
6924bfc86ceSHeiko Carstens	mvc	__THREAD_per_address(8,%r14),__LC_PER_ADDRESS
6934bfc86ceSHeiko Carstens	mvc	__THREAD_per_cause(2,%r14),__LC_PER_CODE
6944bfc86ceSHeiko Carstens	mvc	__THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
695d9fcf2a1SMartin Schwidefsky5:	REENABLE_IRQS
6964bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6974bfc86ceSHeiko Carstens	larl	%r1,pgm_check_table
6984bfc86ceSHeiko Carstens	llgh	%r10,__PT_INT_CODE+2(%r11)
6994bfc86ceSHeiko Carstens	nill	%r10,0x007f
7004bfc86ceSHeiko Carstens	sll	%r10,2
701a359bb11SMartin Schwidefsky	je	.Lpgm_return
702f19fbd5eSMartin Schwidefsky	lgf	%r9,0(%r10,%r1)		# load address of handler routine
7034bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
704f19fbd5eSMartin Schwidefsky	BASR_R14_R9			# branch to interrupt-handler
705a359bb11SMartin Schwidefsky.Lpgm_return:
706a359bb11SMartin Schwidefsky	LOCKDEP_SYS_EXIT
707a359bb11SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
708a359bb11SMartin Schwidefsky	jno	.Lsysc_restore
70957d7f939SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
71057d7f939SMartin Schwidefsky	jo	.Lsysc_do_syscall
711a359bb11SMartin Schwidefsky	j	.Lsysc_tif
7124bfc86ceSHeiko Carstens
7134bfc86ceSHeiko Carstens#
7144bfc86ceSHeiko Carstens# PER event in supervisor state, must be kprobes
7154bfc86ceSHeiko Carstens#
7164bfc86ceSHeiko Carstens.Lpgm_kprobe:
7174bfc86ceSHeiko Carstens	REENABLE_IRQS
7184bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7194bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7204bfc86ceSHeiko Carstens	brasl	%r14,do_per_trap
721a359bb11SMartin Schwidefsky	j	.Lpgm_return
7224bfc86ceSHeiko Carstens
7234bfc86ceSHeiko Carstens#
7244bfc86ceSHeiko Carstens# single stepped system call
7254bfc86ceSHeiko Carstens#
7264bfc86ceSHeiko Carstens.Lpgm_svcper:
7274bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
728d24b98e3SMartin Schwidefsky	lghi	%r13,__TASK_thread
7294bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
7304bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
7314bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL | _PIF_PER_TRAP
7324bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per and enable irqs
7334bfc86ceSHeiko Carstens
7344bfc86ceSHeiko Carstens/*
7354bfc86ceSHeiko Carstens * IO interrupt handler routine
7364bfc86ceSHeiko Carstens */
7374bfc86ceSHeiko CarstensENTRY(io_int_handler)
7384bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
7394bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
740d768bd89SMartin Schwidefsky	BPOFF
7414bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
742d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
7439977e886SHendrik Brueckner	larl	%r13,cleanup_critical
7444bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_IO_OLD_PSW
7452acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
7464bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
7477041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
7487041d281SMartin Schwidefsky	xgr	%r0,%r0
7497041d281SMartin Schwidefsky	xgr	%r1,%r1
7507041d281SMartin Schwidefsky	xgr	%r2,%r2
7517041d281SMartin Schwidefsky	xgr	%r3,%r3
7527041d281SMartin Schwidefsky	xgr	%r4,%r4
7537041d281SMartin Schwidefsky	xgr	%r5,%r5
7547041d281SMartin Schwidefsky	xgr	%r6,%r6
7557041d281SMartin Schwidefsky	xgr	%r7,%r7
7567041d281SMartin Schwidefsky	xgr	%r10,%r10
7574bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
7584bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
7594bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7604bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
761db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
762db7e007fSHeiko Carstens	jo	.Lio_restore
7634bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
7644bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7654bfc86ceSHeiko Carstens.Lio_loop:
7664bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7674bfc86ceSHeiko Carstens	lghi	%r3,IO_INTERRUPT
7684bfc86ceSHeiko Carstens	tm	__PT_INT_CODE+8(%r11),0x80	# adapter interrupt ?
7694bfc86ceSHeiko Carstens	jz	.Lio_call
7704bfc86ceSHeiko Carstens	lghi	%r3,THIN_INTERRUPT
7714bfc86ceSHeiko Carstens.Lio_call:
7724bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
77383abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
7744bfc86ceSHeiko Carstens	jz	.Lio_return
7754bfc86ceSHeiko Carstens	tpi	0
7764bfc86ceSHeiko Carstens	jz	.Lio_return
7774bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7784bfc86ceSHeiko Carstens	j	.Lio_loop
7794bfc86ceSHeiko Carstens.Lio_return:
7804bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
7814bfc86ceSHeiko Carstens	TRACE_IRQS_ON
7824bfc86ceSHeiko Carstens.Lio_tif:
78383abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
7844bfc86ceSHeiko Carstens	jnz	.Lio_work		# there is work to do (signals etc.)
78583abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
7864bfc86ceSHeiko Carstens	jnz	.Lio_work
7874bfc86ceSHeiko Carstens.Lio_restore:
7884bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
7894bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
7904bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
791d768bd89SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
792d768bd89SMartin Schwidefsky	jno	.Lio_exit_kernel
7936b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
79407a63cbeSMartin Schwidefsky.Lio_exit_timer:
7954bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
7964bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
797d768bd89SMartin Schwidefsky.Lio_exit_kernel:
7984bfc86ceSHeiko Carstens	lmg	%r11,%r15,__PT_R11(%r11)
7994bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_PSW
8004bfc86ceSHeiko Carstens.Lio_done:
8014bfc86ceSHeiko Carstens
8024bfc86ceSHeiko Carstens#
8034bfc86ceSHeiko Carstens# There is work todo, find out in which context we have been interrupted:
8044bfc86ceSHeiko Carstens# 1) if we return to user space we can do all _TIF_WORK work
8054bfc86ceSHeiko Carstens# 2) if we return to kernel code and kvm is enabled check if we need to
8064bfc86ceSHeiko Carstens#    modify the psw to leave SIE
8074bfc86ceSHeiko Carstens# 3) if we return to kernel code and preemptive scheduling is enabled check
8084bfc86ceSHeiko Carstens#    the preemption counter and if it is zero call preempt_schedule_irq
8094bfc86ceSHeiko Carstens# Before any work can be done, a switch to the kernel stack is required.
8104bfc86ceSHeiko Carstens#
8114bfc86ceSHeiko Carstens.Lio_work:
8124bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
8134bfc86ceSHeiko Carstens	jo	.Lio_work_user		# yes -> do resched & signal
8144bfc86ceSHeiko Carstens#ifdef CONFIG_PREEMPT
8154bfc86ceSHeiko Carstens	# check for preemptive scheduling
816c360192bSMartin Schwidefsky	icm	%r0,15,__LC_PREEMPT_COUNT
8174bfc86ceSHeiko Carstens	jnz	.Lio_restore		# preemption is disabled
81883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8194bfc86ceSHeiko Carstens	jno	.Lio_restore
8204bfc86ceSHeiko Carstens	# switch to kernel stack
8214bfc86ceSHeiko Carstens	lg	%r1,__PT_R15(%r11)
8224bfc86ceSHeiko Carstens	aghi	%r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
8234bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8244bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8254bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8264bfc86ceSHeiko Carstens	lgr	%r15,%r1
8274bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return, call
8284bfc86ceSHeiko Carstens	# TRACE_IRQS_OFF to keep things symmetrical
8294bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8304bfc86ceSHeiko Carstens	brasl	%r14,preempt_schedule_irq
8314bfc86ceSHeiko Carstens	j	.Lio_return
8324bfc86ceSHeiko Carstens#else
8334bfc86ceSHeiko Carstens	j	.Lio_restore
8344bfc86ceSHeiko Carstens#endif
8354bfc86ceSHeiko Carstens
8364bfc86ceSHeiko Carstens#
8374bfc86ceSHeiko Carstens# Need to do work before returning to userspace, switch to kernel stack
8384bfc86ceSHeiko Carstens#
8394bfc86ceSHeiko Carstens.Lio_work_user:
8404bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK
8414bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8424bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8434bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8444bfc86ceSHeiko Carstens	lgr	%r15,%r1
8454bfc86ceSHeiko Carstens
8464bfc86ceSHeiko Carstens#
8474bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
8484bfc86ceSHeiko Carstens#
8494bfc86ceSHeiko Carstens.Lio_work_tif:
85083abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
8514bfc86ceSHeiko Carstens	jo	.Lio_mcck_pending
85283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8534bfc86ceSHeiko Carstens	jo	.Lio_reschedule
8542f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
8552f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
8562f09ca60SMiroslav Benes	jo	.Lio_patch_pending
8572f09ca60SMiroslav Benes#endif
85883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
8594bfc86ceSHeiko Carstens	jo	.Lio_sigpending
86083abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
8614bfc86ceSHeiko Carstens	jo	.Lio_notify_resume
862916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
863916cda1aSMartin Schwidefsky	jo	.Lio_guarded_storage
86483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
8659977e886SHendrik Brueckner	jo	.Lio_vxrs
866b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
867b5a882fcSHeiko Carstens	jnz	.Lio_asce
8684bfc86ceSHeiko Carstens	j	.Lio_return		# beware of critical section cleanup
8694bfc86ceSHeiko Carstens
8704bfc86ceSHeiko Carstens#
8714bfc86ceSHeiko Carstens# _CIF_MCCK_PENDING is set, call handler
8724bfc86ceSHeiko Carstens#
8734bfc86ceSHeiko Carstens.Lio_mcck_pending:
8744bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
8754bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck	# TIF bit will be cleared by handler
8764bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
8774bfc86ceSHeiko Carstens	j	.Lio_return
8784bfc86ceSHeiko Carstens
8794bfc86ceSHeiko Carstens#
880b5a882fcSHeiko Carstens# _CIF_ASCE_PRIMARY and/or CIF_ASCE_SECONDARY set, load user space asce
8814bfc86ceSHeiko Carstens#
882b5a882fcSHeiko Carstens.Lio_asce:
8830aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
8840aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
8850aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
8860aaba41bSMartin Schwidefsky	jz	.Lio_return
8870aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
8880aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
8890aaba41bSMartin Schwidefsky	jnz	.Lio_set_fs_fixup
890606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
8914bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
8920aaba41bSMartin Schwidefsky	j	.Lio_return
8930aaba41bSMartin Schwidefsky.Lio_set_fs_fixup:
8940aaba41bSMartin Schwidefsky#endif
895b5a882fcSHeiko Carstens	larl	%r14,.Lio_return
896b5a882fcSHeiko Carstens	jg	set_fs_fixup
8974bfc86ceSHeiko Carstens
8984bfc86ceSHeiko Carstens#
8999977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
9009977e886SHendrik Brueckner#
9019977e886SHendrik Brueckner.Lio_vxrs:
9029977e886SHendrik Brueckner	larl	%r14,.Lio_return
9039977e886SHendrik Brueckner	jg	load_fpu_regs
9049977e886SHendrik Brueckner
9059977e886SHendrik Brueckner#
906916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
907916cda1aSMartin Schwidefsky#
908916cda1aSMartin Schwidefsky.Lio_guarded_storage:
909916cda1aSMartin Schwidefsky	# TRACE_IRQS_ON already done at .Lio_return
910916cda1aSMartin Schwidefsky	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
911916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
912916cda1aSMartin Schwidefsky	brasl	%r14,gs_load_bc_cb
913916cda1aSMartin Schwidefsky	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
914916cda1aSMartin Schwidefsky	TRACE_IRQS_OFF
915916cda1aSMartin Schwidefsky	j	.Lio_return
916916cda1aSMartin Schwidefsky
917916cda1aSMartin Schwidefsky#
9184bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
9194bfc86ceSHeiko Carstens#
9204bfc86ceSHeiko Carstens.Lio_reschedule:
9214bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9224bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9234bfc86ceSHeiko Carstens	brasl	%r14,schedule		# call scheduler
9244bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9254bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9264bfc86ceSHeiko Carstens	j	.Lio_return
9274bfc86ceSHeiko Carstens
9284bfc86ceSHeiko Carstens#
9292f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
9302f09ca60SMiroslav Benes#
9312f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
9322f09ca60SMiroslav Benes.Lio_patch_pending:
9332f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
9342f09ca60SMiroslav Benes	larl	%r14,.Lio_return
9352f09ca60SMiroslav Benes	jg	klp_update_patch_state
9362f09ca60SMiroslav Benes#endif
9372f09ca60SMiroslav Benes
9382f09ca60SMiroslav Benes#
9394bfc86ceSHeiko Carstens# _TIF_SIGPENDING or is set, call do_signal
9404bfc86ceSHeiko Carstens#
9414bfc86ceSHeiko Carstens.Lio_sigpending:
9424bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9434bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9444bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9454bfc86ceSHeiko Carstens	brasl	%r14,do_signal
9464bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9474bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9484bfc86ceSHeiko Carstens	j	.Lio_return
9494bfc86ceSHeiko Carstens
9504bfc86ceSHeiko Carstens#
9514bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
9524bfc86ceSHeiko Carstens#
9534bfc86ceSHeiko Carstens.Lio_notify_resume:
9544bfc86ceSHeiko Carstens	# TRACE_IRQS_ON already done at .Lio_return
9554bfc86ceSHeiko Carstens	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
9564bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9574bfc86ceSHeiko Carstens	brasl	%r14,do_notify_resume
9584bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
9594bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9604bfc86ceSHeiko Carstens	j	.Lio_return
9614bfc86ceSHeiko Carstens
9624bfc86ceSHeiko Carstens/*
9634bfc86ceSHeiko Carstens * External interrupt handler routine
9644bfc86ceSHeiko Carstens */
9654bfc86ceSHeiko CarstensENTRY(ext_int_handler)
9664bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
9674bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
968d768bd89SMartin Schwidefsky	BPOFF
9694bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
970d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
9719977e886SHendrik Brueckner	larl	%r13,cleanup_critical
9724bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_EXT_OLD_PSW
9732acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
9744bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
9757041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
9767041d281SMartin Schwidefsky	xgr	%r0,%r0
9777041d281SMartin Schwidefsky	xgr	%r1,%r1
9787041d281SMartin Schwidefsky	xgr	%r2,%r2
9797041d281SMartin Schwidefsky	xgr	%r3,%r3
9807041d281SMartin Schwidefsky	xgr	%r4,%r4
9817041d281SMartin Schwidefsky	xgr	%r5,%r5
9827041d281SMartin Schwidefsky	xgr	%r6,%r6
9837041d281SMartin Schwidefsky	xgr	%r7,%r7
9847041d281SMartin Schwidefsky	xgr	%r10,%r10
9854bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
9864bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
9874bfc86ceSHeiko Carstens	lghi	%r1,__LC_EXT_PARAMS2
9884bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
9894bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
9904bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),0(%r1)
9914bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
992db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
993db7e007fSHeiko Carstens	jo	.Lio_restore
9944bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9954bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
9964bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9974bfc86ceSHeiko Carstens	lghi	%r3,EXT_INTERRUPT
9984bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
9994bfc86ceSHeiko Carstens	j	.Lio_return
10004bfc86ceSHeiko Carstens
10014bfc86ceSHeiko Carstens/*
10024bfc86ceSHeiko Carstens * Load idle PSW. The second "half" of this function is in .Lcleanup_idle.
10034bfc86ceSHeiko Carstens */
10044bfc86ceSHeiko CarstensENTRY(psw_idle)
10054bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
10064bfc86ceSHeiko Carstens	larl	%r1,.Lpsw_idle_lpsw+4
10074bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
100872d38b19SMartin Schwidefsky#ifdef CONFIG_SMP
100972d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
101072d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
101172d38b19SMartin Schwidefsky	ltgr	%r1,%r1
101272d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
101372d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
101472d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
101572d38b19SMartin Schwidefsky#endif
1016419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
1017d768bd89SMartin Schwidefsky	BPON
10184bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
10194bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
10204bfc86ceSHeiko Carstens.Lpsw_idle_lpsw:
10214bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
1022f19fbd5eSMartin Schwidefsky	BR_R1USE_R14
10234bfc86ceSHeiko Carstens.Lpsw_idle_end:
10244bfc86ceSHeiko Carstens
1025b5510d9bSHendrik Brueckner/*
1026b5510d9bSHendrik Brueckner * Store floating-point controls and floating-point or vector register
1027b5510d9bSHendrik Brueckner * depending whether the vector facility is available.	A critical section
1028b5510d9bSHendrik Brueckner * cleanup assures that the registers are stored even if interrupted for
1029b5510d9bSHendrik Brueckner * some other work.  The CIF_FPU flag is set to trigger a lazy restore
1030b5510d9bSHendrik Brueckner * of the register contents at return from io or a system call.
10319977e886SHendrik Brueckner */
10329977e886SHendrik BruecknerENTRY(save_fpu_regs)
1033d0164ee2SHendrik Brueckner	lg	%r2,__LC_CURRENT
1034d0164ee2SHendrik Brueckner	aghi	%r2,__TASK_thread
103583abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1036f19fbd5eSMartin Schwidefsky	jo	.Lsave_fpu_regs_exit
1037d0164ee2SHendrik Brueckner	stfpc	__THREAD_FPU_fpc(%r2)
1038d0164ee2SHendrik Brueckner	lg	%r3,__THREAD_FPU_regs(%r2)
103983abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
10409977e886SHendrik Brueckner	jz	.Lsave_fpu_regs_fp	  # no -> store FP regs
10419977e886SHendrik Brueckner	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
10429977e886SHendrik Brueckner	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
10439977e886SHendrik Brueckner	j	.Lsave_fpu_regs_done	  # -> set CIF_FPU flag
10449977e886SHendrik Brueckner.Lsave_fpu_regs_fp:
10459977e886SHendrik Brueckner	std	0,0(%r3)
10469977e886SHendrik Brueckner	std	1,8(%r3)
10479977e886SHendrik Brueckner	std	2,16(%r3)
10489977e886SHendrik Brueckner	std	3,24(%r3)
10499977e886SHendrik Brueckner	std	4,32(%r3)
10509977e886SHendrik Brueckner	std	5,40(%r3)
10519977e886SHendrik Brueckner	std	6,48(%r3)
10529977e886SHendrik Brueckner	std	7,56(%r3)
10539977e886SHendrik Brueckner	std	8,64(%r3)
10549977e886SHendrik Brueckner	std	9,72(%r3)
10559977e886SHendrik Brueckner	std	10,80(%r3)
10569977e886SHendrik Brueckner	std	11,88(%r3)
10579977e886SHendrik Brueckner	std	12,96(%r3)
10589977e886SHendrik Brueckner	std	13,104(%r3)
10599977e886SHendrik Brueckner	std	14,112(%r3)
10609977e886SHendrik Brueckner	std	15,120(%r3)
10619977e886SHendrik Brueckner.Lsave_fpu_regs_done:
10629977e886SHendrik Brueckner	oi	__LC_CPU_FLAGS+7,_CIF_FPU
1063f19fbd5eSMartin Schwidefsky.Lsave_fpu_regs_exit:
1064f19fbd5eSMartin Schwidefsky	BR_R1USE_R14
10659977e886SHendrik Brueckner.Lsave_fpu_regs_end:
1066711f5df7SAl ViroEXPORT_SYMBOL(save_fpu_regs)
10679977e886SHendrik Brueckner
1068b5510d9bSHendrik Brueckner/*
1069b5510d9bSHendrik Brueckner * Load floating-point controls and floating-point or vector registers.
1070b5510d9bSHendrik Brueckner * A critical section cleanup assures that the register contents are
1071b5510d9bSHendrik Brueckner * loaded even if interrupted for some other work.
10729977e886SHendrik Brueckner *
10739977e886SHendrik Brueckner * There are special calling conventions to fit into sysc and io return work:
10749977e886SHendrik Brueckner *	%r15:	<kernel stack>
10759977e886SHendrik Brueckner * The function requires:
1076b5510d9bSHendrik Brueckner *	%r4
10779977e886SHendrik Brueckner */
10789977e886SHendrik Bruecknerload_fpu_regs:
1079d0164ee2SHendrik Brueckner	lg	%r4,__LC_CURRENT
1080d0164ee2SHendrik Brueckner	aghi	%r4,__TASK_thread
108183abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1082f19fbd5eSMartin Schwidefsky	jno	.Lload_fpu_regs_exit
1083d0164ee2SHendrik Brueckner	lfpc	__THREAD_FPU_fpc(%r4)
108483abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
1085d0164ee2SHendrik Brueckner	lg	%r4,__THREAD_FPU_regs(%r4)	# %r4 <- reg save area
1086b5510d9bSHendrik Brueckner	jz	.Lload_fpu_regs_fp		# -> no VX, load FP regs
10879977e886SHendrik Brueckner	VLM	%v0,%v15,0,%r4
10889977e886SHendrik Brueckner	VLM	%v16,%v31,256,%r4
10899977e886SHendrik Brueckner	j	.Lload_fpu_regs_done
10909977e886SHendrik Brueckner.Lload_fpu_regs_fp:
10919977e886SHendrik Brueckner	ld	0,0(%r4)
10929977e886SHendrik Brueckner	ld	1,8(%r4)
10939977e886SHendrik Brueckner	ld	2,16(%r4)
10949977e886SHendrik Brueckner	ld	3,24(%r4)
10959977e886SHendrik Brueckner	ld	4,32(%r4)
10969977e886SHendrik Brueckner	ld	5,40(%r4)
10979977e886SHendrik Brueckner	ld	6,48(%r4)
10989977e886SHendrik Brueckner	ld	7,56(%r4)
10999977e886SHendrik Brueckner	ld	8,64(%r4)
11009977e886SHendrik Brueckner	ld	9,72(%r4)
11019977e886SHendrik Brueckner	ld	10,80(%r4)
11029977e886SHendrik Brueckner	ld	11,88(%r4)
11039977e886SHendrik Brueckner	ld	12,96(%r4)
11049977e886SHendrik Brueckner	ld	13,104(%r4)
11059977e886SHendrik Brueckner	ld	14,112(%r4)
11069977e886SHendrik Brueckner	ld	15,120(%r4)
11079977e886SHendrik Brueckner.Lload_fpu_regs_done:
11089977e886SHendrik Brueckner	ni	__LC_CPU_FLAGS+7,255-_CIF_FPU
1109f19fbd5eSMartin Schwidefsky.Lload_fpu_regs_exit:
1110f19fbd5eSMartin Schwidefsky	BR_R1USE_R14
11119977e886SHendrik Brueckner.Lload_fpu_regs_end:
11129977e886SHendrik Brueckner
11134bfc86ceSHeiko Carstens.L__critical_end:
11144bfc86ceSHeiko Carstens
11154bfc86ceSHeiko Carstens/*
11164bfc86ceSHeiko Carstens * Machine check handler routines
11174bfc86ceSHeiko Carstens */
11184bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
11194bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
1120d768bd89SMartin Schwidefsky	BPOFF
11213037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
11223037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
11233037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
11243037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
11253037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
1126d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
11279977e886SHendrik Brueckner	larl	%r13,cleanup_critical
11284bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
112983abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
11304bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
11313037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
11323037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
11333037a52fSMartin Schwidefsky	la	%r14,4095
11343037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
11353037a52fSMartin Schwidefsky	ptlb
11362a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
11373037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
11383037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
11393037a52fSMartin Schwidefsky	jno	0f
11403037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
11413037a52fSMartin Schwidefsky	jno	0f
11423037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
11433037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
11443037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
11453037a52fSMartin Schwidefsky	jo	0f
11463037a52fSMartin Schwidefsky	sr	%r14,%r14
11473037a52fSMartin Schwidefsky0:	sfpc	%r14
11483037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
11493037a52fSMartin Schwidefsky	jo	0f
11503037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
11513037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
11523037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
11533037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
11543037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
11553037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
11563037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
11573037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
11583037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
11593037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
11603037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
11613037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
11623037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
11633037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
11643037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
11653037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
11663037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
11673037a52fSMartin Schwidefsky	j	1f
11683037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
11693037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
11703037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
11714bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
117283abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
11734bfc86ceSHeiko Carstens	jo	3f
11744bfc86ceSHeiko Carstens	la	%r14,__LC_SYNC_ENTER_TIMER
11754bfc86ceSHeiko Carstens	clc	0(8,%r14),__LC_ASYNC_ENTER_TIMER
11764bfc86ceSHeiko Carstens	jl	0f
11774bfc86ceSHeiko Carstens	la	%r14,__LC_ASYNC_ENTER_TIMER
11784bfc86ceSHeiko Carstens0:	clc	0(8,%r14),__LC_EXIT_TIMER
11794bfc86ceSHeiko Carstens	jl	1f
11804bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
11814bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
11824bfc86ceSHeiko Carstens	jl	2f
11834bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
11844bfc86ceSHeiko Carstens2:	spt	0(%r14)
11854bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
11863037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
11873037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11883037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
11893037a52fSMartin Schwidefsky	jnz	4f
11903037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
11913037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11923037a52fSMartin Schwidefsky4:	SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
11934bfc86ceSHeiko Carstens.Lmcck_skip:
11944bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
11954bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
11967041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
11977041d281SMartin Schwidefsky	xgr	%r0,%r0
11987041d281SMartin Schwidefsky	xgr	%r1,%r1
11997041d281SMartin Schwidefsky	xgr	%r2,%r2
12007041d281SMartin Schwidefsky	xgr	%r3,%r3
12017041d281SMartin Schwidefsky	xgr	%r4,%r4
12027041d281SMartin Schwidefsky	xgr	%r5,%r5
12037041d281SMartin Schwidefsky	xgr	%r6,%r6
12047041d281SMartin Schwidefsky	xgr	%r7,%r7
12057041d281SMartin Schwidefsky	xgr	%r10,%r10
12064bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12074bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12084bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
12094bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12104bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12114bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
12124bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
12134bfc86ceSHeiko Carstens	jno	.Lmcck_return
12144bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
12154bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
12164bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
12174bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
12184bfc86ceSHeiko Carstens	lgr	%r15,%r1
12194bfc86ceSHeiko Carstens	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
122083abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_MCCK_PENDING
12214bfc86ceSHeiko Carstens	jno	.Lmcck_return
12224bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
12234bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
12244bfc86ceSHeiko Carstens	TRACE_IRQS_ON
12254bfc86ceSHeiko Carstens.Lmcck_return:
12264bfc86ceSHeiko Carstens	lg	%r14,__LC_VDSO_PER_CPU
12274bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
12284bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
12294bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
12304bfc86ceSHeiko Carstens	jno	0f
12316b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
12324bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
12334bfc86ceSHeiko Carstens	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
12344bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
12354bfc86ceSHeiko Carstens	lpswe	__LC_RETURN_MCCK_PSW
12364bfc86ceSHeiko Carstens
12374bfc86ceSHeiko Carstens.Lmcck_panic:
12384bfc86ceSHeiko Carstens	lg	%r15,__LC_PANIC_STACK
1239ce4dda3fSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12404bfc86ceSHeiko Carstens	j	.Lmcck_skip
12414bfc86ceSHeiko Carstens
12424bfc86ceSHeiko Carstens#
12434bfc86ceSHeiko Carstens# PSW restart interrupt handler
12444bfc86ceSHeiko Carstens#
12454bfc86ceSHeiko CarstensENTRY(restart_int_handler)
1246e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
1247e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
12484bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
12494bfc86ceSHeiko Carstens	aghi	%r15,-__PT_SIZE			# create pt_regs on stack
12504bfc86ceSHeiko Carstens	xc	0(__PT_SIZE,%r15),0(%r15)
12514bfc86ceSHeiko Carstens	stmg	%r0,%r14,__PT_R0(%r15)
12524bfc86ceSHeiko Carstens	mvc	__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
12534bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
12544bfc86ceSHeiko Carstens	aghi	%r15,-STACK_FRAME_OVERHEAD	# create stack frame on stack
12554bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
12564bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
12574bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
12584bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
12594bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
12604bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
12614bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
12624bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
12634bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
12644bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
12654bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
12664bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
12674bfc86ceSHeiko Carstens	brc	2,2b
12684bfc86ceSHeiko Carstens3:	j	3b
12694bfc86ceSHeiko Carstens
12704bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
12714bfc86ceSHeiko Carstens
12724bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
12734bfc86ceSHeiko Carstens/*
12744bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
12754bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
12764bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
12774bfc86ceSHeiko Carstens */
12784bfc86ceSHeiko Carstensstack_overflow:
12794bfc86ceSHeiko Carstens	lg	%r15,__LC_PANIC_STACK	# change to panic stack
12804bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12814bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
12824bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12834bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12844bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
12854bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12864bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12874bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
12884bfc86ceSHeiko Carstens#endif
12894bfc86ceSHeiko Carstens
12904bfc86ceSHeiko Carstenscleanup_critical:
1291d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1292d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie)	# .Lsie_gmap
1293d0fc4107SMartin Schwidefsky	jl	0f
1294d0fc4107SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_table_sie+8)# .Lsie_done
1295d0fc4107SMartin Schwidefsky	jl	.Lcleanup_sie
1296d0fc4107SMartin Schwidefsky#endif
12974bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table)	# system_call
12984bfc86ceSHeiko Carstens	jl	0f
12994bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+8)	# .Lsysc_do_svc
13004bfc86ceSHeiko Carstens	jl	.Lcleanup_system_call
13014bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+16)	# .Lsysc_tif
13024bfc86ceSHeiko Carstens	jl	0f
13034bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+24)	# .Lsysc_restore
13044bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_tif
13054bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+32)	# .Lsysc_done
13064bfc86ceSHeiko Carstens	jl	.Lcleanup_sysc_restore
13074bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+40)	# .Lio_tif
13084bfc86ceSHeiko Carstens	jl	0f
13094bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+48)	# .Lio_restore
13104bfc86ceSHeiko Carstens	jl	.Lcleanup_io_tif
13114bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+56)	# .Lio_done
13124bfc86ceSHeiko Carstens	jl	.Lcleanup_io_restore
13134bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+64)	# psw_idle
13144bfc86ceSHeiko Carstens	jl	0f
13154bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_table+72)	# .Lpsw_idle_end
13164bfc86ceSHeiko Carstens	jl	.Lcleanup_idle
13179977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+80)	# save_fpu_regs
13189977e886SHendrik Brueckner	jl	0f
13199977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+88)	# .Lsave_fpu_regs_end
13209977e886SHendrik Brueckner	jl	.Lcleanup_save_fpu_regs
13219977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+96)	# load_fpu_regs
13229977e886SHendrik Brueckner	jl	0f
13239977e886SHendrik Brueckner	clg	%r9,BASED(.Lcleanup_table+104)	# .Lload_fpu_regs_end
13249977e886SHendrik Brueckner	jl	.Lcleanup_load_fpu_regs
1325f19fbd5eSMartin Schwidefsky0:	BR_R11USE_R14
13264bfc86ceSHeiko Carstens
1327d0fc4107SMartin Schwidefsky	.align	8
1328d0fc4107SMartin Schwidefsky.Lcleanup_table:
1329d0fc4107SMartin Schwidefsky	.quad	system_call
1330d0fc4107SMartin Schwidefsky	.quad	.Lsysc_do_svc
1331d0fc4107SMartin Schwidefsky	.quad	.Lsysc_tif
1332d0fc4107SMartin Schwidefsky	.quad	.Lsysc_restore
1333d0fc4107SMartin Schwidefsky	.quad	.Lsysc_done
1334d0fc4107SMartin Schwidefsky	.quad	.Lio_tif
1335d0fc4107SMartin Schwidefsky	.quad	.Lio_restore
1336d0fc4107SMartin Schwidefsky	.quad	.Lio_done
1337d0fc4107SMartin Schwidefsky	.quad	psw_idle
1338d0fc4107SMartin Schwidefsky	.quad	.Lpsw_idle_end
1339d0fc4107SMartin Schwidefsky	.quad	save_fpu_regs
1340d0fc4107SMartin Schwidefsky	.quad	.Lsave_fpu_regs_end
1341d0fc4107SMartin Schwidefsky	.quad	load_fpu_regs
1342d0fc4107SMartin Schwidefsky	.quad	.Lload_fpu_regs_end
1343d0fc4107SMartin Schwidefsky
1344d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1345d0fc4107SMartin Schwidefsky.Lcleanup_table_sie:
1346d0fc4107SMartin Schwidefsky	.quad	.Lsie_gmap
1347d0fc4107SMartin Schwidefsky	.quad	.Lsie_done
1348d0fc4107SMartin Schwidefsky
1349d0fc4107SMartin Schwidefsky.Lcleanup_sie:
1350c929500dSQingFeng Hao	cghi    %r11,__LC_SAVE_AREA_ASYNC 	#Is this in normal interrupt?
1351c929500dSQingFeng Hao	je      1f
1352c929500dSQingFeng Hao	slg     %r9,BASED(.Lsie_crit_mcck_start)
1353c929500dSQingFeng Hao	clg     %r9,BASED(.Lsie_crit_mcck_length)
1354c929500dSQingFeng Hao	jh      1f
1355c929500dSQingFeng Hao	oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
1356*92fa7a13SMartin Schwidefsky1:	BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
1357*92fa7a13SMartin Schwidefsky	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
1358e22cf8caSChristian Borntraeger	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
1359d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
1360d0fc4107SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
1361f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
1362d0fc4107SMartin Schwidefsky#endif
13634bfc86ceSHeiko Carstens
13644bfc86ceSHeiko Carstens.Lcleanup_system_call:
13654bfc86ceSHeiko Carstens	# check if stpt has been executed
13664bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn)
13674bfc86ceSHeiko Carstens	jh	0f
13684bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
13694bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
13704bfc86ceSHeiko Carstens	je	0f
13714bfc86ceSHeiko Carstens	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
13724bfc86ceSHeiko Carstens0:	# check if stmg has been executed
13734bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+8)
13744bfc86ceSHeiko Carstens	jh	0f
13754bfc86ceSHeiko Carstens	mvc	__LC_SAVE_AREA_SYNC(64),0(%r11)
13764bfc86ceSHeiko Carstens0:	# check if base register setup + TIF bit load has been done
13774bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+16)
13784bfc86ceSHeiko Carstens	jhe	0f
137934525e1fSMartin Schwidefsky	# set up saved register r12 task struct pointer
138034525e1fSMartin Schwidefsky	stg	%r12,32(%r11)
138134525e1fSMartin Schwidefsky	# set up saved register r13 __TASK_thread offset
138234525e1fSMartin Schwidefsky	mvc	40(8,%r11),BASED(.Lcleanup_system_call_const)
13834bfc86ceSHeiko Carstens0:	# check if the user time update has been done
13844bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+24)
13854bfc86ceSHeiko Carstens	jh	0f
13864bfc86ceSHeiko Carstens	lg	%r15,__LC_EXIT_TIMER
13874bfc86ceSHeiko Carstens	slg	%r15,__LC_SYNC_ENTER_TIMER
13884bfc86ceSHeiko Carstens	alg	%r15,__LC_USER_TIMER
13894bfc86ceSHeiko Carstens	stg	%r15,__LC_USER_TIMER
13904bfc86ceSHeiko Carstens0:	# check if the system time update has been done
13914bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_system_call_insn+32)
13924bfc86ceSHeiko Carstens	jh	0f
13934bfc86ceSHeiko Carstens	lg	%r15,__LC_LAST_UPDATE_TIMER
13944bfc86ceSHeiko Carstens	slg	%r15,__LC_EXIT_TIMER
13954bfc86ceSHeiko Carstens	alg	%r15,__LC_SYSTEM_TIMER
13964bfc86ceSHeiko Carstens	stg	%r15,__LC_SYSTEM_TIMER
13974bfc86ceSHeiko Carstens0:	# update accounting time stamp
13984bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
1399d5feec04SMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
140034525e1fSMartin Schwidefsky	# set up saved register r11
14014bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
14024bfc86ceSHeiko Carstens	la	%r9,STACK_FRAME_OVERHEAD(%r15)
14034bfc86ceSHeiko Carstens	stg	%r9,24(%r11)		# r11 pt_regs pointer
14044bfc86ceSHeiko Carstens	# fill pt_regs
14054bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r9),__LC_SAVE_AREA_SYNC
14064bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r9)
14074bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r9),__LC_SVC_OLD_PSW
14084bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r9),__LC_SVC_ILC
14094bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r9),__PT_FLAGS(%r9)
14104bfc86ceSHeiko Carstens	mvi	__PT_FLAGS+7(%r9),_PIF_SYSCALL
14114bfc86ceSHeiko Carstens	# setup saved register r15
14124bfc86ceSHeiko Carstens	stg	%r15,56(%r11)		# r15 stack pointer
14134bfc86ceSHeiko Carstens	# set new psw address and exit
14144bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_do_svc
1415f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
14164bfc86ceSHeiko Carstens.Lcleanup_system_call_insn:
14174bfc86ceSHeiko Carstens	.quad	system_call
14184bfc86ceSHeiko Carstens	.quad	.Lsysc_stmg
14194bfc86ceSHeiko Carstens	.quad	.Lsysc_per
1420a359bb11SMartin Schwidefsky	.quad	.Lsysc_vtime+36
14214bfc86ceSHeiko Carstens	.quad	.Lsysc_vtime+42
142234525e1fSMartin Schwidefsky.Lcleanup_system_call_const:
142334525e1fSMartin Schwidefsky	.quad	__TASK_thread
14244bfc86ceSHeiko Carstens
14254bfc86ceSHeiko Carstens.Lcleanup_sysc_tif:
14264bfc86ceSHeiko Carstens	larl	%r9,.Lsysc_tif
1427f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
14284bfc86ceSHeiko Carstens
14294bfc86ceSHeiko Carstens.Lcleanup_sysc_restore:
143007a63cbeSMartin Schwidefsky	# check if stpt has been executed
14314bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_sysc_restore_insn)
143207a63cbeSMartin Schwidefsky	jh	0f
143307a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
143407a63cbeSMartin Schwidefsky	cghi	%r11,__LC_SAVE_AREA_ASYNC
14354bfc86ceSHeiko Carstens	je	0f
143607a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
143707a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_sysc_restore_insn+8)
143807a63cbeSMartin Schwidefsky	je	1f
14394bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved pointer to pt_regs
14404bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14414bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14424bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
144307a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
1444f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
14454bfc86ceSHeiko Carstens.Lcleanup_sysc_restore_insn:
144607a63cbeSMartin Schwidefsky	.quad	.Lsysc_exit_timer
14474bfc86ceSHeiko Carstens	.quad	.Lsysc_done - 4
14484bfc86ceSHeiko Carstens
14494bfc86ceSHeiko Carstens.Lcleanup_io_tif:
14504bfc86ceSHeiko Carstens	larl	%r9,.Lio_tif
1451f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
14524bfc86ceSHeiko Carstens
14534bfc86ceSHeiko Carstens.Lcleanup_io_restore:
145407a63cbeSMartin Schwidefsky	# check if stpt has been executed
14554bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_io_restore_insn)
145607a63cbeSMartin Schwidefsky	jh	0f
145707a63cbeSMartin Schwidefsky	mvc	__LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
145807a63cbeSMartin Schwidefsky0:	clg	%r9,BASED(.Lcleanup_io_restore_insn+8)
145907a63cbeSMartin Schwidefsky	je	1f
14604bfc86ceSHeiko Carstens	lg	%r9,24(%r11)		# get saved r11 pointer to pt_regs
14614bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
14624bfc86ceSHeiko Carstens	mvc	0(64,%r11),__PT_R8(%r9)
14634bfc86ceSHeiko Carstens	lmg	%r0,%r7,__PT_R0(%r9)
146407a63cbeSMartin Schwidefsky1:	lmg	%r8,%r9,__LC_RETURN_PSW
1465f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
14664bfc86ceSHeiko Carstens.Lcleanup_io_restore_insn:
146707a63cbeSMartin Schwidefsky	.quad	.Lio_exit_timer
14684bfc86ceSHeiko Carstens	.quad	.Lio_done - 4
14694bfc86ceSHeiko Carstens
14704bfc86ceSHeiko Carstens.Lcleanup_idle:
1471419123f9SMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
14724bfc86ceSHeiko Carstens	# copy interrupt clock & cpu timer
14734bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
14744bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
14754bfc86ceSHeiko Carstens	cghi	%r11,__LC_SAVE_AREA_ASYNC
14764bfc86ceSHeiko Carstens	je	0f
14774bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
14784bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
14794bfc86ceSHeiko Carstens0:	# check if stck & stpt have been executed
14804bfc86ceSHeiko Carstens	clg	%r9,BASED(.Lcleanup_idle_insn)
14814bfc86ceSHeiko Carstens	jhe	1f
14824bfc86ceSHeiko Carstens	mvc	__CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
14834bfc86ceSHeiko Carstens	mvc	__TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2)
148472d38b19SMartin Schwidefsky1:	# calculate idle cycles
148572d38b19SMartin Schwidefsky#ifdef CONFIG_SMP
148672d38b19SMartin Schwidefsky	clg	%r9,BASED(.Lcleanup_idle_insn)
148772d38b19SMartin Schwidefsky	jl	3f
148872d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
148972d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
149072d38b19SMartin Schwidefsky	ltgr	%r1,%r1
149172d38b19SMartin Schwidefsky	jz	3f
149272d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+80(%r15)
149372d38b19SMartin Schwidefsky	larl	%r3,mt_cycles
149472d38b19SMartin Schwidefsky	ag	%r3,__LC_PERCPU_OFFSET
149572d38b19SMartin Schwidefsky	la	%r4,__SF_EMPTY+16(%r15)
149672d38b19SMartin Schwidefsky2:	lg	%r0,0(%r3)
149772d38b19SMartin Schwidefsky	slg	%r0,0(%r4)
149872d38b19SMartin Schwidefsky	alg	%r0,64(%r4)
149972d38b19SMartin Schwidefsky	stg	%r0,0(%r3)
150072d38b19SMartin Schwidefsky	la	%r3,8(%r3)
150172d38b19SMartin Schwidefsky	la	%r4,8(%r4)
150272d38b19SMartin Schwidefsky	brct	%r1,2b
150372d38b19SMartin Schwidefsky#endif
150472d38b19SMartin Schwidefsky3:	# account system time going idle
15054bfc86ceSHeiko Carstens	lg	%r9,__LC_STEAL_TIMER
15064bfc86ceSHeiko Carstens	alg	%r9,__CLOCK_IDLE_ENTER(%r2)
15074bfc86ceSHeiko Carstens	slg	%r9,__LC_LAST_UPDATE_CLOCK
15084bfc86ceSHeiko Carstens	stg	%r9,__LC_STEAL_TIMER
15094bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2)
15104bfc86ceSHeiko Carstens	lg	%r9,__LC_SYSTEM_TIMER
15114bfc86ceSHeiko Carstens	alg	%r9,__LC_LAST_UPDATE_TIMER
15124bfc86ceSHeiko Carstens	slg	%r9,__TIMER_IDLE_ENTER(%r2)
15134bfc86ceSHeiko Carstens	stg	%r9,__LC_SYSTEM_TIMER
15144bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
15154bfc86ceSHeiko Carstens	# prepare return psw
15164bfc86ceSHeiko Carstens	nihh	%r8,0xfcfd		# clear irq & wait state bits
15174bfc86ceSHeiko Carstens	lg	%r9,48(%r11)		# return from psw_idle
1518f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
15194bfc86ceSHeiko Carstens.Lcleanup_idle_insn:
15204bfc86ceSHeiko Carstens	.quad	.Lpsw_idle_lpsw
15214bfc86ceSHeiko Carstens
15229977e886SHendrik Brueckner.Lcleanup_save_fpu_regs:
1523e370e476SMartin Schwidefsky	larl	%r9,save_fpu_regs
1524f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
15259977e886SHendrik Brueckner
15269977e886SHendrik Brueckner.Lcleanup_load_fpu_regs:
1527e370e476SMartin Schwidefsky	larl	%r9,load_fpu_regs
1528f19fbd5eSMartin Schwidefsky	BR_R11USE_R14
15299977e886SHendrik Brueckner
15304bfc86ceSHeiko Carstens/*
15314bfc86ceSHeiko Carstens * Integer constants
15324bfc86ceSHeiko Carstens */
15334bfc86ceSHeiko Carstens	.align	8
15344bfc86ceSHeiko Carstens.Lcritical_start:
15354bfc86ceSHeiko Carstens	.quad	.L__critical_start
15364bfc86ceSHeiko Carstens.Lcritical_length:
15374bfc86ceSHeiko Carstens	.quad	.L__critical_end - .L__critical_start
15384bfc86ceSHeiko Carstens#if IS_ENABLED(CONFIG_KVM)
1539d0fc4107SMartin Schwidefsky.Lsie_critical_start:
15404bfc86ceSHeiko Carstens	.quad	.Lsie_gmap
15414bfc86ceSHeiko Carstens.Lsie_critical_length:
15424bfc86ceSHeiko Carstens	.quad	.Lsie_done - .Lsie_gmap
1543c929500dSQingFeng Hao.Lsie_crit_mcck_start:
1544c929500dSQingFeng Hao	.quad   .Lsie_entry
1545c929500dSQingFeng Hao.Lsie_crit_mcck_length:
1546c929500dSQingFeng Hao	.quad   .Lsie_skip - .Lsie_entry
15474bfc86ceSHeiko Carstens#endif
15484bfc86ceSHeiko Carstens	.section .rodata, "a"
1549a876cb3fSHeiko Carstens#define SYSCALL(esame,emu)	.long esame
15504bfc86ceSHeiko Carstens	.globl	sys_call_table
15514bfc86ceSHeiko Carstenssys_call_table:
15524381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15534bfc86ceSHeiko Carstens#undef SYSCALL
15544bfc86ceSHeiko Carstens
15554bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
15564bfc86ceSHeiko Carstens
1557a876cb3fSHeiko Carstens#define SYSCALL(esame,emu)	.long emu
15584bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
15594bfc86ceSHeiko Carstenssys_call_table_emu:
15604381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
15614bfc86ceSHeiko Carstens#undef SYSCALL
15624bfc86ceSHeiko Carstens#endif
1563