xref: /openbmc/linux/arch/s390/kernel/entry.S (revision 0cd9b7230cc57b0f9cfd13ef5c3830c7db1a68d4)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
24bfc86ceSHeiko Carstens/*
34bfc86ceSHeiko Carstens *    S390 low-level entry points.
44bfc86ceSHeiko Carstens *
54bfc86ceSHeiko Carstens *    Copyright IBM Corp. 1999, 2012
64bfc86ceSHeiko Carstens *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
74bfc86ceSHeiko Carstens *		 Hartmut Penner (hp@de.ibm.com),
84bfc86ceSHeiko Carstens *		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
94bfc86ceSHeiko Carstens *		 Heiko Carstens <heiko.carstens@de.ibm.com>
104bfc86ceSHeiko Carstens */
114bfc86ceSHeiko Carstens
124bfc86ceSHeiko Carstens#include <linux/init.h>
134bfc86ceSHeiko Carstens#include <linux/linkage.h>
14b058661aSMartin Schwidefsky#include <asm/alternative-asm.h>
154bfc86ceSHeiko Carstens#include <asm/processor.h>
164bfc86ceSHeiko Carstens#include <asm/cache.h>
173037a52fSMartin Schwidefsky#include <asm/ctl_reg.h>
18dc24b7b4SHendrik Brueckner#include <asm/dwarf.h>
194bfc86ceSHeiko Carstens#include <asm/errno.h>
204bfc86ceSHeiko Carstens#include <asm/ptrace.h>
214bfc86ceSHeiko Carstens#include <asm/thread_info.h>
224bfc86ceSHeiko Carstens#include <asm/asm-offsets.h>
234bfc86ceSHeiko Carstens#include <asm/unistd.h>
244bfc86ceSHeiko Carstens#include <asm/page.h>
254bfc86ceSHeiko Carstens#include <asm/sigp.h>
264bfc86ceSHeiko Carstens#include <asm/irq.h>
279977e886SHendrik Brueckner#include <asm/vx-insn.h>
2883abeffbSHendrik Brueckner#include <asm/setup.h>
2983abeffbSHendrik Brueckner#include <asm/nmi.h>
30711f5df7SAl Viro#include <asm/export.h>
316dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h>
324bfc86ceSHeiko Carstens
334bfc86ceSHeiko Carstens__PT_R0      =	__PT_GPRS
344bfc86ceSHeiko Carstens__PT_R1      =	__PT_GPRS + 8
354bfc86ceSHeiko Carstens__PT_R2      =	__PT_GPRS + 16
364bfc86ceSHeiko Carstens__PT_R3      =	__PT_GPRS + 24
374bfc86ceSHeiko Carstens__PT_R4      =	__PT_GPRS + 32
384bfc86ceSHeiko Carstens__PT_R5      =	__PT_GPRS + 40
394bfc86ceSHeiko Carstens__PT_R6      =	__PT_GPRS + 48
404bfc86ceSHeiko Carstens__PT_R7      =	__PT_GPRS + 56
414bfc86ceSHeiko Carstens__PT_R8      =	__PT_GPRS + 64
424bfc86ceSHeiko Carstens__PT_R9      =	__PT_GPRS + 72
434bfc86ceSHeiko Carstens__PT_R10     =	__PT_GPRS + 80
444bfc86ceSHeiko Carstens__PT_R11     =	__PT_GPRS + 88
454bfc86ceSHeiko Carstens__PT_R12     =	__PT_GPRS + 96
464bfc86ceSHeiko Carstens__PT_R13     =	__PT_GPRS + 104
474bfc86ceSHeiko Carstens__PT_R14     =	__PT_GPRS + 112
484bfc86ceSHeiko Carstens__PT_R15     =	__PT_GPRS + 120
494bfc86ceSHeiko Carstens
503a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER
514bfc86ceSHeiko CarstensSTACK_SIZE  = 1 << STACK_SHIFT
524bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
534bfc86ceSHeiko Carstens
544bfc86ceSHeiko Carstens_TIF_WORK	= (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
5576f1948aSLinus Torvalds		   _TIF_UPROBE | _TIF_GUARDED_STORAGE | _TIF_PATCH_PENDING)
564bfc86ceSHeiko Carstens_TIF_TRACE	= (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
574bfc86ceSHeiko Carstens		   _TIF_SYSCALL_TRACEPOINT)
580b0ed657SSven Schnelle_CIF_WORK	= (_CIF_ASCE_PRIMARY | _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
634bfc86ceSHeiko Carstens	.macro	TRACE_IRQS_ON
644bfc86ceSHeiko Carstens#ifdef CONFIG_TRACE_IRQFLAGS
654bfc86ceSHeiko Carstens	basr	%r2,%r0
664bfc86ceSHeiko Carstens	brasl	%r14,trace_hardirqs_on_caller
674bfc86ceSHeiko Carstens#endif
684bfc86ceSHeiko Carstens	.endm
694bfc86ceSHeiko Carstens
704bfc86ceSHeiko Carstens	.macro	TRACE_IRQS_OFF
714bfc86ceSHeiko Carstens#ifdef CONFIG_TRACE_IRQFLAGS
724bfc86ceSHeiko Carstens	basr	%r2,%r0
734bfc86ceSHeiko Carstens	brasl	%r14,trace_hardirqs_off_caller
744bfc86ceSHeiko Carstens#endif
754bfc86ceSHeiko Carstens	.endm
764bfc86ceSHeiko Carstens
774bfc86ceSHeiko Carstens	.macro	LOCKDEP_SYS_EXIT
784bfc86ceSHeiko Carstens#ifdef CONFIG_LOCKDEP
794bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
804bfc86ceSHeiko Carstens	jz	.+10
814bfc86ceSHeiko Carstens	brasl	%r14,lockdep_sys_exit
824bfc86ceSHeiko Carstens#endif
834bfc86ceSHeiko Carstens	.endm
844bfc86ceSHeiko Carstens
85ce3dc447SMartin Schwidefsky	.macro	CHECK_STACK savearea
864bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK
87ce3dc447SMartin Schwidefsky	tml	%r15,STACK_SIZE - CONFIG_STACK_GUARD
884bfc86ceSHeiko Carstens	lghi	%r14,\savearea
894bfc86ceSHeiko Carstens	jz	stack_overflow
904bfc86ceSHeiko Carstens#endif
914bfc86ceSHeiko Carstens	.endm
924bfc86ceSHeiko Carstens
93ce3dc447SMartin Schwidefsky	.macro	CHECK_VMAP_STACK savearea,oklabel
94ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK
95ce3dc447SMartin Schwidefsky	lgr	%r14,%r15
96ce3dc447SMartin Schwidefsky	nill	%r14,0x10000 - STACK_SIZE
97ce3dc447SMartin Schwidefsky	oill	%r14,STACK_INIT
98ce3dc447SMartin Schwidefsky	clg	%r14,__LC_KERNEL_STACK
99ce3dc447SMartin Schwidefsky	je	\oklabel
100ce3dc447SMartin Schwidefsky	clg	%r14,__LC_ASYNC_STACK
101ce3dc447SMartin Schwidefsky	je	\oklabel
102ce3dc447SMartin Schwidefsky	clg	%r14,__LC_NODAT_STACK
103ce3dc447SMartin Schwidefsky	je	\oklabel
104ce3dc447SMartin Schwidefsky	clg	%r14,__LC_RESTART_STACK
105ce3dc447SMartin Schwidefsky	je	\oklabel
106ce3dc447SMartin Schwidefsky	lghi	%r14,\savearea
107ce3dc447SMartin Schwidefsky	j	stack_overflow
108ce3dc447SMartin Schwidefsky#else
109ce3dc447SMartin Schwidefsky	j	\oklabel
110ce3dc447SMartin Schwidefsky#endif
111ce3dc447SMartin Schwidefsky	.endm
112ce3dc447SMartin Schwidefsky
1132acb94f4SMartin Schwidefsky	.macro	SWITCH_ASYNC savearea,timer
1144bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# interrupting from user ?
1150b38b5e1SSven Schnelle	jnz	2f
1160b0ed657SSven Schnelle#if IS_ENABLED(CONFIG_KVM)
1174bfc86ceSHeiko Carstens	lgr	%r14,%r9
1180b0ed657SSven Schnelle	larl	%r13,.Lsie_gmap
1190b0ed657SSven Schnelle	slgr	%r14,%r13
1200b0ed657SSven Schnelle	lghi	%r13,.Lsie_done - .Lsie_gmap
1210b0ed657SSven Schnelle	clgr	%r14,%r13
1220b0ed657SSven Schnelle	jhe	0f
1234bfc86ceSHeiko Carstens	lghi	%r11,\savearea		# inside critical section, do cleanup
1240b0ed657SSven Schnelle	brasl	%r14,.Lcleanup_sie
1250b0ed657SSven Schnelle#endif
1260b0ed657SSven Schnelle0:	larl	%r13,.Lpsw_idle_exit
1270b0ed657SSven Schnelle	cgr	%r13,%r9
1280b0ed657SSven Schnelle	jne	1f
1290b0ed657SSven Schnelle
1300b0ed657SSven Schnelle	mvc	__CLOCK_IDLE_EXIT(8,%r2), __LC_INT_CLOCK
1310b0ed657SSven Schnelle	mvc	__TIMER_IDLE_EXIT(8,%r2), __LC_ASYNC_ENTER_TIMER
1320b0ed657SSven Schnelle	# account system time going idle
1330b0ed657SSven Schnelle	ni	__LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
1340b0ed657SSven Schnelle
1350b0ed657SSven Schnelle	lg	%r13,__LC_STEAL_TIMER
1360b0ed657SSven Schnelle	alg	%r13,__CLOCK_IDLE_ENTER(%r2)
1370b0ed657SSven Schnelle	slg	%r13,__LC_LAST_UPDATE_CLOCK
1380b0ed657SSven Schnelle	stg	%r13,__LC_STEAL_TIMER
1390b0ed657SSven Schnelle
1400b0ed657SSven Schnelle	mvc	__LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2)
1410b0ed657SSven Schnelle
1420b0ed657SSven Schnelle	lg	%r13,__LC_SYSTEM_TIMER
1430b0ed657SSven Schnelle	alg	%r13,__LC_LAST_UPDATE_TIMER
1440b0ed657SSven Schnelle	slg	%r13,__TIMER_IDLE_ENTER(%r2)
1450b0ed657SSven Schnelle	stg	%r13,__LC_SYSTEM_TIMER
1460b0ed657SSven Schnelle	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
1470b0ed657SSven Schnelle
1480b0ed657SSven Schnelle	nihh	%r8,0xfcfd		# clear wait state and irq bits
1490b38b5e1SSven Schnelle1:	lg	%r14,__LC_ASYNC_STACK	# are we already on the target stack?
1504bfc86ceSHeiko Carstens	slgr	%r14,%r15
1512acb94f4SMartin Schwidefsky	srag	%r14,%r14,STACK_SHIFT
1520b38b5e1SSven Schnelle	jnz	3f
153ce3dc447SMartin Schwidefsky	CHECK_STACK \savearea
1544bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
1550b38b5e1SSven Schnelle	j	4f
1560b38b5e1SSven Schnelle2:	UPDATE_VTIME %r14,%r15,\timer
1576b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
1580b38b5e1SSven Schnelle3:	lg	%r15,__LC_ASYNC_STACK	# load async stack
1590b38b5e1SSven Schnelle4:	la	%r11,STACK_FRAME_OVERHEAD(%r15)
1604bfc86ceSHeiko Carstens	.endm
1614bfc86ceSHeiko Carstens
162a359bb11SMartin Schwidefsky	.macro UPDATE_VTIME w1,w2,enter_timer
163a359bb11SMartin Schwidefsky	lg	\w1,__LC_EXIT_TIMER
164a359bb11SMartin Schwidefsky	lg	\w2,__LC_LAST_UPDATE_TIMER
165a359bb11SMartin Schwidefsky	slg	\w1,\enter_timer
166a359bb11SMartin Schwidefsky	slg	\w2,__LC_EXIT_TIMER
167a359bb11SMartin Schwidefsky	alg	\w1,__LC_USER_TIMER
168a359bb11SMartin Schwidefsky	alg	\w2,__LC_SYSTEM_TIMER
169a359bb11SMartin Schwidefsky	stg	\w1,__LC_USER_TIMER
170a359bb11SMartin Schwidefsky	stg	\w2,__LC_SYSTEM_TIMER
1714bfc86ceSHeiko Carstens	mvc	__LC_LAST_UPDATE_TIMER(8),\enter_timer
1724bfc86ceSHeiko Carstens	.endm
1734bfc86ceSHeiko Carstens
1740b0ed657SSven Schnelle	.macro RESTORE_SM_CLEAR_PER
1754bfc86ceSHeiko Carstens	stg	%r8,__LC_RETURN_PSW
1764bfc86ceSHeiko Carstens	ni	__LC_RETURN_PSW,0xbf
1774bfc86ceSHeiko Carstens	ssm	__LC_RETURN_PSW
1784bfc86ceSHeiko Carstens	.endm
1794bfc86ceSHeiko Carstens
1800b0ed657SSven Schnelle	.macro ENABLE_INTS
1810b0ed657SSven Schnelle	stosm	__SF_EMPTY(%r15),3
1820b0ed657SSven Schnelle	.endm
1830b0ed657SSven Schnelle
1840b0ed657SSven Schnelle	.macro ENABLE_INTS_TRACE
1850b0ed657SSven Schnelle	TRACE_IRQS_ON
1860b0ed657SSven Schnelle	ENABLE_INTS
1870b0ed657SSven Schnelle	.endm
1880b0ed657SSven Schnelle
1890b0ed657SSven Schnelle	.macro DISABLE_INTS
1900b0ed657SSven Schnelle	stnsm	__SF_EMPTY(%r15),0xfc
1910b0ed657SSven Schnelle	.endm
1920b0ed657SSven Schnelle
1930b0ed657SSven Schnelle	.macro DISABLE_INTS_TRACE
1940b0ed657SSven Schnelle	DISABLE_INTS
1950b0ed657SSven Schnelle	TRACE_IRQS_OFF
1960b0ed657SSven Schnelle	.endm
1970b0ed657SSven Schnelle
1984bfc86ceSHeiko Carstens	.macro STCK savearea
1994bfc86ceSHeiko Carstens#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
2004bfc86ceSHeiko Carstens	.insn	s,0xb27c0000,\savearea		# store clock fast
2014bfc86ceSHeiko Carstens#else
2024bfc86ceSHeiko Carstens	.insn	s,0xb2050000,\savearea		# store clock
2034bfc86ceSHeiko Carstens#endif
2044bfc86ceSHeiko Carstens	.endm
2054bfc86ceSHeiko Carstens
20683abeffbSHendrik Brueckner	/*
20783abeffbSHendrik Brueckner	 * The TSTMSK macro generates a test-under-mask instruction by
20883abeffbSHendrik Brueckner	 * calculating the memory offset for the specified mask value.
20983abeffbSHendrik Brueckner	 * Mask value can be any constant.  The macro shifts the mask
21083abeffbSHendrik Brueckner	 * value to calculate the memory offset for the test-under-mask
21183abeffbSHendrik Brueckner	 * instruction.
21283abeffbSHendrik Brueckner	 */
21383abeffbSHendrik Brueckner	.macro TSTMSK addr, mask, size=8, bytepos=0
21483abeffbSHendrik Brueckner		.if (\bytepos < \size) && (\mask >> 8)
21583abeffbSHendrik Brueckner			.if (\mask & 0xff)
21683abeffbSHendrik Brueckner				.error "Mask exceeds byte boundary"
21783abeffbSHendrik Brueckner			.endif
21883abeffbSHendrik Brueckner			TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
21983abeffbSHendrik Brueckner			.exitm
22083abeffbSHendrik Brueckner		.endif
22183abeffbSHendrik Brueckner		.ifeq \mask
22283abeffbSHendrik Brueckner			.error "Mask must not be zero"
22383abeffbSHendrik Brueckner		.endif
22483abeffbSHendrik Brueckner		off = \size - \bytepos - 1
22583abeffbSHendrik Brueckner		tm	off+\addr, \mask
22683abeffbSHendrik Brueckner	.endm
22783abeffbSHendrik Brueckner
228d768bd89SMartin Schwidefsky	.macro BPOFF
229b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8c000", 82
230d768bd89SMartin Schwidefsky	.endm
231d768bd89SMartin Schwidefsky
232d768bd89SMartin Schwidefsky	.macro BPON
233b058661aSMartin Schwidefsky	ALTERNATIVE "", ".long 0xb2e8d000", 82
234d768bd89SMartin Schwidefsky	.endm
235d768bd89SMartin Schwidefsky
2366b73044bSMartin Schwidefsky	.macro BPENTER tif_ptr,tif_mask
237b058661aSMartin Schwidefsky	ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \
238b058661aSMartin Schwidefsky		    "", 82
2396b73044bSMartin Schwidefsky	.endm
2406b73044bSMartin Schwidefsky
2416b73044bSMartin Schwidefsky	.macro BPEXIT tif_ptr,tif_mask
2426b73044bSMartin Schwidefsky	TSTMSK	\tif_ptr,\tif_mask
243b058661aSMartin Schwidefsky	ALTERNATIVE "jz .+8;  .long 0xb2e8c000", \
244b058661aSMartin Schwidefsky		    "jnz .+8; .long 0xb2e8d000", 82
2456b73044bSMartin Schwidefsky	.endm
2466b73044bSMartin Schwidefsky
2476dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r9
2486dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14
2496dd85fbbSMartin Schwidefsky	GEN_BR_THUNK %r14,%r11
250f19fbd5eSMartin Schwidefsky
2514bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
25246210c44SHeiko Carstens.Ldummy:
25346210c44SHeiko Carstens	/*
25446210c44SHeiko Carstens	 * This nop exists only in order to avoid that __switch_to starts at
25546210c44SHeiko Carstens	 * the beginning of the kprobes text section. In that case we would
25646210c44SHeiko Carstens	 * have several symbols at the same address. E.g. objdump would take
25746210c44SHeiko Carstens	 * an arbitrary symbol name when disassembling this code.
25846210c44SHeiko Carstens	 * With the added nop in between the __switch_to symbol is unique
25946210c44SHeiko Carstens	 * again.
26046210c44SHeiko Carstens	 */
26146210c44SHeiko Carstens	nop	0
2624bfc86ceSHeiko Carstens
263d768bd89SMartin SchwidefskyENTRY(__bpon)
264d768bd89SMartin Schwidefsky	.globl __bpon
265d768bd89SMartin Schwidefsky	BPON
2666dd85fbbSMartin Schwidefsky	BR_EX	%r14
26726a374aeSMartin SchwidefskyENDPROC(__bpon)
268d768bd89SMartin Schwidefsky
2694bfc86ceSHeiko Carstens/*
2704bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to
2714bfc86ceSHeiko Carstens *  gpr2 = (task_struct *) prev
2724bfc86ceSHeiko Carstens *  gpr3 = (task_struct *) next
2734bfc86ceSHeiko Carstens * Returns:
2744bfc86ceSHeiko Carstens *  gpr2 = prev
2754bfc86ceSHeiko Carstens */
2764bfc86ceSHeiko CarstensENTRY(__switch_to)
2774bfc86ceSHeiko Carstens	stmg	%r6,%r15,__SF_GPRS(%r15)	# store gprs of prev task
2783241d3ebSHeiko Carstens	lghi	%r4,__TASK_stack
2793241d3ebSHeiko Carstens	lghi	%r1,__TASK_thread
2809fed920eSVasily Gorbik	llill	%r5,STACK_INIT
2813241d3ebSHeiko Carstens	stg	%r15,__THREAD_ksp(%r1,%r2)	# store kernel stack of prev
2829fed920eSVasily Gorbik	lg	%r15,0(%r4,%r3)			# start of kernel stack of next
2839fed920eSVasily Gorbik	agr	%r15,%r5			# end of kernel stack of next
2844bfc86ceSHeiko Carstens	stg	%r3,__LC_CURRENT		# store task struct of next
2854bfc86ceSHeiko Carstens	stg	%r15,__LC_KERNEL_STACK		# store end of kernel stack
2863241d3ebSHeiko Carstens	lg	%r15,__THREAD_ksp(%r1,%r3)	# load kernel stack of next
2873241d3ebSHeiko Carstens	aghi	%r3,__TASK_pid
2883241d3ebSHeiko Carstens	mvc	__LC_CURRENT_PID(4,%r0),0(%r3)	# store pid of next
2894bfc86ceSHeiko Carstens	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
290e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
2916dd85fbbSMartin Schwidefsky	BR_EX	%r14
29226a374aeSMartin SchwidefskyENDPROC(__switch_to)
2934bfc86ceSHeiko Carstens
294d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
295d0fc4107SMartin Schwidefsky/*
296d0fc4107SMartin Schwidefsky * sie64a calling convention:
297d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block
298d0fc4107SMartin Schwidefsky * %r3 guest register save area
299d0fc4107SMartin Schwidefsky */
300d0fc4107SMartin SchwidefskyENTRY(sie64a)
301d0fc4107SMartin Schwidefsky	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
3026b73044bSMartin Schwidefsky	lg	%r12,__LC_CURRENT
30392fa7a13SMartin Schwidefsky	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer
30492fa7a13SMartin Schwidefsky	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area
30592fa7a13SMartin Schwidefsky	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
30692fa7a13SMartin Schwidefsky	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
30783abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU		# load guest fp/vx registers ?
308d0fc4107SMartin Schwidefsky	jno	.Lsie_load_guest_gprs
309d0fc4107SMartin Schwidefsky	brasl	%r14,load_fpu_regs		# load guest fp/vx regs
310d0fc4107SMartin Schwidefsky.Lsie_load_guest_gprs:
311d0fc4107SMartin Schwidefsky	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
312d0fc4107SMartin Schwidefsky	lg	%r14,__LC_GMAP			# get gmap pointer
313d0fc4107SMartin Schwidefsky	ltgr	%r14,%r14
314d0fc4107SMartin Schwidefsky	jz	.Lsie_gmap
315d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
316d0fc4107SMartin Schwidefsky.Lsie_gmap:
31792fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
318d0fc4107SMartin Schwidefsky	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
319d0fc4107SMartin Schwidefsky	tm	__SIE_PROG20+3(%r14),3		# last exit...
320d0fc4107SMartin Schwidefsky	jnz	.Lsie_skip
32183abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
322d0fc4107SMartin Schwidefsky	jo	.Lsie_skip			# exit if fp/vx regs changed
32392fa7a13SMartin Schwidefsky	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
324c929500dSQingFeng Hao.Lsie_entry:
325d0fc4107SMartin Schwidefsky	sie	0(%r14)
326d768bd89SMartin Schwidefsky	BPOFF
32792fa7a13SMartin Schwidefsky	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
328d0fc4107SMartin Schwidefsky.Lsie_skip:
329d0fc4107SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
330d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
331d0fc4107SMartin Schwidefsky.Lsie_done:
332d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception)
333c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
334c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
335c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program
336c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
337d0fc4107SMartin Schwidefsky# See also .Lcleanup_sie
338c0e7bb38SChristian Borntraeger.Lrewind_pad6:
339c0e7bb38SChristian Borntraeger	nopr	7
340c0e7bb38SChristian Borntraeger.Lrewind_pad4:
341c0e7bb38SChristian Borntraeger	nopr	7
342c0e7bb38SChristian Borntraeger.Lrewind_pad2:
343c0e7bb38SChristian Borntraeger	nopr	7
344d0fc4107SMartin Schwidefsky	.globl sie_exit
345d0fc4107SMartin Schwidefskysie_exit:
34692fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_SAVEAREA(%r15)	# load guest register save area
347d0fc4107SMartin Schwidefsky	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
3487041d281SMartin Schwidefsky	xgr	%r0,%r0				# clear guest registers to
3497041d281SMartin Schwidefsky	xgr	%r1,%r1				# prevent speculative use
3507041d281SMartin Schwidefsky	xgr	%r2,%r2
3517041d281SMartin Schwidefsky	xgr	%r3,%r3
3527041d281SMartin Schwidefsky	xgr	%r4,%r4
3537041d281SMartin Schwidefsky	xgr	%r5,%r5
354d0fc4107SMartin Schwidefsky	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
35592fa7a13SMartin Schwidefsky	lg	%r2,__SF_SIE_REASON(%r15)	# return exit reason code
3566dd85fbbSMartin Schwidefsky	BR_EX	%r14
357d0fc4107SMartin Schwidefsky.Lsie_fault:
358d0fc4107SMartin Schwidefsky	lghi	%r14,-EFAULT
35992fa7a13SMartin Schwidefsky	stg	%r14,__SF_SIE_REASON(%r15)	# set exit reason code
360d0fc4107SMartin Schwidefsky	j	sie_exit
361d0fc4107SMartin Schwidefsky
362c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad6,.Lsie_fault)
363c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad4,.Lsie_fault)
364c0e7bb38SChristian Borntraeger	EX_TABLE(.Lrewind_pad2,.Lsie_fault)
365d0fc4107SMartin Schwidefsky	EX_TABLE(sie_exit,.Lsie_fault)
36626a374aeSMartin SchwidefskyENDPROC(sie64a)
367711f5df7SAl ViroEXPORT_SYMBOL(sie64a)
368711f5df7SAl ViroEXPORT_SYMBOL(sie_exit)
369d0fc4107SMartin Schwidefsky#endif
370d0fc4107SMartin Schwidefsky
3714bfc86ceSHeiko Carstens/*
3724bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and
3737b7735c5SChristian Borntraeger * are entered with interrupts disabled.
3744bfc86ceSHeiko Carstens */
3754bfc86ceSHeiko Carstens
3764bfc86ceSHeiko CarstensENTRY(system_call)
3774bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
3784bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
379d768bd89SMartin Schwidefsky	BPOFF
380d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
3814bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL
3824bfc86ceSHeiko Carstens.Lsysc_per:
383e64a1618SSven Schnelle	lghi	%r13,__TASK_thread
3844bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
3854bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)	# pointer to pt_regs
38634525e1fSMartin Schwidefsky	UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
3876b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
3884bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
3894bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
3904bfc86ceSHeiko Carstens	mvc	__PT_PSW(16,%r11),__LC_SVC_OLD_PSW
3914bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_SVC_ILC
3924bfc86ceSHeiko Carstens	stg	%r14,__PT_FLAGS(%r11)
3930b0ed657SSven Schnelle	ENABLE_INTS
3944bfc86ceSHeiko Carstens.Lsysc_do_svc:
395d3f46896SChristian Borntraeger	# clear user controlled register to prevent speculative use
396d3f46896SChristian Borntraeger	xgr	%r0,%r0
397ef280c85SMartin Schwidefsky	# load address of system call table
398ef280c85SMartin Schwidefsky	lg	%r10,__THREAD_sysc_table(%r13,%r12)
3994bfc86ceSHeiko Carstens	llgh	%r8,__PT_INT_CODE+2(%r11)
400ff4a742dSGerald Schaefer	slag	%r8,%r8,3			# shift and test for svc 0
4014bfc86ceSHeiko Carstens	jnz	.Lsysc_nr_ok
4024bfc86ceSHeiko Carstens	# svc 0: system call number in %r1
4034bfc86ceSHeiko Carstens	llgfr	%r1,%r1				# clear high word in r1
40400332c16SSven Schnelle	sth	%r1,__PT_INT_CODE+2(%r11)
4054bfc86ceSHeiko Carstens	cghi	%r1,NR_syscalls
4064bfc86ceSHeiko Carstens	jnl	.Lsysc_nr_ok
407ff4a742dSGerald Schaefer	slag	%r8,%r1,3
4084bfc86ceSHeiko Carstens.Lsysc_nr_ok:
4094bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
4104bfc86ceSHeiko Carstens	stg	%r2,__PT_ORIG_GPR2(%r11)
4114bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
412ff4a742dSGerald Schaefer	lg	%r9,0(%r8,%r10)			# get system call add.
41383abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
4144bfc86ceSHeiko Carstens	jnz	.Lsysc_tracesys
4156dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9			# call sys_xxxx
4164bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)		# store return value
4174bfc86ceSHeiko Carstens
4184bfc86ceSHeiko Carstens.Lsysc_return:
4199d6d99e3SHeiko Carstens#ifdef CONFIG_DEBUG_RSEQ
4209d6d99e3SHeiko Carstens	lgr	%r2,%r11
4219d6d99e3SHeiko Carstens	brasl	%r14,rseq_syscall
4229d6d99e3SHeiko Carstens#endif
4234bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
4244bfc86ceSHeiko Carstens.Lsysc_tif:
425ce9dfafeSHeiko Carstens	DISABLE_INTS
42683abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_WORK
4274bfc86ceSHeiko Carstens	jnz	.Lsysc_work
42883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
4294bfc86ceSHeiko Carstens	jnz	.Lsysc_work			# check for work
4300b0ed657SSven Schnelle	TSTMSK	__LC_CPU_FLAGS,(_CIF_WORK-_CIF_FPU)
4314bfc86ceSHeiko Carstens	jnz	.Lsysc_work
4326b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
4330b0ed657SSven Schnelle	TSTMSK	__LC_CPU_FLAGS, _CIF_FPU
4340b0ed657SSven Schnelle	jz	.Lsysc_skip_fpu
4350b0ed657SSven Schnelle	brasl	%r14,load_fpu_regs
4360b0ed657SSven Schnelle.Lsysc_skip_fpu:
4374bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
4384bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
4390b0ed657SSven Schnelle	lmg	%r0,%r15,__PT_R0(%r11)
4400b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
4414bfc86ceSHeiko Carstens
4424bfc86ceSHeiko Carstens#
4434bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
4444bfc86ceSHeiko Carstens#
4454bfc86ceSHeiko Carstens.Lsysc_work:
446ce9dfafeSHeiko Carstens	ENABLE_INTS
44783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
4484bfc86ceSHeiko Carstens	jo	.Lsysc_reschedule
44923fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
45023fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
4514bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
45283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_UPROBE
4534bfc86ceSHeiko Carstens	jo	.Lsysc_uprobe_notify
4544bfc86ceSHeiko Carstens#endif
455916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
456916cda1aSMartin Schwidefsky	jo	.Lsysc_guarded_storage
45783abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_PER_TRAP
4584bfc86ceSHeiko Carstens	jo	.Lsysc_singlestep
4592f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
4602f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
4612f09ca60SMiroslav Benes	jo	.Lsysc_patch_pending	# handle live patching just before
4622f09ca60SMiroslav Benes					# signals and possible syscall restart
4632f09ca60SMiroslav Benes#endif
46423fefe11SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL_RESTART
46523fefe11SMartin Schwidefsky	jo	.Lsysc_syscall_restart
46683abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
4674bfc86ceSHeiko Carstens	jo	.Lsysc_sigpending
46883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
4694bfc86ceSHeiko Carstens	jo	.Lsysc_notify_resume
470b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
471b5a882fcSHeiko Carstens	jnz	.Lsysc_asce
4720b0ed657SSven Schnelle	j	.Lsysc_return
4734bfc86ceSHeiko Carstens
4744bfc86ceSHeiko Carstens#
4754bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
4764bfc86ceSHeiko Carstens#
4774bfc86ceSHeiko Carstens.Lsysc_reschedule:
4784bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
4794bfc86ceSHeiko Carstens	jg	schedule
4804bfc86ceSHeiko Carstens
4814bfc86ceSHeiko Carstens#
4820aaba41bSMartin Schwidefsky# _CIF_ASCE_PRIMARY and/or _CIF_ASCE_SECONDARY set, load user space asce
4834bfc86ceSHeiko Carstens#
484b5a882fcSHeiko Carstens.Lsysc_asce:
4850aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
4860aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
4870aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
4880aaba41bSMartin Schwidefsky	jz	.Lsysc_return
4890aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
4900aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
4910aaba41bSMartin Schwidefsky	jnz	.Lsysc_set_fs_fixup
492606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
4934bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
4940aaba41bSMartin Schwidefsky	j	.Lsysc_return
4950aaba41bSMartin Schwidefsky.Lsysc_set_fs_fixup:
4960aaba41bSMartin Schwidefsky#endif
497b5a882fcSHeiko Carstens	larl	%r14,.Lsysc_return
498b5a882fcSHeiko Carstens	jg	set_fs_fixup
4994bfc86ceSHeiko Carstens
5009977e886SHendrik Brueckner
5019977e886SHendrik Brueckner#
5024bfc86ceSHeiko Carstens# _TIF_SIGPENDING is set, call do_signal
5034bfc86ceSHeiko Carstens#
5044bfc86ceSHeiko Carstens.Lsysc_sigpending:
5054bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5064bfc86ceSHeiko Carstens	brasl	%r14,do_signal
50783abeffbSHendrik Brueckner	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
5084bfc86ceSHeiko Carstens	jno	.Lsysc_return
50957d7f939SMartin Schwidefsky.Lsysc_do_syscall:
51057d7f939SMartin Schwidefsky	lghi	%r13,__TASK_thread
5114bfc86ceSHeiko Carstens	lmg	%r2,%r7,__PT_R2(%r11)	# load svc arguments
51257d7f939SMartin Schwidefsky	lghi	%r1,0			# svc 0 returns -ENOSYS
51357d7f939SMartin Schwidefsky	j	.Lsysc_do_svc
5144bfc86ceSHeiko Carstens
5154bfc86ceSHeiko Carstens#
5164bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME is set, call do_notify_resume
5174bfc86ceSHeiko Carstens#
5184bfc86ceSHeiko Carstens.Lsysc_notify_resume:
5194bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5204bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5214bfc86ceSHeiko Carstens	jg	do_notify_resume
5224bfc86ceSHeiko Carstens
5234bfc86ceSHeiko Carstens#
5244bfc86ceSHeiko Carstens# _TIF_UPROBE is set, call uprobe_notify_resume
5254bfc86ceSHeiko Carstens#
5264bfc86ceSHeiko Carstens#ifdef CONFIG_UPROBES
5274bfc86ceSHeiko Carstens.Lsysc_uprobe_notify:
5284bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5294bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5304bfc86ceSHeiko Carstens	jg	uprobe_notify_resume
5314bfc86ceSHeiko Carstens#endif
5324bfc86ceSHeiko Carstens
5334bfc86ceSHeiko Carstens#
534916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
535916cda1aSMartin Schwidefsky#
536916cda1aSMartin Schwidefsky.Lsysc_guarded_storage:
537916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
538916cda1aSMartin Schwidefsky	larl	%r14,.Lsysc_return
539916cda1aSMartin Schwidefsky	jg	gs_load_bc_cb
54076f1948aSLinus Torvalds#
5412f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
5422f09ca60SMiroslav Benes#
5432f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
5442f09ca60SMiroslav Benes.Lsysc_patch_pending:
5452f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
5462f09ca60SMiroslav Benes	larl	%r14,.Lsysc_return
5472f09ca60SMiroslav Benes	jg	klp_update_patch_state
5482f09ca60SMiroslav Benes#endif
549916cda1aSMartin Schwidefsky
550916cda1aSMartin Schwidefsky#
5514bfc86ceSHeiko Carstens# _PIF_PER_TRAP is set, call do_per_trap
5524bfc86ceSHeiko Carstens#
5534bfc86ceSHeiko Carstens.Lsysc_singlestep:
5544bfc86ceSHeiko Carstens	ni	__PT_FLAGS+7(%r11),255-_PIF_PER_TRAP
5554bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5564bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5574bfc86ceSHeiko Carstens	jg	do_per_trap
5584bfc86ceSHeiko Carstens
5594bfc86ceSHeiko Carstens#
56023fefe11SMartin Schwidefsky# _PIF_SYSCALL_RESTART is set, repeat the current system call
56123fefe11SMartin Schwidefsky#
56223fefe11SMartin Schwidefsky.Lsysc_syscall_restart:
56323fefe11SMartin Schwidefsky	ni	__PT_FLAGS+7(%r11),255-_PIF_SYSCALL_RESTART
56423fefe11SMartin Schwidefsky	lmg	%r1,%r7,__PT_R1(%r11)	# load svc arguments
56523fefe11SMartin Schwidefsky	lg	%r2,__PT_ORIG_GPR2(%r11)
56623fefe11SMartin Schwidefsky	j	.Lsysc_do_svc
56723fefe11SMartin Schwidefsky
56823fefe11SMartin Schwidefsky#
5694bfc86ceSHeiko Carstens# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
5704bfc86ceSHeiko Carstens# and after the system call
5714bfc86ceSHeiko Carstens#
5724bfc86ceSHeiko Carstens.Lsysc_tracesys:
5734bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5744bfc86ceSHeiko Carstens	la	%r3,0
5754bfc86ceSHeiko Carstens	llgh	%r0,__PT_INT_CODE+2(%r11)
5764bfc86ceSHeiko Carstens	stg	%r0,__PT_R2(%r11)
5774bfc86ceSHeiko Carstens	brasl	%r14,do_syscall_trace_enter
5784bfc86ceSHeiko Carstens	lghi	%r0,NR_syscalls
5794bfc86ceSHeiko Carstens	clgr	%r0,%r2
5804bfc86ceSHeiko Carstens	jnh	.Lsysc_tracenogo
581ff4a742dSGerald Schaefer	sllg	%r8,%r2,3
582ff4a742dSGerald Schaefer	lg	%r9,0(%r8,%r10)
5834bfc86ceSHeiko Carstens	lmg	%r3,%r7,__PT_R3(%r11)
5844bfc86ceSHeiko Carstens	stg	%r7,STACK_FRAME_OVERHEAD(%r15)
5854bfc86ceSHeiko Carstens	lg	%r2,__PT_ORIG_GPR2(%r11)
5866dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# call sys_xxx
5874bfc86ceSHeiko Carstens	stg	%r2,__PT_R2(%r11)	# store return value
5884bfc86ceSHeiko Carstens.Lsysc_tracenogo:
58983abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_TRACE
5904bfc86ceSHeiko Carstens	jz	.Lsysc_return
5914bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
5924bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_return
5934bfc86ceSHeiko Carstens	jg	do_syscall_trace_exit
59426a374aeSMartin SchwidefskyENDPROC(system_call)
5954bfc86ceSHeiko Carstens
5964bfc86ceSHeiko Carstens#
5974bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork
5984bfc86ceSHeiko Carstens#
5994bfc86ceSHeiko CarstensENTRY(ret_from_fork)
6004bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
601d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
6024bfc86ceSHeiko Carstens	brasl	%r14,schedule_tail
6034bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
6044bfc86ceSHeiko Carstens	jne	.Lsysc_tracenogo
6054bfc86ceSHeiko Carstens	# it's a kernel thread
6064bfc86ceSHeiko Carstens	lmg	%r9,%r10,__PT_R9(%r11)	# load gprs
60726a374aeSMartin Schwidefsky	la	%r2,0(%r10)
60826a374aeSMartin Schwidefsky	BASR_EX	%r14,%r9
60926a374aeSMartin Schwidefsky	j	.Lsysc_tracenogo
61026a374aeSMartin SchwidefskyENDPROC(ret_from_fork)
61126a374aeSMartin Schwidefsky
6124bfc86ceSHeiko CarstensENTRY(kernel_thread_starter)
6134bfc86ceSHeiko Carstens	la	%r2,0(%r10)
6146dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9
6154bfc86ceSHeiko Carstens	j	.Lsysc_tracenogo
61626a374aeSMartin SchwidefskyENDPROC(kernel_thread_starter)
6174bfc86ceSHeiko Carstens
6184bfc86ceSHeiko Carstens/*
6194bfc86ceSHeiko Carstens * Program check handler routine
6204bfc86ceSHeiko Carstens */
6214bfc86ceSHeiko Carstens
6224bfc86ceSHeiko CarstensENTRY(pgm_check_handler)
6234bfc86ceSHeiko Carstens	stpt	__LC_SYNC_ENTER_TIMER
624d768bd89SMartin Schwidefsky	BPOFF
6254bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
6264bfc86ceSHeiko Carstens	lg	%r10,__LC_LAST_BREAK
6270b38b5e1SSven Schnelle	srag	%r11,%r10,12
6280b38b5e1SSven Schnelle	jnz	0f
6290b38b5e1SSven Schnelle	/* if __LC_LAST_BREAK is < 4096, it contains one of
6300b38b5e1SSven Schnelle	 * the lpswe addresses in lowcore. Set it to 1 (initial state)
6310b38b5e1SSven Schnelle	 * to prevent leaking that address to userspace.
6320b38b5e1SSven Schnelle	 */
6330b38b5e1SSven Schnelle	lghi	%r10,1
6340b38b5e1SSven Schnelle0:	lg	%r12,__LC_CURRENT
635c771320eSMartin Schwidefsky	lghi	%r11,0
6364bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_PGM_OLD_PSW
6374bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# test problem state bit
6380b38b5e1SSven Schnelle	jnz	3f			# -> fault in user space
639d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
6400a5e2ec2SMartin Schwidefsky	# cleanup critical section for program checks in sie64a
641d0fc4107SMartin Schwidefsky	lgr	%r14,%r9
6420b0ed657SSven Schnelle	larl	%r13,.Lsie_gmap
6430b0ed657SSven Schnelle	slgr	%r14,%r13
6440b0ed657SSven Schnelle	lghi	%r13,.Lsie_done - .Lsie_gmap
6450b0ed657SSven Schnelle	clgr	%r14,%r13
6460b38b5e1SSven Schnelle	jhe	1f
64792fa7a13SMartin Schwidefsky	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer
6480a5e2ec2SMartin Schwidefsky	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
6490a5e2ec2SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
6500a5e2ec2SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
651c771320eSMartin Schwidefsky	lghi	%r11,_PIF_GUEST_FAULT
652d0fc4107SMartin Schwidefsky#endif
6530b38b5e1SSven Schnelle1:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
6540b38b5e1SSven Schnelle	jnz	2f			# -> enabled, can't be a double fault
6554bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
6564bfc86ceSHeiko Carstens	jnz	.Lpgm_svcper		# -> single stepped svc
6570b38b5e1SSven Schnelle2:	CHECK_STACK __LC_SAVE_AREA_SYNC
6584bfc86ceSHeiko Carstens	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
6590b38b5e1SSven Schnelle	# CHECK_VMAP_STACK branches to stack_overflow or 5f
6600b38b5e1SSven Schnelle	CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,5f
6610b38b5e1SSven Schnelle3:	UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
6626b73044bSMartin Schwidefsky	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
6634bfc86ceSHeiko Carstens	lg	%r15,__LC_KERNEL_STACK
664d5c352cdSHeiko Carstens	lgr	%r14,%r12
6653827ec3dSMartin Schwidefsky	aghi	%r14,__TASK_thread	# pointer to thread_struct
6664bfc86ceSHeiko Carstens	lghi	%r13,__LC_PGM_TDB
6674bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+2,0x02	# check for transaction abort
6680b38b5e1SSven Schnelle	jz	4f
6694bfc86ceSHeiko Carstens	mvc	__THREAD_trap_tdb(256,%r14),0(%r13)
6700b38b5e1SSven Schnelle4:	stg	%r10,__THREAD_last_break(%r14)
6710b38b5e1SSven Schnelle5:	lgr	%r13,%r11
672c771320eSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
6734bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
6747041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
6757041d281SMartin Schwidefsky	xgr	%r0,%r0
6767041d281SMartin Schwidefsky	xgr	%r1,%r1
6777041d281SMartin Schwidefsky	xgr	%r2,%r2
6787041d281SMartin Schwidefsky	xgr	%r3,%r3
6797041d281SMartin Schwidefsky	xgr	%r4,%r4
6807041d281SMartin Schwidefsky	xgr	%r5,%r5
6817041d281SMartin Schwidefsky	xgr	%r6,%r6
6827041d281SMartin Schwidefsky	xgr	%r7,%r7
6834bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
6844bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
6854bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_PGM_ILC
6864bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
687c771320eSMartin Schwidefsky	stg	%r13,__PT_FLAGS(%r11)
6884bfc86ceSHeiko Carstens	stg	%r10,__PT_ARGS(%r11)
6894bfc86ceSHeiko Carstens	tm	__LC_PGM_ILC+3,0x80	# check for per exception
6900b38b5e1SSven Schnelle	jz	6f
6914bfc86ceSHeiko Carstens	tmhh	%r8,0x0001		# kernel per event ?
6924bfc86ceSHeiko Carstens	jz	.Lpgm_kprobe
6934bfc86ceSHeiko Carstens	oi	__PT_FLAGS+7(%r11),_PIF_PER_TRAP
6944bfc86ceSHeiko Carstens	mvc	__THREAD_per_address(8,%r14),__LC_PER_ADDRESS
6954bfc86ceSHeiko Carstens	mvc	__THREAD_per_cause(2,%r14),__LC_PER_CODE
6964bfc86ceSHeiko Carstens	mvc	__THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID
6970b0ed657SSven Schnelle6:	RESTORE_SM_CLEAR_PER
6984bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
6994bfc86ceSHeiko Carstens	larl	%r1,pgm_check_table
7004bfc86ceSHeiko Carstens	llgh	%r10,__PT_INT_CODE+2(%r11)
7014bfc86ceSHeiko Carstens	nill	%r10,0x007f
702ff4a742dSGerald Schaefer	sll	%r10,3
703a359bb11SMartin Schwidefsky	je	.Lpgm_return
704ff4a742dSGerald Schaefer	lg	%r9,0(%r10,%r1)		# load address of handler routine
7054bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7066dd85fbbSMartin Schwidefsky	BASR_EX	%r14,%r9		# branch to interrupt-handler
707a359bb11SMartin Schwidefsky.Lpgm_return:
708a359bb11SMartin Schwidefsky	LOCKDEP_SYS_EXIT
709a359bb11SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
710*0cd9b723SHeiko Carstens	jno	.Lpgm_restore
71157d7f939SMartin Schwidefsky	TSTMSK	__PT_FLAGS(%r11),_PIF_SYSCALL
71257d7f939SMartin Schwidefsky	jo	.Lsysc_do_syscall
713a359bb11SMartin Schwidefsky	j	.Lsysc_tif
714*0cd9b723SHeiko Carstens.Lpgm_restore:
715*0cd9b723SHeiko Carstens	DISABLE_INTS
716*0cd9b723SHeiko Carstens	TSTMSK	__LC_CPU_FLAGS, _CIF_FPU
717*0cd9b723SHeiko Carstens	jz	.Lpgm_skip_fpu
718*0cd9b723SHeiko Carstens	brasl	%r14,load_fpu_regs
719*0cd9b723SHeiko Carstens.Lpgm_skip_fpu:
720*0cd9b723SHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
721*0cd9b723SHeiko Carstens	stpt	__LC_EXIT_TIMER
722*0cd9b723SHeiko Carstens	lmg	%r0,%r15,__PT_R0(%r11)
723*0cd9b723SHeiko Carstens	b	__LC_RETURN_LPSWE
7244bfc86ceSHeiko Carstens
7254bfc86ceSHeiko Carstens#
7264bfc86ceSHeiko Carstens# PER event in supervisor state, must be kprobes
7274bfc86ceSHeiko Carstens#
7284bfc86ceSHeiko Carstens.Lpgm_kprobe:
7290b0ed657SSven Schnelle	RESTORE_SM_CLEAR_PER
7304bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7314bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7324bfc86ceSHeiko Carstens	brasl	%r14,do_per_trap
733a359bb11SMartin Schwidefsky	j	.Lpgm_return
7344bfc86ceSHeiko Carstens
7354bfc86ceSHeiko Carstens#
7364bfc86ceSHeiko Carstens# single stepped system call
7374bfc86ceSHeiko Carstens#
7384bfc86ceSHeiko Carstens.Lpgm_svcper:
7394bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
7404bfc86ceSHeiko Carstens	larl	%r14,.Lsysc_per
7414bfc86ceSHeiko Carstens	stg	%r14,__LC_RETURN_PSW+8
7424bfc86ceSHeiko Carstens	lghi	%r14,_PIF_SYSCALL | _PIF_PER_TRAP
7430b0ed657SSven Schnelle	lpswe	__LC_RETURN_PSW		# branch to .Lsysc_per
74426a374aeSMartin SchwidefskyENDPROC(pgm_check_handler)
7454bfc86ceSHeiko Carstens
7464bfc86ceSHeiko Carstens/*
7474bfc86ceSHeiko Carstens * IO interrupt handler routine
7484bfc86ceSHeiko Carstens */
7494bfc86ceSHeiko CarstensENTRY(io_int_handler)
7504bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
7514bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
752d768bd89SMartin Schwidefsky	BPOFF
7534bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
754d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
7554bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_IO_OLD_PSW
7562acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
7574bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
7587041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
7597041d281SMartin Schwidefsky	xgr	%r0,%r0
7607041d281SMartin Schwidefsky	xgr	%r1,%r1
7617041d281SMartin Schwidefsky	xgr	%r2,%r2
7627041d281SMartin Schwidefsky	xgr	%r3,%r3
7637041d281SMartin Schwidefsky	xgr	%r4,%r4
7647041d281SMartin Schwidefsky	xgr	%r5,%r5
7657041d281SMartin Schwidefsky	xgr	%r6,%r6
7667041d281SMartin Schwidefsky	xgr	%r7,%r7
7677041d281SMartin Schwidefsky	xgr	%r10,%r10
7684bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
7694bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
7704bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7714bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
772db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
773db7e007fSHeiko Carstens	jo	.Lio_restore
7740b0ed657SSven Schnelle#if IS_ENABLED(CONFIG_TRACE_IRQFLAGS)
7750b0ed657SSven Schnelle	tmhh	%r8,0x300
7760b0ed657SSven Schnelle	jz	1f
7774bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
7780b0ed657SSven Schnelle1:
7790b0ed657SSven Schnelle#endif
7804bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
7814bfc86ceSHeiko Carstens.Lio_loop:
7824bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
7834bfc86ceSHeiko Carstens	lghi	%r3,IO_INTERRUPT
7844bfc86ceSHeiko Carstens	tm	__PT_INT_CODE+8(%r11),0x80	# adapter interrupt ?
7854bfc86ceSHeiko Carstens	jz	.Lio_call
7864bfc86ceSHeiko Carstens	lghi	%r3,THIN_INTERRUPT
7874bfc86ceSHeiko Carstens.Lio_call:
7884bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
78983abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_LPAR
7904bfc86ceSHeiko Carstens	jz	.Lio_return
7914bfc86ceSHeiko Carstens	tpi	0
7924bfc86ceSHeiko Carstens	jz	.Lio_return
7934bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
7944bfc86ceSHeiko Carstens	j	.Lio_loop
7954bfc86ceSHeiko Carstens.Lio_return:
7964bfc86ceSHeiko Carstens	LOCKDEP_SYS_EXIT
79783abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_WORK
7984bfc86ceSHeiko Carstens	jnz	.Lio_work		# there is work to do (signals etc.)
79983abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_WORK
8004bfc86ceSHeiko Carstens	jnz	.Lio_work
8014bfc86ceSHeiko Carstens.Lio_restore:
8020b0ed657SSven Schnelle#if IS_ENABLED(CONFIG_TRACE_IRQFLAGS)
8030b0ed657SSven Schnelle	tm	__PT_PSW(%r11),3
8040b0ed657SSven Schnelle	jno	0f
8050b0ed657SSven Schnelle	TRACE_IRQS_ON
8060b0ed657SSven Schnelle0:
8070b0ed657SSven Schnelle#endif
8084bfc86ceSHeiko Carstens	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
809d768bd89SMartin Schwidefsky	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
810d768bd89SMartin Schwidefsky	jno	.Lio_exit_kernel
8116b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
8124bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
813d768bd89SMartin Schwidefsky.Lio_exit_kernel:
8140b0ed657SSven Schnelle	lmg	%r0,%r15,__PT_R0(%r11)
8150b0ed657SSven Schnelle	b	__LC_RETURN_LPSWE
8164bfc86ceSHeiko Carstens.Lio_done:
8174bfc86ceSHeiko Carstens
8184bfc86ceSHeiko Carstens#
8194bfc86ceSHeiko Carstens# There is work todo, find out in which context we have been interrupted:
8204bfc86ceSHeiko Carstens# 1) if we return to user space we can do all _TIF_WORK work
8214bfc86ceSHeiko Carstens# 2) if we return to kernel code and kvm is enabled check if we need to
8224bfc86ceSHeiko Carstens#    modify the psw to leave SIE
8234bfc86ceSHeiko Carstens# 3) if we return to kernel code and preemptive scheduling is enabled check
8244bfc86ceSHeiko Carstens#    the preemption counter and if it is zero call preempt_schedule_irq
8254bfc86ceSHeiko Carstens# Before any work can be done, a switch to the kernel stack is required.
8264bfc86ceSHeiko Carstens#
8274bfc86ceSHeiko Carstens.Lio_work:
8284bfc86ceSHeiko Carstens	tm	__PT_PSW+1(%r11),0x01	# returning to user ?
8294bfc86ceSHeiko Carstens	jo	.Lio_work_user		# yes -> do resched & signal
830fa686453SThomas Gleixner#ifdef CONFIG_PREEMPTION
8314bfc86ceSHeiko Carstens	# check for preemptive scheduling
832c360192bSMartin Schwidefsky	icm	%r0,15,__LC_PREEMPT_COUNT
8334bfc86ceSHeiko Carstens	jnz	.Lio_restore		# preemption is disabled
83483abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8354bfc86ceSHeiko Carstens	jno	.Lio_restore
8364bfc86ceSHeiko Carstens	# switch to kernel stack
8374bfc86ceSHeiko Carstens	lg	%r1,__PT_R15(%r11)
8384bfc86ceSHeiko Carstens	aghi	%r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
8394bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8404bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8414bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8424bfc86ceSHeiko Carstens	lgr	%r15,%r1
8434bfc86ceSHeiko Carstens	brasl	%r14,preempt_schedule_irq
8444bfc86ceSHeiko Carstens	j	.Lio_return
8454bfc86ceSHeiko Carstens#else
8464bfc86ceSHeiko Carstens	j	.Lio_restore
8474bfc86ceSHeiko Carstens#endif
8484bfc86ceSHeiko Carstens
8494bfc86ceSHeiko Carstens#
8504bfc86ceSHeiko Carstens# Need to do work before returning to userspace, switch to kernel stack
8514bfc86ceSHeiko Carstens#
8524bfc86ceSHeiko Carstens.Lio_work_user:
8534bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK
8544bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
8554bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
8564bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
8574bfc86ceSHeiko Carstens	lgr	%r15,%r1
8584bfc86ceSHeiko Carstens
8594bfc86ceSHeiko Carstens#
8604bfc86ceSHeiko Carstens# One of the work bits is on. Find out which one.
8614bfc86ceSHeiko Carstens#
86283abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NEED_RESCHED
8634bfc86ceSHeiko Carstens	jo	.Lio_reschedule
8642f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
8652f09ca60SMiroslav Benes	TSTMSK	__TI_flags(%r12),_TIF_PATCH_PENDING
8662f09ca60SMiroslav Benes	jo	.Lio_patch_pending
8672f09ca60SMiroslav Benes#endif
86883abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_SIGPENDING
8694bfc86ceSHeiko Carstens	jo	.Lio_sigpending
87083abeffbSHendrik Brueckner	TSTMSK	__TI_flags(%r12),_TIF_NOTIFY_RESUME
8714bfc86ceSHeiko Carstens	jo	.Lio_notify_resume
872916cda1aSMartin Schwidefsky	TSTMSK	__TI_flags(%r12),_TIF_GUARDED_STORAGE
873916cda1aSMartin Schwidefsky	jo	.Lio_guarded_storage
87483abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
8759977e886SHendrik Brueckner	jo	.Lio_vxrs
876b5a882fcSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,(_CIF_ASCE_PRIMARY|_CIF_ASCE_SECONDARY)
877b5a882fcSHeiko Carstens	jnz	.Lio_asce
8784bfc86ceSHeiko Carstens	j	.Lio_return
8794bfc86ceSHeiko Carstens
8804bfc86ceSHeiko Carstens#
881b5a882fcSHeiko Carstens# _CIF_ASCE_PRIMARY and/or CIF_ASCE_SECONDARY set, load user space asce
8824bfc86ceSHeiko Carstens#
883b5a882fcSHeiko Carstens.Lio_asce:
8840aaba41bSMartin Schwidefsky	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_SECONDARY
8850aaba41bSMartin Schwidefsky	lctlg	%c7,%c7,__LC_VDSO_ASCE		# load secondary asce
8860aaba41bSMartin Schwidefsky	TSTMSK	__LC_CPU_FLAGS,_CIF_ASCE_PRIMARY
8870aaba41bSMartin Schwidefsky	jz	.Lio_return
8880aaba41bSMartin Schwidefsky#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES
8890aaba41bSMartin Schwidefsky	tm	__LC_STFLE_FAC_LIST+3,0x10	# has MVCOS ?
8900aaba41bSMartin Schwidefsky	jnz	.Lio_set_fs_fixup
891606aa4aaSHeiko Carstens	ni	__LC_CPU_FLAGS+7,255-_CIF_ASCE_PRIMARY
8924bfc86ceSHeiko Carstens	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
8930aaba41bSMartin Schwidefsky	j	.Lio_return
8940aaba41bSMartin Schwidefsky.Lio_set_fs_fixup:
8950aaba41bSMartin Schwidefsky#endif
896b5a882fcSHeiko Carstens	larl	%r14,.Lio_return
897b5a882fcSHeiko Carstens	jg	set_fs_fixup
8984bfc86ceSHeiko Carstens
8994bfc86ceSHeiko Carstens#
9009977e886SHendrik Brueckner# CIF_FPU is set, restore floating-point controls and floating-point registers.
9019977e886SHendrik Brueckner#
9029977e886SHendrik Brueckner.Lio_vxrs:
9039977e886SHendrik Brueckner	larl	%r14,.Lio_return
9049977e886SHendrik Brueckner	jg	load_fpu_regs
9059977e886SHendrik Brueckner
9069977e886SHendrik Brueckner#
907916cda1aSMartin Schwidefsky# _TIF_GUARDED_STORAGE is set, call guarded_storage_load
908916cda1aSMartin Schwidefsky#
909916cda1aSMartin Schwidefsky.Lio_guarded_storage:
9100b0ed657SSven Schnelle	ENABLE_INTS_TRACE
911916cda1aSMartin Schwidefsky	lgr	%r2,%r11		# pass pointer to pt_regs
912916cda1aSMartin Schwidefsky	brasl	%r14,gs_load_bc_cb
9130b0ed657SSven Schnelle	DISABLE_INTS_TRACE
914916cda1aSMartin Schwidefsky	j	.Lio_return
915916cda1aSMartin Schwidefsky
916916cda1aSMartin Schwidefsky#
9174bfc86ceSHeiko Carstens# _TIF_NEED_RESCHED is set, call schedule
9184bfc86ceSHeiko Carstens#
9194bfc86ceSHeiko Carstens.Lio_reschedule:
9200b0ed657SSven Schnelle	ENABLE_INTS_TRACE
9214bfc86ceSHeiko Carstens	brasl	%r14,schedule		# call scheduler
9220b0ed657SSven Schnelle	DISABLE_INTS_TRACE
9234bfc86ceSHeiko Carstens	j	.Lio_return
9244bfc86ceSHeiko Carstens
9254bfc86ceSHeiko Carstens#
9262f09ca60SMiroslav Benes# _TIF_PATCH_PENDING is set, call klp_update_patch_state
9272f09ca60SMiroslav Benes#
9282f09ca60SMiroslav Benes#ifdef CONFIG_LIVEPATCH
9292f09ca60SMiroslav Benes.Lio_patch_pending:
9302f09ca60SMiroslav Benes	lg	%r2,__LC_CURRENT	# pass pointer to task struct
9312f09ca60SMiroslav Benes	larl	%r14,.Lio_return
9322f09ca60SMiroslav Benes	jg	klp_update_patch_state
9332f09ca60SMiroslav Benes#endif
9342f09ca60SMiroslav Benes
9352f09ca60SMiroslav Benes#
9364bfc86ceSHeiko Carstens# _TIF_SIGPENDING or is set, call do_signal
9374bfc86ceSHeiko Carstens#
9384bfc86ceSHeiko Carstens.Lio_sigpending:
9390b0ed657SSven Schnelle	ENABLE_INTS_TRACE
9404bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9414bfc86ceSHeiko Carstens	brasl	%r14,do_signal
9420b0ed657SSven Schnelle	DISABLE_INTS_TRACE
9434bfc86ceSHeiko Carstens	j	.Lio_return
9444bfc86ceSHeiko Carstens
9454bfc86ceSHeiko Carstens#
9464bfc86ceSHeiko Carstens# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
9474bfc86ceSHeiko Carstens#
9484bfc86ceSHeiko Carstens.Lio_notify_resume:
9490b0ed657SSven Schnelle	ENABLE_INTS_TRACE
9504bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9514bfc86ceSHeiko Carstens	brasl	%r14,do_notify_resume
9520b0ed657SSven Schnelle	DISABLE_INTS_TRACE
9534bfc86ceSHeiko Carstens	j	.Lio_return
95426a374aeSMartin SchwidefskyENDPROC(io_int_handler)
9554bfc86ceSHeiko Carstens
9564bfc86ceSHeiko Carstens/*
9574bfc86ceSHeiko Carstens * External interrupt handler routine
9584bfc86ceSHeiko Carstens */
9594bfc86ceSHeiko CarstensENTRY(ext_int_handler)
9604bfc86ceSHeiko Carstens	STCK	__LC_INT_CLOCK
9614bfc86ceSHeiko Carstens	stpt	__LC_ASYNC_ENTER_TIMER
962d768bd89SMartin Schwidefsky	BPOFF
9634bfc86ceSHeiko Carstens	stmg	%r8,%r15,__LC_SAVE_AREA_ASYNC
964d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
9654bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_EXT_OLD_PSW
9662acb94f4SMartin Schwidefsky	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
9674bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
9687041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
9697041d281SMartin Schwidefsky	xgr	%r0,%r0
9707041d281SMartin Schwidefsky	xgr	%r1,%r1
9717041d281SMartin Schwidefsky	xgr	%r2,%r2
9727041d281SMartin Schwidefsky	xgr	%r3,%r3
9737041d281SMartin Schwidefsky	xgr	%r4,%r4
9747041d281SMartin Schwidefsky	xgr	%r5,%r5
9757041d281SMartin Schwidefsky	xgr	%r6,%r6
9767041d281SMartin Schwidefsky	xgr	%r7,%r7
9777041d281SMartin Schwidefsky	xgr	%r10,%r10
9784bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
9794bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
9804bfc86ceSHeiko Carstens	lghi	%r1,__LC_EXT_PARAMS2
9814bfc86ceSHeiko Carstens	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
9824bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
9834bfc86ceSHeiko Carstens	mvc	__PT_INT_PARM_LONG(8,%r11),0(%r1)
9844bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
985db7e007fSHeiko Carstens	TSTMSK	__LC_CPU_FLAGS,_CIF_IGNORE_IRQ
986db7e007fSHeiko Carstens	jo	.Lio_restore
9870b0ed657SSven Schnelle#if IS_ENABLED(CONFIG_TRACE_IRQFLAGS)
9880b0ed657SSven Schnelle	tmhh	%r8,0x300
9890b0ed657SSven Schnelle	jz	1f
9904bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
9910b0ed657SSven Schnelle1:
9920b0ed657SSven Schnelle#endif
9934bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
9944bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
9954bfc86ceSHeiko Carstens	lghi	%r3,EXT_INTERRUPT
9964bfc86ceSHeiko Carstens	brasl	%r14,do_IRQ
9974bfc86ceSHeiko Carstens	j	.Lio_return
99826a374aeSMartin SchwidefskyENDPROC(ext_int_handler)
9994bfc86ceSHeiko Carstens
10004bfc86ceSHeiko Carstens/*
10010b0ed657SSven Schnelle * Load idle PSW.
10024bfc86ceSHeiko Carstens */
10034bfc86ceSHeiko CarstensENTRY(psw_idle)
10044bfc86ceSHeiko Carstens	stg	%r3,__SF_EMPTY(%r15)
10050b0ed657SSven Schnelle	larl	%r1,.Lpsw_idle_exit
10064bfc86ceSHeiko Carstens	stg	%r1,__SF_EMPTY+8(%r15)
100772d38b19SMartin Schwidefsky	larl	%r1,smp_cpu_mtid
100872d38b19SMartin Schwidefsky	llgf	%r1,0(%r1)
100972d38b19SMartin Schwidefsky	ltgr	%r1,%r1
101072d38b19SMartin Schwidefsky	jz	.Lpsw_idle_stcctm
101172d38b19SMartin Schwidefsky	.insn	rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
101272d38b19SMartin Schwidefsky.Lpsw_idle_stcctm:
1013419123f9SMartin Schwidefsky	oi	__LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
1014d768bd89SMartin Schwidefsky	BPON
10154bfc86ceSHeiko Carstens	STCK	__CLOCK_IDLE_ENTER(%r2)
10164bfc86ceSHeiko Carstens	stpt	__TIMER_IDLE_ENTER(%r2)
10174bfc86ceSHeiko Carstens	lpswe	__SF_EMPTY(%r15)
10180b0ed657SSven Schnelle.Lpsw_idle_exit:
10196dd85fbbSMartin Schwidefsky	BR_EX	%r14
102026a374aeSMartin SchwidefskyENDPROC(psw_idle)
10214bfc86ceSHeiko Carstens
1022b5510d9bSHendrik Brueckner/*
1023b5510d9bSHendrik Brueckner * Store floating-point controls and floating-point or vector register
1024b5510d9bSHendrik Brueckner * depending whether the vector facility is available.	A critical section
1025b5510d9bSHendrik Brueckner * cleanup assures that the registers are stored even if interrupted for
1026b5510d9bSHendrik Brueckner * some other work.  The CIF_FPU flag is set to trigger a lazy restore
1027b5510d9bSHendrik Brueckner * of the register contents at return from io or a system call.
10289977e886SHendrik Brueckner */
10299977e886SHendrik BruecknerENTRY(save_fpu_regs)
10300b0ed657SSven Schnelle	stnsm	__SF_EMPTY(%r15),0xfc
1031d0164ee2SHendrik Brueckner	lg	%r2,__LC_CURRENT
1032d0164ee2SHendrik Brueckner	aghi	%r2,__TASK_thread
103383abeffbSHendrik Brueckner	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU
1034f19fbd5eSMartin Schwidefsky	jo	.Lsave_fpu_regs_exit
1035d0164ee2SHendrik Brueckner	stfpc	__THREAD_FPU_fpc(%r2)
1036d0164ee2SHendrik Brueckner	lg	%r3,__THREAD_FPU_regs(%r2)
103783abeffbSHendrik Brueckner	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
10389977e886SHendrik Brueckner	jz	.Lsave_fpu_regs_fp	  # no -> store FP regs
10399977e886SHendrik Brueckner	VSTM	%v0,%v15,0,%r3		  # vstm 0,15,0(3)
10409977e886SHendrik Brueckner	VSTM	%v16,%v31,256,%r3	  # vstm 16,31,256(3)
10419977e886SHendrik Brueckner	j	.Lsave_fpu_regs_done	  # -> set CIF_FPU flag
10429977e886SHendrik Brueckner.Lsave_fpu_regs_fp:
10439977e886SHendrik Brueckner	std	0,0(%r3)
10449977e886SHendrik Brueckner	std	1,8(%r3)
10459977e886SHendrik Brueckner	std	2,16(%r3)
10469977e886SHendrik Brueckner	std	3,24(%r3)
10479977e886SHendrik Brueckner	std	4,32(%r3)
10489977e886SHendrik Brueckner	std	5,40(%r3)
10499977e886SHendrik Brueckner	std	6,48(%r3)
10509977e886SHendrik Brueckner	std	7,56(%r3)
10519977e886SHendrik Brueckner	std	8,64(%r3)
10529977e886SHendrik Brueckner	std	9,72(%r3)
10539977e886SHendrik Brueckner	std	10,80(%r3)
10549977e886SHendrik Brueckner	std	11,88(%r3)
10559977e886SHendrik Brueckner	std	12,96(%r3)
10569977e886SHendrik Brueckner	std	13,104(%r3)
10579977e886SHendrik Brueckner	std	14,112(%r3)
10589977e886SHendrik Brueckner	std	15,120(%r3)
10599977e886SHendrik Brueckner.Lsave_fpu_regs_done:
10609977e886SHendrik Brueckner	oi	__LC_CPU_FLAGS+7,_CIF_FPU
1061f19fbd5eSMartin Schwidefsky.Lsave_fpu_regs_exit:
10620b0ed657SSven Schnelle	ssm	__SF_EMPTY(%r15)
10636dd85fbbSMartin Schwidefsky	BR_EX	%r14
10649977e886SHendrik Brueckner.Lsave_fpu_regs_end:
106526a374aeSMartin SchwidefskyENDPROC(save_fpu_regs)
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:
11106dd85fbbSMartin Schwidefsky	BR_EX	%r14
11119977e886SHendrik Brueckner.Lload_fpu_regs_end:
111226a374aeSMartin SchwidefskyENDPROC(load_fpu_regs)
11139977e886SHendrik Brueckner
11144bfc86ceSHeiko Carstens/*
11154bfc86ceSHeiko Carstens * Machine check handler routines
11164bfc86ceSHeiko Carstens */
11174bfc86ceSHeiko CarstensENTRY(mcck_int_handler)
11184bfc86ceSHeiko Carstens	STCK	__LC_MCCK_CLOCK
1119d768bd89SMartin Schwidefsky	BPOFF
11203037a52fSMartin Schwidefsky	la	%r1,4095		# validate r1
11213037a52fSMartin Schwidefsky	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# validate cpu timer
11223037a52fSMartin Schwidefsky	sckc	__LC_CLOCK_COMPARATOR			# validate comparator
11233037a52fSMartin Schwidefsky	lam	%a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs
11243037a52fSMartin Schwidefsky	lmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
1125d5c352cdSHeiko Carstens	lg	%r12,__LC_CURRENT
11264bfc86ceSHeiko Carstens	lmg	%r8,%r9,__LC_MCK_OLD_PSW
112783abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
11284bfc86ceSHeiko Carstens	jo	.Lmcck_panic		# yes -> rest of mcck code invalid
11293037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CR_VALID
11303037a52fSMartin Schwidefsky	jno	.Lmcck_panic		# control registers invalid -> panic
11313037a52fSMartin Schwidefsky	la	%r14,4095
11323037a52fSMartin Schwidefsky	lctlg	%c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
11333037a52fSMartin Schwidefsky	ptlb
11342a2d7befSVasily Gorbik	lg	%r11,__LC_MCESAD-4095(%r14) # extended machine check save area
11353037a52fSMartin Schwidefsky	nill	%r11,0xfc00		# MCESA_ORIGIN_MASK
11363037a52fSMartin Schwidefsky	TSTMSK	__LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE
11373037a52fSMartin Schwidefsky	jno	0f
11383037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_GS_VALID
11393037a52fSMartin Schwidefsky	jno	0f
11403037a52fSMartin Schwidefsky	.insn	 rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC
11413037a52fSMartin Schwidefsky0:	l	%r14,__LC_FP_CREG_SAVE_AREA-4095(%r14)
11423037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_FC_VALID
11433037a52fSMartin Schwidefsky	jo	0f
11443037a52fSMartin Schwidefsky	sr	%r14,%r14
11453037a52fSMartin Schwidefsky0:	sfpc	%r14
11463037a52fSMartin Schwidefsky	TSTMSK	__LC_MACHINE_FLAGS,MACHINE_FLAG_VX
11473037a52fSMartin Schwidefsky	jo	0f
11483037a52fSMartin Schwidefsky	lghi	%r14,__LC_FPREGS_SAVE_AREA
11493037a52fSMartin Schwidefsky	ld	%f0,0(%r14)
11503037a52fSMartin Schwidefsky	ld	%f1,8(%r14)
11513037a52fSMartin Schwidefsky	ld	%f2,16(%r14)
11523037a52fSMartin Schwidefsky	ld	%f3,24(%r14)
11533037a52fSMartin Schwidefsky	ld	%f4,32(%r14)
11543037a52fSMartin Schwidefsky	ld	%f5,40(%r14)
11553037a52fSMartin Schwidefsky	ld	%f6,48(%r14)
11563037a52fSMartin Schwidefsky	ld	%f7,56(%r14)
11573037a52fSMartin Schwidefsky	ld	%f8,64(%r14)
11583037a52fSMartin Schwidefsky	ld	%f9,72(%r14)
11593037a52fSMartin Schwidefsky	ld	%f10,80(%r14)
11603037a52fSMartin Schwidefsky	ld	%f11,88(%r14)
11613037a52fSMartin Schwidefsky	ld	%f12,96(%r14)
11623037a52fSMartin Schwidefsky	ld	%f13,104(%r14)
11633037a52fSMartin Schwidefsky	ld	%f14,112(%r14)
11643037a52fSMartin Schwidefsky	ld	%f15,120(%r14)
11653037a52fSMartin Schwidefsky	j	1f
11663037a52fSMartin Schwidefsky0:	VLM	%v0,%v15,0,%r11
11673037a52fSMartin Schwidefsky	VLM	%v16,%v31,256,%r11
11683037a52fSMartin Schwidefsky1:	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
11694bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
117083abeffbSHendrik Brueckner	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
11714bfc86ceSHeiko Carstens	jo	3f
11724bfc86ceSHeiko Carstens	la	%r14,__LC_SYNC_ENTER_TIMER
11734bfc86ceSHeiko Carstens	clc	0(8,%r14),__LC_ASYNC_ENTER_TIMER
11744bfc86ceSHeiko Carstens	jl	0f
11754bfc86ceSHeiko Carstens	la	%r14,__LC_ASYNC_ENTER_TIMER
11764bfc86ceSHeiko Carstens0:	clc	0(8,%r14),__LC_EXIT_TIMER
11774bfc86ceSHeiko Carstens	jl	1f
11784bfc86ceSHeiko Carstens	la	%r14,__LC_EXIT_TIMER
11794bfc86ceSHeiko Carstens1:	clc	0(8,%r14),__LC_LAST_UPDATE_TIMER
11804bfc86ceSHeiko Carstens	jl	2f
11814bfc86ceSHeiko Carstens	la	%r14,__LC_LAST_UPDATE_TIMER
11824bfc86ceSHeiko Carstens2:	spt	0(%r14)
11834bfc86ceSHeiko Carstens	mvc	__LC_MCCK_ENTER_TIMER(8),0(%r14)
11843037a52fSMartin Schwidefsky3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
11853037a52fSMartin Schwidefsky	jno	.Lmcck_panic
11863037a52fSMartin Schwidefsky	tmhh	%r8,0x0001		# interrupting from user ?
11873037a52fSMartin Schwidefsky	jnz	4f
11883037a52fSMartin Schwidefsky	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
11893037a52fSMartin Schwidefsky	jno	.Lmcck_panic
1190ce3dc447SMartin Schwidefsky4:	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
1191ce3dc447SMartin Schwidefsky	SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_MCCK_ENTER_TIMER
11924bfc86ceSHeiko Carstens.Lmcck_skip:
11934bfc86ceSHeiko Carstens	lghi	%r14,__LC_GPREGS_SAVE_AREA+64
11944bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
11957041d281SMartin Schwidefsky	# clear user controlled registers to prevent speculative use
11967041d281SMartin Schwidefsky	xgr	%r0,%r0
11977041d281SMartin Schwidefsky	xgr	%r1,%r1
11987041d281SMartin Schwidefsky	xgr	%r2,%r2
11997041d281SMartin Schwidefsky	xgr	%r3,%r3
12007041d281SMartin Schwidefsky	xgr	%r4,%r4
12017041d281SMartin Schwidefsky	xgr	%r5,%r5
12027041d281SMartin Schwidefsky	xgr	%r6,%r6
12037041d281SMartin Schwidefsky	xgr	%r7,%r7
12047041d281SMartin Schwidefsky	xgr	%r10,%r10
12054bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12064bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12074bfc86ceSHeiko Carstens	xc	__PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
12084bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12094bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12104bfc86ceSHeiko Carstens	brasl	%r14,s390_do_machine_check
12110b0ed657SSven Schnelle	cghi	%r2,0
12120b0ed657SSven Schnelle	je	.Lmcck_return
12134bfc86ceSHeiko Carstens	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
12144bfc86ceSHeiko Carstens	mvc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
12154bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
12164bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r1)
12174bfc86ceSHeiko Carstens	lgr	%r15,%r1
12184bfc86ceSHeiko Carstens	TRACE_IRQS_OFF
12194bfc86ceSHeiko Carstens	brasl	%r14,s390_handle_mcck
12204bfc86ceSHeiko Carstens	TRACE_IRQS_ON
12214bfc86ceSHeiko Carstens.Lmcck_return:
12224bfc86ceSHeiko Carstens	lmg	%r0,%r10,__PT_R0(%r11)
12234bfc86ceSHeiko Carstens	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
12244bfc86ceSHeiko Carstens	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
12254bfc86ceSHeiko Carstens	jno	0f
12266b73044bSMartin Schwidefsky	BPEXIT	__TI_flags(%r12),_TIF_ISOLATE_BP
12274bfc86ceSHeiko Carstens	stpt	__LC_EXIT_TIMER
12284bfc86ceSHeiko Carstens0:	lmg	%r11,%r15,__PT_R11(%r11)
12290b38b5e1SSven Schnelle	b	__LC_RETURN_MCCK_LPSWE
12304bfc86ceSHeiko Carstens
12314bfc86ceSHeiko Carstens.Lmcck_panic:
1232ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK
1233ce4dda3fSMartin Schwidefsky	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12344bfc86ceSHeiko Carstens	j	.Lmcck_skip
123526a374aeSMartin SchwidefskyENDPROC(mcck_int_handler)
12364bfc86ceSHeiko Carstens
12374bfc86ceSHeiko Carstens#
12384bfc86ceSHeiko Carstens# PSW restart interrupt handler
12394bfc86ceSHeiko Carstens#
12404bfc86ceSHeiko CarstensENTRY(restart_int_handler)
1241e5b98199SMartin Schwidefsky	ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
1242e5b98199SMartin Schwidefsky	stg	%r15,__LC_SAVE_AREA_RESTART
12434bfc86ceSHeiko Carstens	lg	%r15,__LC_RESTART_STACK
1244ce3dc447SMartin Schwidefsky	xc	STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
1245ce3dc447SMartin Schwidefsky	stmg	%r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
1246ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
1247ce3dc447SMartin Schwidefsky	mvc	STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
12484bfc86ceSHeiko Carstens	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
12494bfc86ceSHeiko Carstens	lg	%r1,__LC_RESTART_FN		# load fn, parm & source cpu
12504bfc86ceSHeiko Carstens	lg	%r2,__LC_RESTART_DATA
12514bfc86ceSHeiko Carstens	lg	%r3,__LC_RESTART_SOURCE
12524bfc86ceSHeiko Carstens	ltgr	%r3,%r3				# test source cpu address
12534bfc86ceSHeiko Carstens	jm	1f				# negative -> skip source stop
12544bfc86ceSHeiko Carstens0:	sigp	%r4,%r3,SIGP_SENSE		# sigp sense to source cpu
12554bfc86ceSHeiko Carstens	brc	10,0b				# wait for status stored
12564bfc86ceSHeiko Carstens1:	basr	%r14,%r1			# call function
12574bfc86ceSHeiko Carstens	stap	__SF_EMPTY(%r15)		# store cpu address
12584bfc86ceSHeiko Carstens	llgh	%r3,__SF_EMPTY(%r15)
12594bfc86ceSHeiko Carstens2:	sigp	%r4,%r3,SIGP_STOP		# sigp stop to current cpu
12604bfc86ceSHeiko Carstens	brc	2,2b
12614bfc86ceSHeiko Carstens3:	j	3b
126226a374aeSMartin SchwidefskyENDPROC(restart_int_handler)
12634bfc86ceSHeiko Carstens
12644bfc86ceSHeiko Carstens	.section .kprobes.text, "ax"
12654bfc86ceSHeiko Carstens
1266ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
12674bfc86ceSHeiko Carstens/*
12684bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead.
12694bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway.
12704bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace.
12714bfc86ceSHeiko Carstens */
127226a374aeSMartin SchwidefskyENTRY(stack_overflow)
1273ce3dc447SMartin Schwidefsky	lg	%r15,__LC_NODAT_STACK	# change to panic stack
12744bfc86ceSHeiko Carstens	la	%r11,STACK_FRAME_OVERHEAD(%r15)
12754bfc86ceSHeiko Carstens	stmg	%r0,%r7,__PT_R0(%r11)
12764bfc86ceSHeiko Carstens	stmg	%r8,%r9,__PT_PSW(%r11)
12774bfc86ceSHeiko Carstens	mvc	__PT_R8(64,%r11),0(%r14)
12784bfc86ceSHeiko Carstens	stg	%r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
12794bfc86ceSHeiko Carstens	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
12804bfc86ceSHeiko Carstens	lgr	%r2,%r11		# pass pointer to pt_regs
12814bfc86ceSHeiko Carstens	jg	kernel_stack_overflow
128226a374aeSMartin SchwidefskyENDPROC(stack_overflow)
12834bfc86ceSHeiko Carstens#endif
12844bfc86ceSHeiko Carstens
1285d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM)
1286d0fc4107SMartin Schwidefsky.Lcleanup_sie:
1287c929500dSQingFeng Hao	cghi	%r11,__LC_SAVE_AREA_ASYNC	#Is this in normal interrupt?
1288c929500dSQingFeng Hao	je	1f
12890b0ed657SSven Schnelle	larl	%r13,.Lsie_entry
12900b0ed657SSven Schnelle	slgr	%r9,%r13
12910b0ed657SSven Schnelle	larl	%r13,.Lsie_skip
12920b0ed657SSven Schnelle	clgr	%r9,%r13
1293c929500dSQingFeng Hao	jh	1f
1294c929500dSQingFeng Hao	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
129592fa7a13SMartin Schwidefsky1:	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
129692fa7a13SMartin Schwidefsky	lg	%r9,__SF_SIE_CONTROL(%r15)	# get control block pointer
1297e22cf8caSChristian Borntraeger	ni	__SIE_PROG0C+3(%r9),0xfe	# no longer in SIE
1298d0fc4107SMartin Schwidefsky	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
1299d0fc4107SMartin Schwidefsky	larl	%r9,sie_exit			# skip forward to sie_exit
1300891f6a72SChristian Borntraeger	BR_EX	%r14,%r11
13014bfc86ceSHeiko Carstens
13024bfc86ceSHeiko Carstens#endif
13034bfc86ceSHeiko Carstens	.section .rodata, "a"
1304ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390x_ ## esame
13054bfc86ceSHeiko Carstens	.globl	sys_call_table
13064bfc86ceSHeiko Carstenssys_call_table:
13074381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
13084bfc86ceSHeiko Carstens#undef SYSCALL
13094bfc86ceSHeiko Carstens
13104bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT
13114bfc86ceSHeiko Carstens
1312ff4a742dSGerald Schaefer#define SYSCALL(esame,emu)	.quad __s390_ ## emu
13134bfc86ceSHeiko Carstens	.globl	sys_call_table_emu
13144bfc86ceSHeiko Carstenssys_call_table_emu:
13154381f9f1SHendrik Brueckner#include "asm/syscall_table.h"
13164bfc86ceSHeiko Carstens#undef SYSCALL
13174bfc86ceSHeiko Carstens#endif
1318