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 563b051e89SSven Schnelle ALTERNATIVE "", ".insn s,0xb2010000,\address", 193 573b051e89SSven Schnelle .endm 583b051e89SSven Schnelle 593b051e89SSven Schnelle .macro LBEAR address 603b051e89SSven Schnelle ALTERNATIVE "", ".insn s,0xb2000000,\address", 193 613b051e89SSven Schnelle .endm 623b051e89SSven Schnelle 633b051e89SSven Schnelle .macro LPSWEY address,lpswe 643b051e89SSven Schnelle ALTERNATIVE "b \lpswe", ".insn siy,0xeb0000000071,\address,0", 193 653b051e89SSven Schnelle .endm 663b051e89SSven Schnelle 673b051e89SSven Schnelle .macro MBEAR reg 683b051e89SSven Schnelle ALTERNATIVE "", __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 124b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8c000", 82 125d768bd89SMartin Schwidefsky .endm 126d768bd89SMartin Schwidefsky 127d768bd89SMartin Schwidefsky .macro BPON 128b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8d000", 82 129d768bd89SMartin Schwidefsky .endm 130d768bd89SMartin Schwidefsky 1316b73044bSMartin Schwidefsky .macro BPENTER tif_ptr,tif_mask 132b058661aSMartin Schwidefsky ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \ 133b058661aSMartin Schwidefsky "", 82 1346b73044bSMartin Schwidefsky .endm 1356b73044bSMartin Schwidefsky 1366b73044bSMartin Schwidefsky .macro BPEXIT tif_ptr,tif_mask 1376b73044bSMartin Schwidefsky TSTMSK \tif_ptr,\tif_mask 138b058661aSMartin Schwidefsky ALTERNATIVE "jz .+8; .long 0xb2e8c000", \ 139b058661aSMartin Schwidefsky "jnz .+8; .long 0xb2e8d000", 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 229e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_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) 440*10bc15baSVasily 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) 47656e62a73SSven Schnelle tm %r8,0x0001 # coming from user space? 47756e62a73SSven Schnelle jno 1f 47887d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 47956e62a73SSven Schnelle1: lgr %r2,%r11 # pass pointer to pt_regs 48056e62a73SSven Schnelle brasl %r14,\handler 4814bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 48256e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 48356e62a73SSven Schnelle jno 2f 48487d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4856b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4864bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 4873b051e89SSven Schnelle2: LBEAR __PT_LAST_BREAK(%r11) 4883b051e89SSven Schnelle lmg %r0,%r15,__PT_R0(%r11) 4893b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 49056e62a73SSven SchnelleENDPROC(\name) 49156e62a73SSven Schnelle.endm 4924bfc86ceSHeiko Carstens 49356e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 49456e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 4954bfc86ceSHeiko Carstens 4964bfc86ceSHeiko Carstens/* 4970b0ed657SSven Schnelle * Load idle PSW. 4984bfc86ceSHeiko Carstens */ 4994bfc86ceSHeiko CarstensENTRY(psw_idle) 500a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 5014bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 50256e62a73SSven Schnelle larl %r1,psw_idle_exit 5034bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 50472d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 50572d38b19SMartin Schwidefsky llgf %r1,0(%r1) 50672d38b19SMartin Schwidefsky ltgr %r1,%r1 50772d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 50856e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 50972d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 510419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 511d768bd89SMartin Schwidefsky BPON 512*10bc15baSVasily Gorbik stckf __CLOCK_IDLE_ENTER(%r2) 5134bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 5144bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 51556e62a73SSven Schnelle.globl psw_idle_exit 51656e62a73SSven Schnellepsw_idle_exit: 5176dd85fbbSMartin Schwidefsky BR_EX %r14 51826a374aeSMartin SchwidefskyENDPROC(psw_idle) 5194bfc86ceSHeiko Carstens 520b5510d9bSHendrik Brueckner/* 5214bfc86ceSHeiko Carstens * Machine check handler routines 5224bfc86ceSHeiko Carstens */ 5234bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 524*10bc15baSVasily Gorbik stckf __LC_MCCK_CLOCK 525d768bd89SMartin Schwidefsky BPOFF 5263037a52fSMartin Schwidefsky la %r1,4095 # validate r1 5273037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 5283b051e89SSven Schnelle LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear 5293037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 530d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 5314bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 53283abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 5334bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 5343037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 5353037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5363037a52fSMartin Schwidefsky la %r14,4095 5373037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5383037a52fSMartin Schwidefsky ptlb 5395fa2ea07SAlexander Gordeev lghi %r14,__LC_CPU_TIMER_SAVE_AREA 5404bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 54183abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID 5424bfc86ceSHeiko Carstens jo 3f 54356e62a73SSven Schnelle la %r14,__LC_SYS_ENTER_TIMER 54456e62a73SSven Schnelle clc 0(8,%r14),__LC_EXIT_TIMER 5454bfc86ceSHeiko Carstens jl 1f 5464bfc86ceSHeiko Carstens la %r14,__LC_EXIT_TIMER 5474bfc86ceSHeiko Carstens1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 5484bfc86ceSHeiko Carstens jl 2f 5494bfc86ceSHeiko Carstens la %r14,__LC_LAST_UPDATE_TIMER 5504bfc86ceSHeiko Carstens2: spt 0(%r14) 5514bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 5523037a52fSMartin Schwidefsky3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 5533037a52fSMartin Schwidefsky jno .Lmcck_panic 5543037a52fSMartin Schwidefsky tmhh %r8,0x0001 # interrupting from user ? 555d35925b3SAlexander Gordeev jnz 6f 5563037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5573037a52fSMartin Schwidefsky jno .Lmcck_panic 558b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 559d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f 560d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_skip,4f 56120232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 562d35925b3SAlexander Gordeev j 5f 563d35925b3SAlexander Gordeev4: CHKSTG .Lmcck_panic 564d35925b3SAlexander Gordeev5: larl %r14,.Lstosm_tmp 565d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 566d35925b3SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 567fbbdfca5SAlexander Gordeev SIEEXIT 568b61b1595SSven Schnelle j .Lmcck_stack 569e2c13d64SAlexander Gordeev#endif 570d35925b3SAlexander Gordeev6: CHKSTG .Lmcck_panic 571d35925b3SAlexander Gordeev larl %r14,.Lstosm_tmp 572d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 573d35925b3SAlexander Gordeev tmhh %r8,0x0001 # interrupting from user ? 574d35925b3SAlexander Gordeev jz .Lmcck_stack 575b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 576b61b1595SSven Schnelle.Lmcck_stack: 577b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 578b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 57926521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 580b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 581b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5824bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5834bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5847041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5857041d281SMartin Schwidefsky xgr %r0,%r0 5867041d281SMartin Schwidefsky xgr %r1,%r1 5877041d281SMartin Schwidefsky xgr %r3,%r3 5887041d281SMartin Schwidefsky xgr %r4,%r4 5897041d281SMartin Schwidefsky xgr %r5,%r5 5907041d281SMartin Schwidefsky xgr %r6,%r6 5917041d281SMartin Schwidefsky xgr %r7,%r7 5927041d281SMartin Schwidefsky xgr %r10,%r10 5934bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 5944bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 5954bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 5964bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5974bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 5984bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 5990b0ed657SSven Schnelle cghi %r2,0 6000b0ed657SSven Schnelle je .Lmcck_return 6014bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 6024bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 6034bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 6044bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 6054bfc86ceSHeiko Carstens lgr %r15,%r1 6064bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 6074bfc86ceSHeiko Carstens.Lmcck_return: 60887d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 6094bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 6104bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 6114bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 6124bfc86ceSHeiko Carstens jno 0f 6136b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 6144bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 6153b051e89SSven Schnelle0: ALTERNATIVE "", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193 6163b051e89SSven Schnelle LBEAR 0(%r12) 6173b051e89SSven Schnelle lmg %r11,%r15,__PT_R11(%r11) 6183b051e89SSven Schnelle LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE 6194bfc86ceSHeiko Carstens 6204bfc86ceSHeiko Carstens.Lmcck_panic: 6217f6dc8d4SAlexander Gordeev /* 6227f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 6237f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 6247f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 6257f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 6267f6dc8d4SAlexander Gordeev */ 6277f6dc8d4SAlexander Gordeev lhi %r5,0 6287f6dc8d4SAlexander Gordeev lhi %r6,1 6297f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 6307f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 6317f6dc8d4SAlexander Gordeev jnz 4f 6327f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 6337f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 6347f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 6357f6dc8d4SAlexander Gordeev nilh %r4,0 6367f6dc8d4SAlexander Gordeev lhi %r0,1 6377f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 6387f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 6397f6dc8d4SAlexander Gordeev0: cr %r3,%r4 6407f6dc8d4SAlexander Gordeev je 2f 6417f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 6427f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 6437f6dc8d4SAlexander Gordeev2: ahi %r3,1 6447f6dc8d4SAlexander Gordeev brct %r0,0b 6457f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 6467f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 6477f6dc8d4SAlexander Gordeev4: j 4b 64826a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6494bfc86ceSHeiko Carstens 6504bfc86ceSHeiko CarstensENTRY(restart_int_handler) 651e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 652e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 653915fea04SAlexander Gordeev TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4 654915fea04SAlexander Gordeev jz 0f 655915fea04SAlexander Gordeev la %r15,4095 656915fea04SAlexander Gordeev lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15) 657915fea04SAlexander Gordeev0: larl %r15,.Lstosm_tmp 658915fea04SAlexander Gordeev stosm 0(%r15),0x04 # turn dat on, keep irqs off 6594bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 660ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 661ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 662ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 663ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6644bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6654bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6664bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 667915fea04SAlexander Gordeev lgf %r3,__LC_RESTART_SOURCE 6684bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6694bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6704bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6714bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6724bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6734bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6744bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6754bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6764bfc86ceSHeiko Carstens brc 2,2b 6774bfc86ceSHeiko Carstens3: j 3b 67826a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6794bfc86ceSHeiko Carstens 6804bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6814bfc86ceSHeiko Carstens 682ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6834bfc86ceSHeiko Carstens/* 6844bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6854bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6864bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6874bfc86ceSHeiko Carstens */ 68826a374aeSMartin SchwidefskyENTRY(stack_overflow) 689ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6904bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6914bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6924bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6934bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6944bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 6954bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6964bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6974bfc86ceSHeiko Carstens jg kernel_stack_overflow 69826a374aeSMartin SchwidefskyENDPROC(stack_overflow) 6994bfc86ceSHeiko Carstens#endif 7004bfc86ceSHeiko Carstens 7017f6dc8d4SAlexander Gordeev .section .data, "aw" 7027f6dc8d4SAlexander Gordeev .align 4 7037f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 7047f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 705d35925b3SAlexander Gordeev.Lstosm_tmp: .byte 0 7064bfc86ceSHeiko Carstens .section .rodata, "a" 707ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 7084bfc86ceSHeiko Carstens .globl sys_call_table 7094bfc86ceSHeiko Carstenssys_call_table: 7104381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7114bfc86ceSHeiko Carstens#undef SYSCALL 7124bfc86ceSHeiko Carstens 7134bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 7144bfc86ceSHeiko Carstens 715ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 7164bfc86ceSHeiko Carstens .globl sys_call_table_emu 7174bfc86ceSHeiko Carstenssys_call_table_emu: 7184381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7194bfc86ceSHeiko Carstens#undef SYSCALL 7204bfc86ceSHeiko Carstens#endif 721