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