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> 17dc24b7b4SHendrik Brueckner#include <asm/dwarf.h> 184bfc86ceSHeiko Carstens#include <asm/errno.h> 194bfc86ceSHeiko Carstens#include <asm/ptrace.h> 204bfc86ceSHeiko Carstens#include <asm/thread_info.h> 214bfc86ceSHeiko Carstens#include <asm/asm-offsets.h> 224bfc86ceSHeiko Carstens#include <asm/unistd.h> 234bfc86ceSHeiko Carstens#include <asm/page.h> 244bfc86ceSHeiko Carstens#include <asm/sigp.h> 254bfc86ceSHeiko Carstens#include <asm/irq.h> 269977e886SHendrik Brueckner#include <asm/vx-insn.h> 2783abeffbSHendrik Brueckner#include <asm/setup.h> 2883abeffbSHendrik Brueckner#include <asm/nmi.h> 29711f5df7SAl Viro#include <asm/export.h> 306dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h> 314bfc86ceSHeiko Carstens 324bfc86ceSHeiko Carstens__PT_R0 = __PT_GPRS 334bfc86ceSHeiko Carstens__PT_R1 = __PT_GPRS + 8 344bfc86ceSHeiko Carstens__PT_R2 = __PT_GPRS + 16 354bfc86ceSHeiko Carstens__PT_R3 = __PT_GPRS + 24 364bfc86ceSHeiko Carstens__PT_R4 = __PT_GPRS + 32 374bfc86ceSHeiko Carstens__PT_R5 = __PT_GPRS + 40 384bfc86ceSHeiko Carstens__PT_R6 = __PT_GPRS + 48 394bfc86ceSHeiko Carstens__PT_R7 = __PT_GPRS + 56 404bfc86ceSHeiko Carstens__PT_R8 = __PT_GPRS + 64 414bfc86ceSHeiko Carstens__PT_R9 = __PT_GPRS + 72 424bfc86ceSHeiko Carstens__PT_R10 = __PT_GPRS + 80 434bfc86ceSHeiko Carstens__PT_R11 = __PT_GPRS + 88 444bfc86ceSHeiko Carstens__PT_R12 = __PT_GPRS + 96 454bfc86ceSHeiko Carstens__PT_R13 = __PT_GPRS + 104 464bfc86ceSHeiko Carstens__PT_R14 = __PT_GPRS + 112 474bfc86ceSHeiko Carstens__PT_R15 = __PT_GPRS + 120 484bfc86ceSHeiko Carstens 493a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER 504bfc86ceSHeiko CarstensSTACK_SIZE = 1 << STACK_SHIFT 514bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE 524bfc86ceSHeiko Carstens 53e5b98199SMartin Schwidefsky_LPP_OFFSET = __LC_LPP 54e5b98199SMartin Schwidefsky 55*3b051e89SSven Schnelle .macro STBEAR address 56*3b051e89SSven Schnelle ALTERNATIVE "", ".insn s,0xb2010000,\address", 193 57*3b051e89SSven Schnelle .endm 58*3b051e89SSven Schnelle 59*3b051e89SSven Schnelle .macro LBEAR address 60*3b051e89SSven Schnelle ALTERNATIVE "", ".insn s,0xb2000000,\address", 193 61*3b051e89SSven Schnelle .endm 62*3b051e89SSven Schnelle 63*3b051e89SSven Schnelle .macro LPSWEY address,lpswe 64*3b051e89SSven Schnelle ALTERNATIVE "b \lpswe", ".insn siy,0xeb0000000071,\address,0", 193 65*3b051e89SSven Schnelle .endm 66*3b051e89SSven Schnelle 67*3b051e89SSven Schnelle .macro MBEAR reg 68*3b051e89SSven Schnelle ALTERNATIVE "", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193 69*3b051e89SSven Schnelle .endm 70*3b051e89SSven Schnelle 71ce3dc447SMartin Schwidefsky .macro CHECK_STACK savearea 724bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK 73ce3dc447SMartin Schwidefsky tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 744bfc86ceSHeiko Carstens lghi %r14,\savearea 754bfc86ceSHeiko Carstens jz stack_overflow 764bfc86ceSHeiko Carstens#endif 774bfc86ceSHeiko Carstens .endm 784bfc86ceSHeiko Carstens 79ce3dc447SMartin Schwidefsky .macro CHECK_VMAP_STACK savearea,oklabel 80ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK 81ce3dc447SMartin Schwidefsky lgr %r14,%r15 82ce3dc447SMartin Schwidefsky nill %r14,0x10000 - STACK_SIZE 83ce3dc447SMartin Schwidefsky oill %r14,STACK_INIT 84ce3dc447SMartin Schwidefsky clg %r14,__LC_KERNEL_STACK 85ce3dc447SMartin Schwidefsky je \oklabel 86ce3dc447SMartin Schwidefsky clg %r14,__LC_ASYNC_STACK 87ce3dc447SMartin Schwidefsky je \oklabel 88b61b1595SSven Schnelle clg %r14,__LC_MCCK_STACK 89b61b1595SSven Schnelle je \oklabel 90ce3dc447SMartin Schwidefsky clg %r14,__LC_NODAT_STACK 91ce3dc447SMartin Schwidefsky je \oklabel 92ce3dc447SMartin Schwidefsky clg %r14,__LC_RESTART_STACK 93ce3dc447SMartin Schwidefsky je \oklabel 94ce3dc447SMartin Schwidefsky lghi %r14,\savearea 95ce3dc447SMartin Schwidefsky j stack_overflow 96ce3dc447SMartin Schwidefsky#else 97ce3dc447SMartin Schwidefsky j \oklabel 98ce3dc447SMartin Schwidefsky#endif 99ce3dc447SMartin Schwidefsky .endm 100ce3dc447SMartin Schwidefsky 1014bfc86ceSHeiko Carstens .macro STCK savearea 10278f65709SHeiko Carstens ALTERNATIVE ".insn s,0xb2050000,\savearea", \ 10378f65709SHeiko Carstens ".insn s,0xb27c0000,\savearea", 25 1044bfc86ceSHeiko Carstens .endm 1054bfc86ceSHeiko Carstens 10683abeffbSHendrik Brueckner /* 10783abeffbSHendrik Brueckner * The TSTMSK macro generates a test-under-mask instruction by 10883abeffbSHendrik Brueckner * calculating the memory offset for the specified mask value. 10983abeffbSHendrik Brueckner * Mask value can be any constant. The macro shifts the mask 11083abeffbSHendrik Brueckner * value to calculate the memory offset for the test-under-mask 11183abeffbSHendrik Brueckner * instruction. 11283abeffbSHendrik Brueckner */ 11383abeffbSHendrik Brueckner .macro TSTMSK addr, mask, size=8, bytepos=0 11483abeffbSHendrik Brueckner .if (\bytepos < \size) && (\mask >> 8) 11583abeffbSHendrik Brueckner .if (\mask & 0xff) 11683abeffbSHendrik Brueckner .error "Mask exceeds byte boundary" 11783abeffbSHendrik Brueckner .endif 11883abeffbSHendrik Brueckner TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)" 11983abeffbSHendrik Brueckner .exitm 12083abeffbSHendrik Brueckner .endif 12183abeffbSHendrik Brueckner .ifeq \mask 12283abeffbSHendrik Brueckner .error "Mask must not be zero" 12383abeffbSHendrik Brueckner .endif 12483abeffbSHendrik Brueckner off = \size - \bytepos - 1 12583abeffbSHendrik Brueckner tm off+\addr, \mask 12683abeffbSHendrik Brueckner .endm 12783abeffbSHendrik Brueckner 128d768bd89SMartin Schwidefsky .macro BPOFF 129b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8c000", 82 130d768bd89SMartin Schwidefsky .endm 131d768bd89SMartin Schwidefsky 132d768bd89SMartin Schwidefsky .macro BPON 133b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8d000", 82 134d768bd89SMartin Schwidefsky .endm 135d768bd89SMartin Schwidefsky 1366b73044bSMartin Schwidefsky .macro BPENTER tif_ptr,tif_mask 137b058661aSMartin Schwidefsky ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \ 138b058661aSMartin Schwidefsky "", 82 1396b73044bSMartin Schwidefsky .endm 1406b73044bSMartin Schwidefsky 1416b73044bSMartin Schwidefsky .macro BPEXIT tif_ptr,tif_mask 1426b73044bSMartin Schwidefsky TSTMSK \tif_ptr,\tif_mask 143b058661aSMartin Schwidefsky ALTERNATIVE "jz .+8; .long 0xb2e8c000", \ 144b058661aSMartin Schwidefsky "jnz .+8; .long 0xb2e8d000", 82 1456b73044bSMartin Schwidefsky .endm 1466b73044bSMartin Schwidefsky 147d35925b3SAlexander Gordeev /* 148d35925b3SAlexander Gordeev * The CHKSTG macro jumps to the provided label in case the 149d35925b3SAlexander Gordeev * machine check interruption code reports one of unrecoverable 150d35925b3SAlexander Gordeev * storage errors: 151d35925b3SAlexander Gordeev * - Storage error uncorrected 152d35925b3SAlexander Gordeev * - Storage key error uncorrected 153d35925b3SAlexander Gordeev * - Storage degradation with Failing-storage-address validity 154d35925b3SAlexander Gordeev */ 155d35925b3SAlexander Gordeev .macro CHKSTG errlabel 156d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR) 157d35925b3SAlexander Gordeev jnz \errlabel 158d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD 15915256194SHeiko Carstens jz .Loklabel\@ 160d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR 161d35925b3SAlexander Gordeev jnz \errlabel 16215256194SHeiko Carstens.Loklabel\@: 163d35925b3SAlexander Gordeev .endm 164d35925b3SAlexander Gordeev 165b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM) 166b5415c8fSAlexander Gordeev /* 167b5415c8fSAlexander Gordeev * The OUTSIDE macro jumps to the provided label in case the value 168b5415c8fSAlexander Gordeev * in the provided register is outside of the provided range. The 169b5415c8fSAlexander Gordeev * macro is useful for checking whether a PSW stored in a register 170b5415c8fSAlexander Gordeev * pair points inside or outside of a block of instructions. 171b5415c8fSAlexander Gordeev * @reg: register to check 172b5415c8fSAlexander Gordeev * @start: start of the range 173b5415c8fSAlexander Gordeev * @end: end of the range 174b5415c8fSAlexander Gordeev * @outside_label: jump here if @reg is outside of [@start..@end) 175b5415c8fSAlexander Gordeev */ 176b5415c8fSAlexander Gordeev .macro OUTSIDE reg,start,end,outside_label 177b5415c8fSAlexander Gordeev lgr %r14,\reg 178b5415c8fSAlexander Gordeev larl %r13,\start 179b5415c8fSAlexander Gordeev slgr %r14,%r13 180b5415c8fSAlexander Gordeev lghi %r13,\end - \start 181b5415c8fSAlexander Gordeev clgr %r14,%r13 182b5415c8fSAlexander Gordeev jhe \outside_label 183b5415c8fSAlexander Gordeev .endm 184fbbdfca5SAlexander Gordeev 185fbbdfca5SAlexander Gordeev .macro SIEEXIT 186fbbdfca5SAlexander Gordeev lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer 187fbbdfca5SAlexander Gordeev ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 188fbbdfca5SAlexander Gordeev lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 189fbbdfca5SAlexander Gordeev larl %r9,sie_exit # skip forward to sie_exit 190fbbdfca5SAlexander Gordeev .endm 191b5415c8fSAlexander Gordeev#endif 192b5415c8fSAlexander Gordeev 1936dd85fbbSMartin Schwidefsky GEN_BR_THUNK %r14 19433ea0487SSven Schnelle GEN_BR_THUNK %r14,%r13 195f19fbd5eSMartin Schwidefsky 1964bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 19746210c44SHeiko Carstens.Ldummy: 19846210c44SHeiko Carstens /* 19956e62a73SSven Schnelle * This nop exists only in order to avoid that __bpon starts at 20046210c44SHeiko Carstens * the beginning of the kprobes text section. In that case we would 20146210c44SHeiko Carstens * have several symbols at the same address. E.g. objdump would take 20246210c44SHeiko Carstens * an arbitrary symbol name when disassembling this code. 20356e62a73SSven Schnelle * With the added nop in between the __bpon symbol is unique 20446210c44SHeiko Carstens * again. 20546210c44SHeiko Carstens */ 20646210c44SHeiko Carstens nop 0 2074bfc86ceSHeiko Carstens 208d768bd89SMartin SchwidefskyENTRY(__bpon) 209d768bd89SMartin Schwidefsky .globl __bpon 210d768bd89SMartin Schwidefsky BPON 2116dd85fbbSMartin Schwidefsky BR_EX %r14 21226a374aeSMartin SchwidefskyENDPROC(__bpon) 213d768bd89SMartin Schwidefsky 2144bfc86ceSHeiko Carstens/* 2154bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to 2164bfc86ceSHeiko Carstens * gpr2 = (task_struct *) prev 2174bfc86ceSHeiko Carstens * gpr3 = (task_struct *) next 2184bfc86ceSHeiko Carstens * Returns: 2194bfc86ceSHeiko Carstens * gpr2 = prev 2204bfc86ceSHeiko Carstens */ 2214bfc86ceSHeiko CarstensENTRY(__switch_to) 2224bfc86ceSHeiko Carstens stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 2233241d3ebSHeiko Carstens lghi %r4,__TASK_stack 2243241d3ebSHeiko Carstens lghi %r1,__TASK_thread 2259fed920eSVasily Gorbik llill %r5,STACK_INIT 2263241d3ebSHeiko Carstens stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev 2279fed920eSVasily Gorbik lg %r15,0(%r4,%r3) # start of kernel stack of next 2289fed920eSVasily Gorbik agr %r15,%r5 # end of kernel stack of next 2294bfc86ceSHeiko Carstens stg %r3,__LC_CURRENT # store task struct of next 2304bfc86ceSHeiko Carstens stg %r15,__LC_KERNEL_STACK # store end of kernel stack 2313241d3ebSHeiko Carstens lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next 2323241d3ebSHeiko Carstens aghi %r3,__TASK_pid 2333241d3ebSHeiko Carstens mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 2344bfc86ceSHeiko Carstens lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 235e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 2366dd85fbbSMartin Schwidefsky BR_EX %r14 23726a374aeSMartin SchwidefskyENDPROC(__switch_to) 2384bfc86ceSHeiko Carstens 239d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 240d0fc4107SMartin Schwidefsky/* 241d0fc4107SMartin Schwidefsky * sie64a calling convention: 242d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block 243d0fc4107SMartin Schwidefsky * %r3 guest register save area 244d0fc4107SMartin Schwidefsky */ 245d0fc4107SMartin SchwidefskyENTRY(sie64a) 246d0fc4107SMartin Schwidefsky stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 2476b73044bSMartin Schwidefsky lg %r12,__LC_CURRENT 24892fa7a13SMartin Schwidefsky stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer 24992fa7a13SMartin Schwidefsky stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area 25092fa7a13SMartin Schwidefsky xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 25192fa7a13SMartin Schwidefsky mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 252d0fc4107SMartin Schwidefsky lmg %r0,%r13,0(%r3) # load guest gprs 0-13 253d0fc4107SMartin Schwidefsky lg %r14,__LC_GMAP # get gmap pointer 254d0fc4107SMartin Schwidefsky ltgr %r14,%r14 255d0fc4107SMartin Schwidefsky jz .Lsie_gmap 256d0fc4107SMartin Schwidefsky lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 257d0fc4107SMartin Schwidefsky.Lsie_gmap: 25892fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 259d0fc4107SMartin Schwidefsky oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 260d0fc4107SMartin Schwidefsky tm __SIE_PROG20+3(%r14),3 # last exit... 261d0fc4107SMartin Schwidefsky jnz .Lsie_skip 26283abeffbSHendrik Brueckner TSTMSK __LC_CPU_FLAGS,_CIF_FPU 263d0fc4107SMartin Schwidefsky jo .Lsie_skip # exit if fp/vx regs changed 26492fa7a13SMartin Schwidefsky BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 265c929500dSQingFeng Hao.Lsie_entry: 266d0fc4107SMartin Schwidefsky sie 0(%r14) 267d768bd89SMartin Schwidefsky BPOFF 26892fa7a13SMartin Schwidefsky BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 269d0fc4107SMartin Schwidefsky.Lsie_skip: 270d0fc4107SMartin Schwidefsky ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 27187d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 272d0fc4107SMartin Schwidefsky.Lsie_done: 273d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception) 274c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There 275c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. 276c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program 277c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. 278c0e7bb38SChristian Borntraeger.Lrewind_pad6: 279c0e7bb38SChristian Borntraeger nopr 7 280c0e7bb38SChristian Borntraeger.Lrewind_pad4: 281c0e7bb38SChristian Borntraeger nopr 7 282c0e7bb38SChristian Borntraeger.Lrewind_pad2: 283c0e7bb38SChristian Borntraeger nopr 7 284d0fc4107SMartin Schwidefsky .globl sie_exit 285d0fc4107SMartin Schwidefskysie_exit: 28692fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area 287d0fc4107SMartin Schwidefsky stmg %r0,%r13,0(%r14) # save guest gprs 0-13 2887041d281SMartin Schwidefsky xgr %r0,%r0 # clear guest registers to 2897041d281SMartin Schwidefsky xgr %r1,%r1 # prevent speculative use 2907041d281SMartin Schwidefsky xgr %r3,%r3 2917041d281SMartin Schwidefsky xgr %r4,%r4 2927041d281SMartin Schwidefsky xgr %r5,%r5 293d0fc4107SMartin Schwidefsky lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 29492fa7a13SMartin Schwidefsky lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 2956dd85fbbSMartin Schwidefsky BR_EX %r14 296d0fc4107SMartin Schwidefsky.Lsie_fault: 297d0fc4107SMartin Schwidefsky lghi %r14,-EFAULT 29892fa7a13SMartin Schwidefsky stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 299d0fc4107SMartin Schwidefsky j sie_exit 300d0fc4107SMartin Schwidefsky 301c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad6,.Lsie_fault) 302c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad4,.Lsie_fault) 303c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad2,.Lsie_fault) 304d0fc4107SMartin Schwidefsky EX_TABLE(sie_exit,.Lsie_fault) 30526a374aeSMartin SchwidefskyENDPROC(sie64a) 306711f5df7SAl ViroEXPORT_SYMBOL(sie64a) 307711f5df7SAl ViroEXPORT_SYMBOL(sie_exit) 308d0fc4107SMartin Schwidefsky#endif 309d0fc4107SMartin Schwidefsky 3104bfc86ceSHeiko Carstens/* 3114bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and 3127b7735c5SChristian Borntraeger * are entered with interrupts disabled. 3134bfc86ceSHeiko Carstens */ 3144bfc86ceSHeiko Carstens 3154bfc86ceSHeiko CarstensENTRY(system_call) 31656e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 3174bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 318d768bd89SMartin Schwidefsky BPOFF 31956e62a73SSven Schnelle lghi %r14,0 3204bfc86ceSHeiko Carstens.Lsysc_per: 321*3b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 32287d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 32356e62a73SSven Schnelle lg %r12,__LC_CURRENT 3244bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 3259365965dSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 32656e62a73SSven Schnelle stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 32756e62a73SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 328d3f46896SChristian Borntraeger # clear user controlled register to prevent speculative use 329d3f46896SChristian Borntraeger xgr %r0,%r0 33056e62a73SSven Schnelle xgr %r1,%r1 33156e62a73SSven Schnelle xgr %r4,%r4 33256e62a73SSven Schnelle xgr %r5,%r5 33356e62a73SSven Schnelle xgr %r6,%r6 33456e62a73SSven Schnelle xgr %r7,%r7 33556e62a73SSven Schnelle xgr %r8,%r8 33656e62a73SSven Schnelle xgr %r9,%r9 33756e62a73SSven Schnelle xgr %r10,%r10 33856e62a73SSven Schnelle xgr %r11,%r11 33956e62a73SSven Schnelle la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 340af9ad822SSven Schnelle mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC 341*3b051e89SSven Schnelle MBEAR %r2 34256e62a73SSven Schnelle lgr %r3,%r14 34356e62a73SSven Schnelle brasl %r14,__do_syscall 34487d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 34556e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3466b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 347*3b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 34856e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3494bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 350*3b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 35126a374aeSMartin SchwidefskyENDPROC(system_call) 3524bfc86ceSHeiko Carstens 3534bfc86ceSHeiko Carstens# 3544bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork 3554bfc86ceSHeiko Carstens# 3564bfc86ceSHeiko CarstensENTRY(ret_from_fork) 35756e62a73SSven Schnelle lgr %r3,%r11 35856e62a73SSven Schnelle brasl %r14,__ret_from_fork 35956e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 36056e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 36156e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 362*3b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 36356e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 36456e62a73SSven Schnelle stpt __LC_EXIT_TIMER 365*3b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 36626a374aeSMartin SchwidefskyENDPROC(ret_from_fork) 36726a374aeSMartin Schwidefsky 3684bfc86ceSHeiko Carstens/* 3694bfc86ceSHeiko Carstens * Program check handler routine 3704bfc86ceSHeiko Carstens */ 3714bfc86ceSHeiko Carstens 3724bfc86ceSHeiko CarstensENTRY(pgm_check_handler) 37356e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 374d768bd89SMartin Schwidefsky BPOFF 3754bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 37656e62a73SSven Schnelle lg %r12,__LC_CURRENT 37756e62a73SSven Schnelle lghi %r10,0 3784bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_PGM_OLD_PSW 37987d59863SHeiko Carstens tmhh %r8,0x0001 # coming from user space? 38087d59863SHeiko Carstens jno .Lpgm_skip_asce 38187d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 38256e62a73SSven Schnelle j 3f # -> fault in user space 38387d59863SHeiko Carstens.Lpgm_skip_asce: 384d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 3850a5e2ec2SMartin Schwidefsky # cleanup critical section for program checks in sie64a 386b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f 387fbbdfca5SAlexander Gordeev SIEEXIT 38856e62a73SSven Schnelle lghi %r10,_PIF_GUEST_FAULT 389d0fc4107SMartin Schwidefsky#endif 3900b38b5e1SSven Schnelle1: tmhh %r8,0x4000 # PER bit set in old PSW ? 3910b38b5e1SSven Schnelle jnz 2f # -> enabled, can't be a double fault 3924bfc86ceSHeiko Carstens tm __LC_PGM_ILC+3,0x80 # check for per exception 3934bfc86ceSHeiko Carstens jnz .Lpgm_svcper # -> single stepped svc 3940b38b5e1SSven Schnelle2: CHECK_STACK __LC_SAVE_AREA_SYNC 3954bfc86ceSHeiko Carstens aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 39656e62a73SSven Schnelle # CHECK_VMAP_STACK branches to stack_overflow or 4f 39756e62a73SSven Schnelle CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f 39856e62a73SSven Schnelle3: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 3994bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 40056e62a73SSven Schnelle4: la %r11,STACK_FRAME_OVERHEAD(%r15) 40156e62a73SSven Schnelle stg %r10,__PT_FLAGS(%r11) 40256e62a73SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 4034bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 40456e62a73SSven Schnelle mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC 405*3b051e89SSven Schnelle mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK 40656e62a73SSven Schnelle stmg %r8,%r9,__PT_PSW(%r11) 40756e62a73SSven Schnelle 4087041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4097041d281SMartin Schwidefsky xgr %r0,%r0 4107041d281SMartin Schwidefsky xgr %r1,%r1 4117041d281SMartin Schwidefsky xgr %r3,%r3 4127041d281SMartin Schwidefsky xgr %r4,%r4 4137041d281SMartin Schwidefsky xgr %r5,%r5 4147041d281SMartin Schwidefsky xgr %r6,%r6 4157041d281SMartin Schwidefsky xgr %r7,%r7 41656e62a73SSven Schnelle lgr %r2,%r11 41756e62a73SSven Schnelle brasl %r14,__do_pgm_check 41856e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user space? 41956e62a73SSven Schnelle jno .Lpgm_exit_kernel 42056e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 42156e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4220cd9b723SHeiko Carstens stpt __LC_EXIT_TIMER 42356e62a73SSven Schnelle.Lpgm_exit_kernel: 42456e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 425*3b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 42656e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 427*3b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 4284bfc86ceSHeiko Carstens 4294bfc86ceSHeiko Carstens# 4304bfc86ceSHeiko Carstens# single stepped system call 4314bfc86ceSHeiko Carstens# 4324bfc86ceSHeiko Carstens.Lpgm_svcper: 4334bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 4344bfc86ceSHeiko Carstens larl %r14,.Lsysc_per 4354bfc86ceSHeiko Carstens stg %r14,__LC_RETURN_PSW+8 43656e62a73SSven Schnelle lghi %r14,1 437*3b051e89SSven Schnelle LBEAR __LC_PGM_LAST_BREAK 438*3b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per 43926a374aeSMartin SchwidefskyENDPROC(pgm_check_handler) 4404bfc86ceSHeiko Carstens 4414bfc86ceSHeiko Carstens/* 44256e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts. 4434bfc86ceSHeiko Carstens */ 44456e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler 44556e62a73SSven SchnelleENTRY(\name) 4464bfc86ceSHeiko Carstens STCK __LC_INT_CLOCK 44756e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 448*3b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 449d768bd89SMartin Schwidefsky BPOFF 4504bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_ASYNC 451d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 45256e62a73SSven Schnelle lmg %r8,%r9,\lc_old_psw 453b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 454b0d31159SSven Schnelle jnz 1f 455b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 456b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f 457fbbdfca5SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 458fbbdfca5SAlexander Gordeev SIEEXIT 459b0d31159SSven Schnelle#endif 460b0d31159SSven Schnelle0: CHECK_STACK __LC_SAVE_AREA_ASYNC 461b0d31159SSven Schnelle aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 462b0d31159SSven Schnelle j 2f 463b0d31159SSven Schnelle1: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 464b0d31159SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 465b0d31159SSven Schnelle lg %r15,__LC_KERNEL_STACK 466b74e409eSVasily Gorbik2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 467b74e409eSVasily Gorbik la %r11,STACK_FRAME_OVERHEAD(%r15) 4684bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 4697041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4707041d281SMartin Schwidefsky xgr %r0,%r0 4717041d281SMartin Schwidefsky xgr %r1,%r1 4727041d281SMartin Schwidefsky xgr %r3,%r3 4737041d281SMartin Schwidefsky xgr %r4,%r4 4747041d281SMartin Schwidefsky xgr %r5,%r5 4757041d281SMartin Schwidefsky xgr %r6,%r6 4767041d281SMartin Schwidefsky xgr %r7,%r7 4777041d281SMartin Schwidefsky xgr %r10,%r10 478ca1f4d70SSven Schnelle xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 4794bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 480*3b051e89SSven Schnelle MBEAR %r11 4814bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 48256e62a73SSven Schnelle tm %r8,0x0001 # coming from user space? 48356e62a73SSven Schnelle jno 1f 48487d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 48556e62a73SSven Schnelle1: lgr %r2,%r11 # pass pointer to pt_regs 48656e62a73SSven Schnelle brasl %r14,\handler 4874bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 48856e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 48956e62a73SSven Schnelle jno 2f 49087d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4916b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4924bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 493*3b051e89SSven Schnelle2: LBEAR __PT_LAST_BREAK(%r11) 494*3b051e89SSven Schnelle lmg %r0,%r15,__PT_R0(%r11) 495*3b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 49656e62a73SSven SchnelleENDPROC(\name) 49756e62a73SSven Schnelle.endm 4984bfc86ceSHeiko Carstens 49956e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 50056e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 5014bfc86ceSHeiko Carstens 5024bfc86ceSHeiko Carstens/* 5030b0ed657SSven Schnelle * Load idle PSW. 5044bfc86ceSHeiko Carstens */ 5054bfc86ceSHeiko CarstensENTRY(psw_idle) 506a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 5074bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 50856e62a73SSven Schnelle larl %r1,psw_idle_exit 5094bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 51072d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 51172d38b19SMartin Schwidefsky llgf %r1,0(%r1) 51272d38b19SMartin Schwidefsky ltgr %r1,%r1 51372d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 51456e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 51572d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 516419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 517d768bd89SMartin Schwidefsky BPON 5184bfc86ceSHeiko Carstens STCK __CLOCK_IDLE_ENTER(%r2) 5194bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 5204bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 52156e62a73SSven Schnelle.globl psw_idle_exit 52256e62a73SSven Schnellepsw_idle_exit: 5236dd85fbbSMartin Schwidefsky BR_EX %r14 52426a374aeSMartin SchwidefskyENDPROC(psw_idle) 5254bfc86ceSHeiko Carstens 526b5510d9bSHendrik Brueckner/* 5274bfc86ceSHeiko Carstens * Machine check handler routines 5284bfc86ceSHeiko Carstens */ 5294bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 5304bfc86ceSHeiko Carstens STCK __LC_MCCK_CLOCK 531d768bd89SMartin Schwidefsky BPOFF 5323037a52fSMartin Schwidefsky la %r1,4095 # validate r1 5333037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 534*3b051e89SSven Schnelle LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear 5353037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 536d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 5374bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 53883abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 5394bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 5403037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 5413037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5423037a52fSMartin Schwidefsky la %r14,4095 5433037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5443037a52fSMartin Schwidefsky ptlb 5455fa2ea07SAlexander Gordeev lghi %r14,__LC_CPU_TIMER_SAVE_AREA 5464bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 54783abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID 5484bfc86ceSHeiko Carstens jo 3f 54956e62a73SSven Schnelle la %r14,__LC_SYS_ENTER_TIMER 55056e62a73SSven Schnelle clc 0(8,%r14),__LC_EXIT_TIMER 5514bfc86ceSHeiko Carstens jl 1f 5524bfc86ceSHeiko Carstens la %r14,__LC_EXIT_TIMER 5534bfc86ceSHeiko Carstens1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 5544bfc86ceSHeiko Carstens jl 2f 5554bfc86ceSHeiko Carstens la %r14,__LC_LAST_UPDATE_TIMER 5564bfc86ceSHeiko Carstens2: spt 0(%r14) 5574bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 5583037a52fSMartin Schwidefsky3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 5593037a52fSMartin Schwidefsky jno .Lmcck_panic 5603037a52fSMartin Schwidefsky tmhh %r8,0x0001 # interrupting from user ? 561d35925b3SAlexander Gordeev jnz 6f 5623037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5633037a52fSMartin Schwidefsky jno .Lmcck_panic 564b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 565d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f 566d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_skip,4f 56720232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 568d35925b3SAlexander Gordeev j 5f 569d35925b3SAlexander Gordeev4: CHKSTG .Lmcck_panic 570d35925b3SAlexander Gordeev5: larl %r14,.Lstosm_tmp 571d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 572d35925b3SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 573fbbdfca5SAlexander Gordeev SIEEXIT 574b61b1595SSven Schnelle j .Lmcck_stack 575e2c13d64SAlexander Gordeev#endif 576d35925b3SAlexander Gordeev6: CHKSTG .Lmcck_panic 577d35925b3SAlexander Gordeev larl %r14,.Lstosm_tmp 578d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 579d35925b3SAlexander Gordeev tmhh %r8,0x0001 # interrupting from user ? 580d35925b3SAlexander Gordeev jz .Lmcck_stack 581b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 582b61b1595SSven Schnelle.Lmcck_stack: 583b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 584b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 58526521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 586b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 587b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5884bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5894bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5907041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5917041d281SMartin Schwidefsky xgr %r0,%r0 5927041d281SMartin Schwidefsky xgr %r1,%r1 5937041d281SMartin Schwidefsky xgr %r3,%r3 5947041d281SMartin Schwidefsky xgr %r4,%r4 5957041d281SMartin Schwidefsky xgr %r5,%r5 5967041d281SMartin Schwidefsky xgr %r6,%r6 5977041d281SMartin Schwidefsky xgr %r7,%r7 5987041d281SMartin Schwidefsky xgr %r10,%r10 5994bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6004bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6014bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 6024bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6034bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6044bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 6050b0ed657SSven Schnelle cghi %r2,0 6060b0ed657SSven Schnelle je .Lmcck_return 6074bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 6084bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 6094bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 6104bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 6114bfc86ceSHeiko Carstens lgr %r15,%r1 6124bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 6134bfc86ceSHeiko Carstens.Lmcck_return: 61487d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 6154bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 6164bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 6174bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 6184bfc86ceSHeiko Carstens jno 0f 6196b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 6204bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 621*3b051e89SSven Schnelle0: ALTERNATIVE "", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193 622*3b051e89SSven Schnelle LBEAR 0(%r12) 623*3b051e89SSven Schnelle lmg %r11,%r15,__PT_R11(%r11) 624*3b051e89SSven Schnelle LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE 6254bfc86ceSHeiko Carstens 6264bfc86ceSHeiko Carstens.Lmcck_panic: 6277f6dc8d4SAlexander Gordeev /* 6287f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 6297f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 6307f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 6317f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 6327f6dc8d4SAlexander Gordeev */ 6337f6dc8d4SAlexander Gordeev lhi %r5,0 6347f6dc8d4SAlexander Gordeev lhi %r6,1 6357f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 6367f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 6377f6dc8d4SAlexander Gordeev jnz 4f 6387f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 6397f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 6407f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 6417f6dc8d4SAlexander Gordeev nilh %r4,0 6427f6dc8d4SAlexander Gordeev lhi %r0,1 6437f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 6447f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 6457f6dc8d4SAlexander Gordeev0: cr %r3,%r4 6467f6dc8d4SAlexander Gordeev je 2f 6477f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 6487f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 6497f6dc8d4SAlexander Gordeev2: ahi %r3,1 6507f6dc8d4SAlexander Gordeev brct %r0,0b 6517f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 6527f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 6537f6dc8d4SAlexander Gordeev4: j 4b 65426a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6554bfc86ceSHeiko Carstens 6564bfc86ceSHeiko CarstensENTRY(restart_int_handler) 657e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 658e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 659915fea04SAlexander Gordeev TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4 660915fea04SAlexander Gordeev jz 0f 661915fea04SAlexander Gordeev la %r15,4095 662915fea04SAlexander Gordeev lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15) 663915fea04SAlexander Gordeev0: larl %r15,.Lstosm_tmp 664915fea04SAlexander Gordeev stosm 0(%r15),0x04 # turn dat on, keep irqs off 6654bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 666ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 667ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 668ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 669ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6704bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6714bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6724bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 673915fea04SAlexander Gordeev lgf %r3,__LC_RESTART_SOURCE 6744bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6754bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6764bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6774bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6784bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6794bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6804bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6814bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6824bfc86ceSHeiko Carstens brc 2,2b 6834bfc86ceSHeiko Carstens3: j 3b 68426a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6854bfc86ceSHeiko Carstens 6864bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6874bfc86ceSHeiko Carstens 688ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6894bfc86ceSHeiko Carstens/* 6904bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6914bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6924bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6934bfc86ceSHeiko Carstens */ 69426a374aeSMartin SchwidefskyENTRY(stack_overflow) 695ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6964bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6974bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6984bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6994bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 7004bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 7014bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 7024bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 7034bfc86ceSHeiko Carstens jg kernel_stack_overflow 70426a374aeSMartin SchwidefskyENDPROC(stack_overflow) 7054bfc86ceSHeiko Carstens#endif 7064bfc86ceSHeiko Carstens 7077f6dc8d4SAlexander Gordeev .section .data, "aw" 7087f6dc8d4SAlexander Gordeev .align 4 7097f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 7107f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 711d35925b3SAlexander Gordeev.Lstosm_tmp: .byte 0 7124bfc86ceSHeiko Carstens .section .rodata, "a" 713ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 7144bfc86ceSHeiko Carstens .globl sys_call_table 7154bfc86ceSHeiko Carstenssys_call_table: 7164381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7174bfc86ceSHeiko Carstens#undef SYSCALL 7184bfc86ceSHeiko Carstens 7194bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 7204bfc86ceSHeiko Carstens 721ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 7224bfc86ceSHeiko Carstens .globl sys_call_table_emu 7234bfc86ceSHeiko Carstenssys_call_table_emu: 7244381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7254bfc86ceSHeiko Carstens#undef SYSCALL 7264bfc86ceSHeiko Carstens#endif 727