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 */ 104bfc86ceSHeiko Carstens 114bfc86ceSHeiko Carstens#include <linux/init.h> 124bfc86ceSHeiko Carstens#include <linux/linkage.h> 13d09a307fSHeiko Carstens#include <asm/asm-extable.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 553b051e89SSven Schnelle .macro STBEAR address 56*fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193 573b051e89SSven Schnelle .endm 583b051e89SSven Schnelle 593b051e89SSven Schnelle .macro LBEAR address 60*fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193 613b051e89SSven Schnelle .endm 623b051e89SSven Schnelle 633b051e89SSven Schnelle .macro LPSWEY address,lpswe 64*fad442d3SHeiko Carstens ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193 653b051e89SSven Schnelle .endm 663b051e89SSven Schnelle 673b051e89SSven Schnelle .macro MBEAR reg 68*fad442d3SHeiko Carstens ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193 693b051e89SSven Schnelle .endm 703b051e89SSven 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 10183abeffbSHendrik Brueckner /* 10283abeffbSHendrik Brueckner * The TSTMSK macro generates a test-under-mask instruction by 10383abeffbSHendrik Brueckner * calculating the memory offset for the specified mask value. 10483abeffbSHendrik Brueckner * Mask value can be any constant. The macro shifts the mask 10583abeffbSHendrik Brueckner * value to calculate the memory offset for the test-under-mask 10683abeffbSHendrik Brueckner * instruction. 10783abeffbSHendrik Brueckner */ 10883abeffbSHendrik Brueckner .macro TSTMSK addr, mask, size=8, bytepos=0 10983abeffbSHendrik Brueckner .if (\bytepos < \size) && (\mask >> 8) 11083abeffbSHendrik Brueckner .if (\mask & 0xff) 11183abeffbSHendrik Brueckner .error "Mask exceeds byte boundary" 11283abeffbSHendrik Brueckner .endif 11383abeffbSHendrik Brueckner TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)" 11483abeffbSHendrik Brueckner .exitm 11583abeffbSHendrik Brueckner .endif 11683abeffbSHendrik Brueckner .ifeq \mask 11783abeffbSHendrik Brueckner .error "Mask must not be zero" 11883abeffbSHendrik Brueckner .endif 11983abeffbSHendrik Brueckner off = \size - \bytepos - 1 12083abeffbSHendrik Brueckner tm off+\addr, \mask 12183abeffbSHendrik Brueckner .endm 12283abeffbSHendrik Brueckner 123d768bd89SMartin Schwidefsky .macro BPOFF 124*fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82 125d768bd89SMartin Schwidefsky .endm 126d768bd89SMartin Schwidefsky 127d768bd89SMartin Schwidefsky .macro BPON 128*fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82 129d768bd89SMartin Schwidefsky .endm 130d768bd89SMartin Schwidefsky 1316b73044bSMartin Schwidefsky .macro BPENTER tif_ptr,tif_mask 1326982dba1SHeiko Carstens ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \ 133*fad442d3SHeiko Carstens "j .+12; nop; nop", 82 1346b73044bSMartin Schwidefsky .endm 1356b73044bSMartin Schwidefsky 1366b73044bSMartin Schwidefsky .macro BPEXIT tif_ptr,tif_mask 1376b73044bSMartin Schwidefsky TSTMSK \tif_ptr,\tif_mask 1386982dba1SHeiko Carstens ALTERNATIVE "jz .+8; .insn rrf,0xb2e80000,0,0,12,0", \ 1396982dba1SHeiko Carstens "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82 1406b73044bSMartin Schwidefsky .endm 1416b73044bSMartin Schwidefsky 142d35925b3SAlexander Gordeev /* 143d35925b3SAlexander Gordeev * The CHKSTG macro jumps to the provided label in case the 144d35925b3SAlexander Gordeev * machine check interruption code reports one of unrecoverable 145d35925b3SAlexander Gordeev * storage errors: 146d35925b3SAlexander Gordeev * - Storage error uncorrected 147d35925b3SAlexander Gordeev * - Storage key error uncorrected 148d35925b3SAlexander Gordeev * - Storage degradation with Failing-storage-address validity 149d35925b3SAlexander Gordeev */ 150d35925b3SAlexander Gordeev .macro CHKSTG errlabel 151d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR) 152d35925b3SAlexander Gordeev jnz \errlabel 153d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD 15415256194SHeiko Carstens jz .Loklabel\@ 155d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR 156d35925b3SAlexander Gordeev jnz \errlabel 15715256194SHeiko Carstens.Loklabel\@: 158d35925b3SAlexander Gordeev .endm 159d35925b3SAlexander Gordeev 160b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM) 161b5415c8fSAlexander Gordeev /* 162b5415c8fSAlexander Gordeev * The OUTSIDE macro jumps to the provided label in case the value 163b5415c8fSAlexander Gordeev * in the provided register is outside of the provided range. The 164b5415c8fSAlexander Gordeev * macro is useful for checking whether a PSW stored in a register 165b5415c8fSAlexander Gordeev * pair points inside or outside of a block of instructions. 166b5415c8fSAlexander Gordeev * @reg: register to check 167b5415c8fSAlexander Gordeev * @start: start of the range 168b5415c8fSAlexander Gordeev * @end: end of the range 169b5415c8fSAlexander Gordeev * @outside_label: jump here if @reg is outside of [@start..@end) 170b5415c8fSAlexander Gordeev */ 171b5415c8fSAlexander Gordeev .macro OUTSIDE reg,start,end,outside_label 172b5415c8fSAlexander Gordeev lgr %r14,\reg 173b5415c8fSAlexander Gordeev larl %r13,\start 174b5415c8fSAlexander Gordeev slgr %r14,%r13 175b5415c8fSAlexander Gordeev lghi %r13,\end - \start 176b5415c8fSAlexander Gordeev clgr %r14,%r13 177b5415c8fSAlexander Gordeev jhe \outside_label 178b5415c8fSAlexander Gordeev .endm 179fbbdfca5SAlexander Gordeev 180fbbdfca5SAlexander Gordeev .macro SIEEXIT 181fbbdfca5SAlexander Gordeev lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer 182fbbdfca5SAlexander Gordeev ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 183fbbdfca5SAlexander Gordeev lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 184fbbdfca5SAlexander Gordeev larl %r9,sie_exit # skip forward to sie_exit 185fbbdfca5SAlexander Gordeev .endm 186b5415c8fSAlexander Gordeev#endif 187b5415c8fSAlexander Gordeev 1886dd85fbbSMartin Schwidefsky GEN_BR_THUNK %r14 189f19fbd5eSMartin Schwidefsky 1904bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 19146210c44SHeiko Carstens.Ldummy: 19246210c44SHeiko Carstens /* 19356e62a73SSven Schnelle * This nop exists only in order to avoid that __bpon starts at 19446210c44SHeiko Carstens * the beginning of the kprobes text section. In that case we would 19546210c44SHeiko Carstens * have several symbols at the same address. E.g. objdump would take 19646210c44SHeiko Carstens * an arbitrary symbol name when disassembling this code. 19756e62a73SSven Schnelle * With the added nop in between the __bpon symbol is unique 19846210c44SHeiko Carstens * again. 19946210c44SHeiko Carstens */ 20046210c44SHeiko Carstens nop 0 2014bfc86ceSHeiko Carstens 202d768bd89SMartin SchwidefskyENTRY(__bpon) 203d768bd89SMartin Schwidefsky .globl __bpon 204d768bd89SMartin Schwidefsky BPON 2056dd85fbbSMartin Schwidefsky BR_EX %r14 20626a374aeSMartin SchwidefskyENDPROC(__bpon) 207d768bd89SMartin Schwidefsky 2084bfc86ceSHeiko Carstens/* 2094bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to 2104bfc86ceSHeiko Carstens * gpr2 = (task_struct *) prev 2114bfc86ceSHeiko Carstens * gpr3 = (task_struct *) next 2124bfc86ceSHeiko Carstens * Returns: 2134bfc86ceSHeiko Carstens * gpr2 = prev 2144bfc86ceSHeiko Carstens */ 2154bfc86ceSHeiko CarstensENTRY(__switch_to) 2164bfc86ceSHeiko Carstens stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 2173241d3ebSHeiko Carstens lghi %r4,__TASK_stack 2183241d3ebSHeiko Carstens lghi %r1,__TASK_thread 2199fed920eSVasily Gorbik llill %r5,STACK_INIT 2203241d3ebSHeiko Carstens stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev 2219fed920eSVasily Gorbik lg %r15,0(%r4,%r3) # start of kernel stack of next 2229fed920eSVasily Gorbik agr %r15,%r5 # end of kernel stack of next 2234bfc86ceSHeiko Carstens stg %r3,__LC_CURRENT # store task struct of next 2244bfc86ceSHeiko Carstens stg %r15,__LC_KERNEL_STACK # store end of kernel stack 2253241d3ebSHeiko Carstens lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next 2263241d3ebSHeiko Carstens aghi %r3,__TASK_pid 2273241d3ebSHeiko Carstens mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 2284bfc86ceSHeiko Carstens lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 229*fad442d3SHeiko Carstens ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40 2306dd85fbbSMartin Schwidefsky BR_EX %r14 23126a374aeSMartin SchwidefskyENDPROC(__switch_to) 2324bfc86ceSHeiko Carstens 233d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 234d0fc4107SMartin Schwidefsky/* 235d0fc4107SMartin Schwidefsky * sie64a calling convention: 236d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block 237d0fc4107SMartin Schwidefsky * %r3 guest register save area 238d0fc4107SMartin Schwidefsky */ 239d0fc4107SMartin SchwidefskyENTRY(sie64a) 240d0fc4107SMartin Schwidefsky stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 2416b73044bSMartin Schwidefsky lg %r12,__LC_CURRENT 24292fa7a13SMartin Schwidefsky stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer 24392fa7a13SMartin Schwidefsky stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area 24492fa7a13SMartin Schwidefsky xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 24592fa7a13SMartin Schwidefsky mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 246d0fc4107SMartin Schwidefsky lmg %r0,%r13,0(%r3) # load guest gprs 0-13 247d0fc4107SMartin Schwidefsky lg %r14,__LC_GMAP # get gmap pointer 248d0fc4107SMartin Schwidefsky ltgr %r14,%r14 249d0fc4107SMartin Schwidefsky jz .Lsie_gmap 250d0fc4107SMartin Schwidefsky lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 251d0fc4107SMartin Schwidefsky.Lsie_gmap: 25292fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 253d0fc4107SMartin Schwidefsky oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 254d0fc4107SMartin Schwidefsky tm __SIE_PROG20+3(%r14),3 # last exit... 255d0fc4107SMartin Schwidefsky jnz .Lsie_skip 25683abeffbSHendrik Brueckner TSTMSK __LC_CPU_FLAGS,_CIF_FPU 257d0fc4107SMartin Schwidefsky jo .Lsie_skip # exit if fp/vx regs changed 25892fa7a13SMartin Schwidefsky BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 259c929500dSQingFeng Hao.Lsie_entry: 260d0fc4107SMartin Schwidefsky sie 0(%r14) 261d768bd89SMartin Schwidefsky BPOFF 26292fa7a13SMartin Schwidefsky BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 263d0fc4107SMartin Schwidefsky.Lsie_skip: 264d0fc4107SMartin Schwidefsky ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 26587d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 266d0fc4107SMartin Schwidefsky.Lsie_done: 267d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception) 268c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There 269c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. 270c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program 271c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. 272c0e7bb38SChristian Borntraeger.Lrewind_pad6: 273c0e7bb38SChristian Borntraeger nopr 7 274c0e7bb38SChristian Borntraeger.Lrewind_pad4: 275c0e7bb38SChristian Borntraeger nopr 7 276c0e7bb38SChristian Borntraeger.Lrewind_pad2: 277c0e7bb38SChristian Borntraeger nopr 7 278d0fc4107SMartin Schwidefsky .globl sie_exit 279d0fc4107SMartin Schwidefskysie_exit: 28092fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area 281d0fc4107SMartin Schwidefsky stmg %r0,%r13,0(%r14) # save guest gprs 0-13 2827041d281SMartin Schwidefsky xgr %r0,%r0 # clear guest registers to 2837041d281SMartin Schwidefsky xgr %r1,%r1 # prevent speculative use 2847041d281SMartin Schwidefsky xgr %r3,%r3 2857041d281SMartin Schwidefsky xgr %r4,%r4 2867041d281SMartin Schwidefsky xgr %r5,%r5 287d0fc4107SMartin Schwidefsky lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 28892fa7a13SMartin Schwidefsky lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 2896dd85fbbSMartin Schwidefsky BR_EX %r14 290d0fc4107SMartin Schwidefsky.Lsie_fault: 291d0fc4107SMartin Schwidefsky lghi %r14,-EFAULT 29292fa7a13SMartin Schwidefsky stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 293d0fc4107SMartin Schwidefsky j sie_exit 294d0fc4107SMartin Schwidefsky 295c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad6,.Lsie_fault) 296c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad4,.Lsie_fault) 297c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad2,.Lsie_fault) 298d0fc4107SMartin Schwidefsky EX_TABLE(sie_exit,.Lsie_fault) 29926a374aeSMartin SchwidefskyENDPROC(sie64a) 300711f5df7SAl ViroEXPORT_SYMBOL(sie64a) 301711f5df7SAl ViroEXPORT_SYMBOL(sie_exit) 302d0fc4107SMartin Schwidefsky#endif 303d0fc4107SMartin Schwidefsky 3044bfc86ceSHeiko Carstens/* 3054bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and 3067b7735c5SChristian Borntraeger * are entered with interrupts disabled. 3074bfc86ceSHeiko Carstens */ 3084bfc86ceSHeiko Carstens 3094bfc86ceSHeiko CarstensENTRY(system_call) 31056e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 3114bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 312d768bd89SMartin Schwidefsky BPOFF 31356e62a73SSven Schnelle lghi %r14,0 3144bfc86ceSHeiko Carstens.Lsysc_per: 3153b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 31687d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 31756e62a73SSven Schnelle lg %r12,__LC_CURRENT 3184bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 3199365965dSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 32056e62a73SSven Schnelle stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 32156e62a73SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 322d3f46896SChristian Borntraeger # clear user controlled register to prevent speculative use 323d3f46896SChristian Borntraeger xgr %r0,%r0 32456e62a73SSven Schnelle xgr %r1,%r1 32556e62a73SSven Schnelle xgr %r4,%r4 32656e62a73SSven Schnelle xgr %r5,%r5 32756e62a73SSven Schnelle xgr %r6,%r6 32856e62a73SSven Schnelle xgr %r7,%r7 32956e62a73SSven Schnelle xgr %r8,%r8 33056e62a73SSven Schnelle xgr %r9,%r9 33156e62a73SSven Schnelle xgr %r10,%r10 33256e62a73SSven Schnelle xgr %r11,%r11 33356e62a73SSven Schnelle la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 334af9ad822SSven Schnelle mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC 3353b051e89SSven Schnelle MBEAR %r2 33656e62a73SSven Schnelle lgr %r3,%r14 33756e62a73SSven Schnelle brasl %r14,__do_syscall 33887d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 33956e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3406b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3413b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 34256e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3434bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 3443b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 34526a374aeSMartin SchwidefskyENDPROC(system_call) 3464bfc86ceSHeiko Carstens 3474bfc86ceSHeiko Carstens# 3484bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork 3494bfc86ceSHeiko Carstens# 3504bfc86ceSHeiko CarstensENTRY(ret_from_fork) 35156e62a73SSven Schnelle lgr %r3,%r11 35256e62a73SSven Schnelle brasl %r14,__ret_from_fork 35356e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 35456e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 35556e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3563b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 35756e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 35856e62a73SSven Schnelle stpt __LC_EXIT_TIMER 3593b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 36026a374aeSMartin SchwidefskyENDPROC(ret_from_fork) 36126a374aeSMartin Schwidefsky 3624bfc86ceSHeiko Carstens/* 3634bfc86ceSHeiko Carstens * Program check handler routine 3644bfc86ceSHeiko Carstens */ 3654bfc86ceSHeiko Carstens 3664bfc86ceSHeiko CarstensENTRY(pgm_check_handler) 36756e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 368d768bd89SMartin Schwidefsky BPOFF 3694bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 37056e62a73SSven Schnelle lg %r12,__LC_CURRENT 37156e62a73SSven Schnelle lghi %r10,0 3724bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_PGM_OLD_PSW 37387d59863SHeiko Carstens tmhh %r8,0x0001 # coming from user space? 37487d59863SHeiko Carstens jno .Lpgm_skip_asce 37587d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 37656e62a73SSven Schnelle j 3f # -> fault in user space 37787d59863SHeiko Carstens.Lpgm_skip_asce: 378d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 3790a5e2ec2SMartin Schwidefsky # cleanup critical section for program checks in sie64a 380b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f 381fbbdfca5SAlexander Gordeev SIEEXIT 38256e62a73SSven Schnelle lghi %r10,_PIF_GUEST_FAULT 383d0fc4107SMartin Schwidefsky#endif 3840b38b5e1SSven Schnelle1: tmhh %r8,0x4000 # PER bit set in old PSW ? 3850b38b5e1SSven Schnelle jnz 2f # -> enabled, can't be a double fault 3864bfc86ceSHeiko Carstens tm __LC_PGM_ILC+3,0x80 # check for per exception 3874bfc86ceSHeiko Carstens jnz .Lpgm_svcper # -> single stepped svc 3880b38b5e1SSven Schnelle2: CHECK_STACK __LC_SAVE_AREA_SYNC 3894bfc86ceSHeiko Carstens aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 39056e62a73SSven Schnelle # CHECK_VMAP_STACK branches to stack_overflow or 4f 39156e62a73SSven Schnelle CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f 39256e62a73SSven Schnelle3: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 3934bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 39456e62a73SSven Schnelle4: la %r11,STACK_FRAME_OVERHEAD(%r15) 39556e62a73SSven Schnelle stg %r10,__PT_FLAGS(%r11) 39656e62a73SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 3974bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 39856e62a73SSven Schnelle mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC 3993b051e89SSven Schnelle mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK 40056e62a73SSven Schnelle stmg %r8,%r9,__PT_PSW(%r11) 40156e62a73SSven Schnelle 4027041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4037041d281SMartin Schwidefsky xgr %r0,%r0 4047041d281SMartin Schwidefsky xgr %r1,%r1 4057041d281SMartin Schwidefsky xgr %r3,%r3 4067041d281SMartin Schwidefsky xgr %r4,%r4 4077041d281SMartin Schwidefsky xgr %r5,%r5 4087041d281SMartin Schwidefsky xgr %r6,%r6 4097041d281SMartin Schwidefsky xgr %r7,%r7 41056e62a73SSven Schnelle lgr %r2,%r11 41156e62a73SSven Schnelle brasl %r14,__do_pgm_check 41256e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user space? 41356e62a73SSven Schnelle jno .Lpgm_exit_kernel 41456e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 41556e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4160cd9b723SHeiko Carstens stpt __LC_EXIT_TIMER 41756e62a73SSven Schnelle.Lpgm_exit_kernel: 41856e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 4193b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 42056e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 4213b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 4224bfc86ceSHeiko Carstens 4234bfc86ceSHeiko Carstens# 4244bfc86ceSHeiko Carstens# single stepped system call 4254bfc86ceSHeiko Carstens# 4264bfc86ceSHeiko Carstens.Lpgm_svcper: 4274bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 4284bfc86ceSHeiko Carstens larl %r14,.Lsysc_per 4294bfc86ceSHeiko Carstens stg %r14,__LC_RETURN_PSW+8 43056e62a73SSven Schnelle lghi %r14,1 4313b051e89SSven Schnelle LBEAR __LC_PGM_LAST_BREAK 4323b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per 43326a374aeSMartin SchwidefskyENDPROC(pgm_check_handler) 4344bfc86ceSHeiko Carstens 4354bfc86ceSHeiko Carstens/* 43656e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts. 4374bfc86ceSHeiko Carstens */ 43856e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler 43956e62a73SSven SchnelleENTRY(\name) 44010bc15baSVasily Gorbik stckf __LC_INT_CLOCK 44156e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 4423b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 443d768bd89SMartin Schwidefsky BPOFF 4444bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_ASYNC 445d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 44656e62a73SSven Schnelle lmg %r8,%r9,\lc_old_psw 447b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 448b0d31159SSven Schnelle jnz 1f 449b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 450b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f 451fbbdfca5SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 452fbbdfca5SAlexander Gordeev SIEEXIT 453b0d31159SSven Schnelle#endif 454b0d31159SSven Schnelle0: CHECK_STACK __LC_SAVE_AREA_ASYNC 455b0d31159SSven Schnelle aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 456b0d31159SSven Schnelle j 2f 457b0d31159SSven Schnelle1: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 458b0d31159SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 459b0d31159SSven Schnelle lg %r15,__LC_KERNEL_STACK 460b74e409eSVasily Gorbik2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 461b74e409eSVasily Gorbik la %r11,STACK_FRAME_OVERHEAD(%r15) 4624bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 4637041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4647041d281SMartin Schwidefsky xgr %r0,%r0 4657041d281SMartin Schwidefsky xgr %r1,%r1 4667041d281SMartin Schwidefsky xgr %r3,%r3 4677041d281SMartin Schwidefsky xgr %r4,%r4 4687041d281SMartin Schwidefsky xgr %r5,%r5 4697041d281SMartin Schwidefsky xgr %r6,%r6 4707041d281SMartin Schwidefsky xgr %r7,%r7 4717041d281SMartin Schwidefsky xgr %r10,%r10 472ca1f4d70SSven Schnelle xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 4734bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 4743b051e89SSven Schnelle MBEAR %r11 4754bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 47629b06ad7SHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 47756e62a73SSven Schnelle brasl %r14,\handler 4784bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 47956e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 48056e62a73SSven Schnelle jno 2f 48187d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4826b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4834bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 4843b051e89SSven Schnelle2: LBEAR __PT_LAST_BREAK(%r11) 4853b051e89SSven Schnelle lmg %r0,%r15,__PT_R0(%r11) 4863b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 48756e62a73SSven SchnelleENDPROC(\name) 48856e62a73SSven Schnelle.endm 4894bfc86ceSHeiko Carstens 49056e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 49156e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 4924bfc86ceSHeiko Carstens 4934bfc86ceSHeiko Carstens/* 4940b0ed657SSven Schnelle * Load idle PSW. 4954bfc86ceSHeiko Carstens */ 4964bfc86ceSHeiko CarstensENTRY(psw_idle) 497a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 4984bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 49956e62a73SSven Schnelle larl %r1,psw_idle_exit 5004bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 50172d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 50272d38b19SMartin Schwidefsky llgf %r1,0(%r1) 50372d38b19SMartin Schwidefsky ltgr %r1,%r1 50472d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 50556e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 50672d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 507419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 508d768bd89SMartin Schwidefsky BPON 50910bc15baSVasily Gorbik stckf __CLOCK_IDLE_ENTER(%r2) 5104bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 5114bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 51256e62a73SSven Schnelle.globl psw_idle_exit 51356e62a73SSven Schnellepsw_idle_exit: 5146dd85fbbSMartin Schwidefsky BR_EX %r14 51526a374aeSMartin SchwidefskyENDPROC(psw_idle) 5164bfc86ceSHeiko Carstens 517b5510d9bSHendrik Brueckner/* 5184bfc86ceSHeiko Carstens * Machine check handler routines 5194bfc86ceSHeiko Carstens */ 5204bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 52110bc15baSVasily Gorbik stckf __LC_MCCK_CLOCK 522d768bd89SMartin Schwidefsky BPOFF 5233037a52fSMartin Schwidefsky la %r1,4095 # validate r1 5243037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 5253b051e89SSven Schnelle LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear 5263037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 527d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 5284bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 52983abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 5304bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 5313037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 5323037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5333037a52fSMartin Schwidefsky la %r14,4095 5343037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5353037a52fSMartin Schwidefsky ptlb 5365fa2ea07SAlexander Gordeev lghi %r14,__LC_CPU_TIMER_SAVE_AREA 5374bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 53883abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID 5394bfc86ceSHeiko Carstens jo 3f 54056e62a73SSven Schnelle la %r14,__LC_SYS_ENTER_TIMER 54156e62a73SSven Schnelle clc 0(8,%r14),__LC_EXIT_TIMER 5424bfc86ceSHeiko Carstens jl 1f 5434bfc86ceSHeiko Carstens la %r14,__LC_EXIT_TIMER 5444bfc86ceSHeiko Carstens1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 5454bfc86ceSHeiko Carstens jl 2f 5464bfc86ceSHeiko Carstens la %r14,__LC_LAST_UPDATE_TIMER 5474bfc86ceSHeiko Carstens2: spt 0(%r14) 5484bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 5493037a52fSMartin Schwidefsky3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 5503037a52fSMartin Schwidefsky jno .Lmcck_panic 5513037a52fSMartin Schwidefsky tmhh %r8,0x0001 # interrupting from user ? 552d35925b3SAlexander Gordeev jnz 6f 5533037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5543037a52fSMartin Schwidefsky jno .Lmcck_panic 555b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 556d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f 557d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_skip,4f 55820232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 559d35925b3SAlexander Gordeev j 5f 560d35925b3SAlexander Gordeev4: CHKSTG .Lmcck_panic 561d35925b3SAlexander Gordeev5: larl %r14,.Lstosm_tmp 562d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 563d35925b3SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 564fbbdfca5SAlexander Gordeev SIEEXIT 565b61b1595SSven Schnelle j .Lmcck_stack 566e2c13d64SAlexander Gordeev#endif 567d35925b3SAlexander Gordeev6: CHKSTG .Lmcck_panic 568d35925b3SAlexander Gordeev larl %r14,.Lstosm_tmp 569d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 570d35925b3SAlexander Gordeev tmhh %r8,0x0001 # interrupting from user ? 571d35925b3SAlexander Gordeev jz .Lmcck_stack 572b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 573b61b1595SSven Schnelle.Lmcck_stack: 574b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 575b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 57626521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 577b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 578b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5794bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5804bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5817041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5827041d281SMartin Schwidefsky xgr %r0,%r0 5837041d281SMartin Schwidefsky xgr %r1,%r1 5847041d281SMartin Schwidefsky xgr %r3,%r3 5857041d281SMartin Schwidefsky xgr %r4,%r4 5867041d281SMartin Schwidefsky xgr %r5,%r5 5877041d281SMartin Schwidefsky xgr %r6,%r6 5887041d281SMartin Schwidefsky xgr %r7,%r7 5897041d281SMartin Schwidefsky xgr %r10,%r10 5904bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 5914bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 5924bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 5934bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5944bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 5954bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 5960b0ed657SSven Schnelle cghi %r2,0 5970b0ed657SSven Schnelle je .Lmcck_return 5984bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 5994bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 6004bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 6014bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 60239d62336SThomas Richter lgr %r2,%r11 6034bfc86ceSHeiko Carstens lgr %r15,%r1 6044bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 6054bfc86ceSHeiko Carstens.Lmcck_return: 60687d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 6074bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 6084bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 6094bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 6104bfc86ceSHeiko Carstens jno 0f 6116b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 6124bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 613*fad442d3SHeiko Carstens0: ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193 6143b051e89SSven Schnelle LBEAR 0(%r12) 6153b051e89SSven Schnelle lmg %r11,%r15,__PT_R11(%r11) 6163b051e89SSven Schnelle LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE 6174bfc86ceSHeiko Carstens 6184bfc86ceSHeiko Carstens.Lmcck_panic: 6197f6dc8d4SAlexander Gordeev /* 6207f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 6217f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 6227f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 6237f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 6247f6dc8d4SAlexander Gordeev */ 6257f6dc8d4SAlexander Gordeev lhi %r5,0 6267f6dc8d4SAlexander Gordeev lhi %r6,1 6277f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 6287f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 6297f6dc8d4SAlexander Gordeev jnz 4f 6307f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 6317f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 6327f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 6337f6dc8d4SAlexander Gordeev nilh %r4,0 6347f6dc8d4SAlexander Gordeev lhi %r0,1 6357f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 6367f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 6377f6dc8d4SAlexander Gordeev0: cr %r3,%r4 6387f6dc8d4SAlexander Gordeev je 2f 6397f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 6407f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 6417f6dc8d4SAlexander Gordeev2: ahi %r3,1 6427f6dc8d4SAlexander Gordeev brct %r0,0b 6437f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 6447f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 6457f6dc8d4SAlexander Gordeev4: j 4b 64626a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6474bfc86ceSHeiko Carstens 6484bfc86ceSHeiko CarstensENTRY(restart_int_handler) 649*fad442d3SHeiko Carstens ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40 650e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 651915fea04SAlexander Gordeev TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4 652915fea04SAlexander Gordeev jz 0f 653915fea04SAlexander Gordeev la %r15,4095 654915fea04SAlexander Gordeev lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15) 655915fea04SAlexander Gordeev0: larl %r15,.Lstosm_tmp 656915fea04SAlexander Gordeev stosm 0(%r15),0x04 # turn dat on, keep irqs off 6574bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 658ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 659ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 660ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 661ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6624bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6634bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6644bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 665915fea04SAlexander Gordeev lgf %r3,__LC_RESTART_SOURCE 6664bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6674bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6684bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6694bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6704bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6714bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6724bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6734bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6744bfc86ceSHeiko Carstens brc 2,2b 6754bfc86ceSHeiko Carstens3: j 3b 67626a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6774bfc86ceSHeiko Carstens 6784bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6794bfc86ceSHeiko Carstens 680ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6814bfc86ceSHeiko Carstens/* 6824bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6834bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6844bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6854bfc86ceSHeiko Carstens */ 68626a374aeSMartin SchwidefskyENTRY(stack_overflow) 687ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6884bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6894bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6904bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6914bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6924bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 6934bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6944bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6954bfc86ceSHeiko Carstens jg kernel_stack_overflow 69626a374aeSMartin SchwidefskyENDPROC(stack_overflow) 6974bfc86ceSHeiko Carstens#endif 6984bfc86ceSHeiko Carstens 6997f6dc8d4SAlexander Gordeev .section .data, "aw" 7007f6dc8d4SAlexander Gordeev .align 4 7017f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 7027f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 703d35925b3SAlexander Gordeev.Lstosm_tmp: .byte 0 7044bfc86ceSHeiko Carstens .section .rodata, "a" 705ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 7064bfc86ceSHeiko Carstens .globl sys_call_table 7074bfc86ceSHeiko Carstenssys_call_table: 7084381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7094bfc86ceSHeiko Carstens#undef SYSCALL 7104bfc86ceSHeiko Carstens 7114bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 7124bfc86ceSHeiko Carstens 713ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 7144bfc86ceSHeiko Carstens .globl sys_call_table_emu 7154bfc86ceSHeiko Carstenssys_call_table_emu: 7164381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7174bfc86ceSHeiko Carstens#undef SYSCALL 7184bfc86ceSHeiko Carstens#endif 719