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 55ce3dc447SMartin Schwidefsky .macro CHECK_STACK savearea 564bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK 57ce3dc447SMartin Schwidefsky tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 584bfc86ceSHeiko Carstens lghi %r14,\savearea 594bfc86ceSHeiko Carstens jz stack_overflow 604bfc86ceSHeiko Carstens#endif 614bfc86ceSHeiko Carstens .endm 624bfc86ceSHeiko Carstens 63ce3dc447SMartin Schwidefsky .macro CHECK_VMAP_STACK savearea,oklabel 64ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK 65ce3dc447SMartin Schwidefsky lgr %r14,%r15 66ce3dc447SMartin Schwidefsky nill %r14,0x10000 - STACK_SIZE 67ce3dc447SMartin Schwidefsky oill %r14,STACK_INIT 68ce3dc447SMartin Schwidefsky clg %r14,__LC_KERNEL_STACK 69ce3dc447SMartin Schwidefsky je \oklabel 70ce3dc447SMartin Schwidefsky clg %r14,__LC_ASYNC_STACK 71ce3dc447SMartin Schwidefsky je \oklabel 72b61b1595SSven Schnelle clg %r14,__LC_MCCK_STACK 73b61b1595SSven Schnelle je \oklabel 74ce3dc447SMartin Schwidefsky clg %r14,__LC_NODAT_STACK 75ce3dc447SMartin Schwidefsky je \oklabel 76ce3dc447SMartin Schwidefsky clg %r14,__LC_RESTART_STACK 77ce3dc447SMartin Schwidefsky je \oklabel 78ce3dc447SMartin Schwidefsky lghi %r14,\savearea 79ce3dc447SMartin Schwidefsky j stack_overflow 80ce3dc447SMartin Schwidefsky#else 81ce3dc447SMartin Schwidefsky j \oklabel 82ce3dc447SMartin Schwidefsky#endif 83ce3dc447SMartin Schwidefsky .endm 84ce3dc447SMartin Schwidefsky 854bfc86ceSHeiko Carstens .macro STCK savearea 8678f65709SHeiko Carstens ALTERNATIVE ".insn s,0xb2050000,\savearea", \ 8778f65709SHeiko Carstens ".insn s,0xb27c0000,\savearea", 25 884bfc86ceSHeiko Carstens .endm 894bfc86ceSHeiko Carstens 9083abeffbSHendrik Brueckner /* 9183abeffbSHendrik Brueckner * The TSTMSK macro generates a test-under-mask instruction by 9283abeffbSHendrik Brueckner * calculating the memory offset for the specified mask value. 9383abeffbSHendrik Brueckner * Mask value can be any constant. The macro shifts the mask 9483abeffbSHendrik Brueckner * value to calculate the memory offset for the test-under-mask 9583abeffbSHendrik Brueckner * instruction. 9683abeffbSHendrik Brueckner */ 9783abeffbSHendrik Brueckner .macro TSTMSK addr, mask, size=8, bytepos=0 9883abeffbSHendrik Brueckner .if (\bytepos < \size) && (\mask >> 8) 9983abeffbSHendrik Brueckner .if (\mask & 0xff) 10083abeffbSHendrik Brueckner .error "Mask exceeds byte boundary" 10183abeffbSHendrik Brueckner .endif 10283abeffbSHendrik Brueckner TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)" 10383abeffbSHendrik Brueckner .exitm 10483abeffbSHendrik Brueckner .endif 10583abeffbSHendrik Brueckner .ifeq \mask 10683abeffbSHendrik Brueckner .error "Mask must not be zero" 10783abeffbSHendrik Brueckner .endif 10883abeffbSHendrik Brueckner off = \size - \bytepos - 1 10983abeffbSHendrik Brueckner tm off+\addr, \mask 11083abeffbSHendrik Brueckner .endm 11183abeffbSHendrik Brueckner 112d768bd89SMartin Schwidefsky .macro BPOFF 113b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8c000", 82 114d768bd89SMartin Schwidefsky .endm 115d768bd89SMartin Schwidefsky 116d768bd89SMartin Schwidefsky .macro BPON 117b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8d000", 82 118d768bd89SMartin Schwidefsky .endm 119d768bd89SMartin Schwidefsky 1206b73044bSMartin Schwidefsky .macro BPENTER tif_ptr,tif_mask 121b058661aSMartin Schwidefsky ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \ 122b058661aSMartin Schwidefsky "", 82 1236b73044bSMartin Schwidefsky .endm 1246b73044bSMartin Schwidefsky 1256b73044bSMartin Schwidefsky .macro BPEXIT tif_ptr,tif_mask 1266b73044bSMartin Schwidefsky TSTMSK \tif_ptr,\tif_mask 127b058661aSMartin Schwidefsky ALTERNATIVE "jz .+8; .long 0xb2e8c000", \ 128b058661aSMartin Schwidefsky "jnz .+8; .long 0xb2e8d000", 82 1296b73044bSMartin Schwidefsky .endm 1306b73044bSMartin Schwidefsky 131d35925b3SAlexander Gordeev /* 132d35925b3SAlexander Gordeev * The CHKSTG macro jumps to the provided label in case the 133d35925b3SAlexander Gordeev * machine check interruption code reports one of unrecoverable 134d35925b3SAlexander Gordeev * storage errors: 135d35925b3SAlexander Gordeev * - Storage error uncorrected 136d35925b3SAlexander Gordeev * - Storage key error uncorrected 137d35925b3SAlexander Gordeev * - Storage degradation with Failing-storage-address validity 138d35925b3SAlexander Gordeev */ 139d35925b3SAlexander Gordeev .macro CHKSTG errlabel 140d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR) 141d35925b3SAlexander Gordeev jnz \errlabel 142d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD 143d35925b3SAlexander Gordeev jz oklabel\@ 144d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR 145d35925b3SAlexander Gordeev jnz \errlabel 146d35925b3SAlexander Gordeevoklabel\@: 147d35925b3SAlexander Gordeev .endm 148d35925b3SAlexander Gordeev 149b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM) 150b5415c8fSAlexander Gordeev /* 151b5415c8fSAlexander Gordeev * The OUTSIDE macro jumps to the provided label in case the value 152b5415c8fSAlexander Gordeev * in the provided register is outside of the provided range. The 153b5415c8fSAlexander Gordeev * macro is useful for checking whether a PSW stored in a register 154b5415c8fSAlexander Gordeev * pair points inside or outside of a block of instructions. 155b5415c8fSAlexander Gordeev * @reg: register to check 156b5415c8fSAlexander Gordeev * @start: start of the range 157b5415c8fSAlexander Gordeev * @end: end of the range 158b5415c8fSAlexander Gordeev * @outside_label: jump here if @reg is outside of [@start..@end) 159b5415c8fSAlexander Gordeev */ 160b5415c8fSAlexander Gordeev .macro OUTSIDE reg,start,end,outside_label 161b5415c8fSAlexander Gordeev lgr %r14,\reg 162b5415c8fSAlexander Gordeev larl %r13,\start 163b5415c8fSAlexander Gordeev slgr %r14,%r13 164b5415c8fSAlexander Gordeev lghi %r13,\end - \start 165b5415c8fSAlexander Gordeev clgr %r14,%r13 166b5415c8fSAlexander Gordeev jhe \outside_label 167b5415c8fSAlexander Gordeev .endm 168fbbdfca5SAlexander Gordeev 169fbbdfca5SAlexander Gordeev .macro SIEEXIT 170fbbdfca5SAlexander Gordeev lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer 171fbbdfca5SAlexander Gordeev ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 172fbbdfca5SAlexander Gordeev lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 173fbbdfca5SAlexander Gordeev larl %r9,sie_exit # skip forward to sie_exit 174fbbdfca5SAlexander Gordeev .endm 175b5415c8fSAlexander Gordeev#endif 176b5415c8fSAlexander Gordeev 1776dd85fbbSMartin Schwidefsky GEN_BR_THUNK %r14 17833ea0487SSven Schnelle GEN_BR_THUNK %r14,%r13 179f19fbd5eSMartin Schwidefsky 1804bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 18146210c44SHeiko Carstens.Ldummy: 18246210c44SHeiko Carstens /* 18356e62a73SSven Schnelle * This nop exists only in order to avoid that __bpon starts at 18446210c44SHeiko Carstens * the beginning of the kprobes text section. In that case we would 18546210c44SHeiko Carstens * have several symbols at the same address. E.g. objdump would take 18646210c44SHeiko Carstens * an arbitrary symbol name when disassembling this code. 18756e62a73SSven Schnelle * With the added nop in between the __bpon symbol is unique 18846210c44SHeiko Carstens * again. 18946210c44SHeiko Carstens */ 19046210c44SHeiko Carstens nop 0 1914bfc86ceSHeiko Carstens 192d768bd89SMartin SchwidefskyENTRY(__bpon) 193d768bd89SMartin Schwidefsky .globl __bpon 194d768bd89SMartin Schwidefsky BPON 1956dd85fbbSMartin Schwidefsky BR_EX %r14 19626a374aeSMartin SchwidefskyENDPROC(__bpon) 197d768bd89SMartin Schwidefsky 1984bfc86ceSHeiko Carstens/* 1994bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to 2004bfc86ceSHeiko Carstens * gpr2 = (task_struct *) prev 2014bfc86ceSHeiko Carstens * gpr3 = (task_struct *) next 2024bfc86ceSHeiko Carstens * Returns: 2034bfc86ceSHeiko Carstens * gpr2 = prev 2044bfc86ceSHeiko Carstens */ 2054bfc86ceSHeiko CarstensENTRY(__switch_to) 2064bfc86ceSHeiko Carstens stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 2073241d3ebSHeiko Carstens lghi %r4,__TASK_stack 2083241d3ebSHeiko Carstens lghi %r1,__TASK_thread 2099fed920eSVasily Gorbik llill %r5,STACK_INIT 2103241d3ebSHeiko Carstens stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev 2119fed920eSVasily Gorbik lg %r15,0(%r4,%r3) # start of kernel stack of next 2129fed920eSVasily Gorbik agr %r15,%r5 # end of kernel stack of next 2134bfc86ceSHeiko Carstens stg %r3,__LC_CURRENT # store task struct of next 2144bfc86ceSHeiko Carstens stg %r15,__LC_KERNEL_STACK # store end of kernel stack 2153241d3ebSHeiko Carstens lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next 2163241d3ebSHeiko Carstens aghi %r3,__TASK_pid 2173241d3ebSHeiko Carstens mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 2184bfc86ceSHeiko Carstens lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 219e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 2206dd85fbbSMartin Schwidefsky BR_EX %r14 22126a374aeSMartin SchwidefskyENDPROC(__switch_to) 2224bfc86ceSHeiko Carstens 223d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 224d0fc4107SMartin Schwidefsky/* 225d0fc4107SMartin Schwidefsky * sie64a calling convention: 226d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block 227d0fc4107SMartin Schwidefsky * %r3 guest register save area 228d0fc4107SMartin Schwidefsky */ 229d0fc4107SMartin SchwidefskyENTRY(sie64a) 230d0fc4107SMartin Schwidefsky stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 2316b73044bSMartin Schwidefsky lg %r12,__LC_CURRENT 23292fa7a13SMartin Schwidefsky stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer 23392fa7a13SMartin Schwidefsky stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area 23492fa7a13SMartin Schwidefsky xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 23592fa7a13SMartin Schwidefsky mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 236d0fc4107SMartin Schwidefsky lmg %r0,%r13,0(%r3) # load guest gprs 0-13 237d0fc4107SMartin Schwidefsky lg %r14,__LC_GMAP # get gmap pointer 238d0fc4107SMartin Schwidefsky ltgr %r14,%r14 239d0fc4107SMartin Schwidefsky jz .Lsie_gmap 240d0fc4107SMartin Schwidefsky lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 241d0fc4107SMartin Schwidefsky.Lsie_gmap: 24292fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 243d0fc4107SMartin Schwidefsky oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 244d0fc4107SMartin Schwidefsky tm __SIE_PROG20+3(%r14),3 # last exit... 245d0fc4107SMartin Schwidefsky jnz .Lsie_skip 24683abeffbSHendrik Brueckner TSTMSK __LC_CPU_FLAGS,_CIF_FPU 247d0fc4107SMartin Schwidefsky jo .Lsie_skip # exit if fp/vx regs changed 24892fa7a13SMartin Schwidefsky BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 249c929500dSQingFeng Hao.Lsie_entry: 250d0fc4107SMartin Schwidefsky sie 0(%r14) 251d768bd89SMartin Schwidefsky BPOFF 25292fa7a13SMartin Schwidefsky BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 253d0fc4107SMartin Schwidefsky.Lsie_skip: 254d0fc4107SMartin Schwidefsky ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 25587d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 256d0fc4107SMartin Schwidefsky.Lsie_done: 257d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception) 258c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There 259c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. 260c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program 261c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. 262c0e7bb38SChristian Borntraeger.Lrewind_pad6: 263c0e7bb38SChristian Borntraeger nopr 7 264c0e7bb38SChristian Borntraeger.Lrewind_pad4: 265c0e7bb38SChristian Borntraeger nopr 7 266c0e7bb38SChristian Borntraeger.Lrewind_pad2: 267c0e7bb38SChristian Borntraeger nopr 7 268d0fc4107SMartin Schwidefsky .globl sie_exit 269d0fc4107SMartin Schwidefskysie_exit: 27092fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area 271d0fc4107SMartin Schwidefsky stmg %r0,%r13,0(%r14) # save guest gprs 0-13 2727041d281SMartin Schwidefsky xgr %r0,%r0 # clear guest registers to 2737041d281SMartin Schwidefsky xgr %r1,%r1 # prevent speculative use 2747041d281SMartin Schwidefsky xgr %r3,%r3 2757041d281SMartin Schwidefsky xgr %r4,%r4 2767041d281SMartin Schwidefsky xgr %r5,%r5 277d0fc4107SMartin Schwidefsky lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 27892fa7a13SMartin Schwidefsky lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 2796dd85fbbSMartin Schwidefsky BR_EX %r14 280d0fc4107SMartin Schwidefsky.Lsie_fault: 281d0fc4107SMartin Schwidefsky lghi %r14,-EFAULT 28292fa7a13SMartin Schwidefsky stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 283d0fc4107SMartin Schwidefsky j sie_exit 284d0fc4107SMartin Schwidefsky 285c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad6,.Lsie_fault) 286c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad4,.Lsie_fault) 287c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad2,.Lsie_fault) 288d0fc4107SMartin Schwidefsky EX_TABLE(sie_exit,.Lsie_fault) 28926a374aeSMartin SchwidefskyENDPROC(sie64a) 290711f5df7SAl ViroEXPORT_SYMBOL(sie64a) 291711f5df7SAl ViroEXPORT_SYMBOL(sie_exit) 292d0fc4107SMartin Schwidefsky#endif 293d0fc4107SMartin Schwidefsky 2944bfc86ceSHeiko Carstens/* 2954bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and 2967b7735c5SChristian Borntraeger * are entered with interrupts disabled. 2974bfc86ceSHeiko Carstens */ 2984bfc86ceSHeiko Carstens 2994bfc86ceSHeiko CarstensENTRY(system_call) 30056e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 3014bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 302d768bd89SMartin Schwidefsky BPOFF 30356e62a73SSven Schnelle lghi %r14,0 3044bfc86ceSHeiko Carstens.Lsysc_per: 30587d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 30656e62a73SSven Schnelle lg %r12,__LC_CURRENT 3074bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 3089365965dSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 30956e62a73SSven Schnelle stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 31056e62a73SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 311d3f46896SChristian Borntraeger # clear user controlled register to prevent speculative use 312d3f46896SChristian Borntraeger xgr %r0,%r0 31356e62a73SSven Schnelle xgr %r1,%r1 31456e62a73SSven Schnelle xgr %r4,%r4 31556e62a73SSven Schnelle xgr %r5,%r5 31656e62a73SSven Schnelle xgr %r6,%r6 31756e62a73SSven Schnelle xgr %r7,%r7 31856e62a73SSven Schnelle xgr %r8,%r8 31956e62a73SSven Schnelle xgr %r9,%r9 32056e62a73SSven Schnelle xgr %r10,%r10 32156e62a73SSven Schnelle xgr %r11,%r11 32256e62a73SSven Schnelle la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 323af9ad822SSven Schnelle mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC 32456e62a73SSven Schnelle lgr %r3,%r14 32556e62a73SSven Schnelle brasl %r14,__do_syscall 32687d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 32756e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3286b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 32956e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3304bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 3310b0ed657SSven Schnelle b __LC_RETURN_LPSWE 33226a374aeSMartin SchwidefskyENDPROC(system_call) 3334bfc86ceSHeiko Carstens 3344bfc86ceSHeiko Carstens# 3354bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork 3364bfc86ceSHeiko Carstens# 3374bfc86ceSHeiko CarstensENTRY(ret_from_fork) 33856e62a73SSven Schnelle lgr %r3,%r11 33956e62a73SSven Schnelle brasl %r14,__ret_from_fork 34056e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 34156e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 34256e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 34356e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 34456e62a73SSven Schnelle stpt __LC_EXIT_TIMER 34556e62a73SSven Schnelle b __LC_RETURN_LPSWE 34626a374aeSMartin SchwidefskyENDPROC(ret_from_fork) 34726a374aeSMartin Schwidefsky 3484bfc86ceSHeiko Carstens/* 3494bfc86ceSHeiko Carstens * Program check handler routine 3504bfc86ceSHeiko Carstens */ 3514bfc86ceSHeiko Carstens 3524bfc86ceSHeiko CarstensENTRY(pgm_check_handler) 35356e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 354d768bd89SMartin Schwidefsky BPOFF 3554bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 35656e62a73SSven Schnelle lg %r12,__LC_CURRENT 35756e62a73SSven Schnelle lghi %r10,0 3584bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_PGM_OLD_PSW 35987d59863SHeiko Carstens tmhh %r8,0x0001 # coming from user space? 36087d59863SHeiko Carstens jno .Lpgm_skip_asce 36187d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 36256e62a73SSven Schnelle j 3f # -> fault in user space 36387d59863SHeiko Carstens.Lpgm_skip_asce: 364d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 3650a5e2ec2SMartin Schwidefsky # cleanup critical section for program checks in sie64a 366b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f 367fbbdfca5SAlexander Gordeev SIEEXIT 36856e62a73SSven Schnelle lghi %r10,_PIF_GUEST_FAULT 369d0fc4107SMartin Schwidefsky#endif 3700b38b5e1SSven Schnelle1: tmhh %r8,0x4000 # PER bit set in old PSW ? 3710b38b5e1SSven Schnelle jnz 2f # -> enabled, can't be a double fault 3724bfc86ceSHeiko Carstens tm __LC_PGM_ILC+3,0x80 # check for per exception 3734bfc86ceSHeiko Carstens jnz .Lpgm_svcper # -> single stepped svc 3740b38b5e1SSven Schnelle2: CHECK_STACK __LC_SAVE_AREA_SYNC 3754bfc86ceSHeiko Carstens aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 37656e62a73SSven Schnelle # CHECK_VMAP_STACK branches to stack_overflow or 4f 37756e62a73SSven Schnelle CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f 37856e62a73SSven Schnelle3: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 3794bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 38056e62a73SSven Schnelle4: la %r11,STACK_FRAME_OVERHEAD(%r15) 38156e62a73SSven Schnelle stg %r10,__PT_FLAGS(%r11) 38256e62a73SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 3834bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 38456e62a73SSven Schnelle mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC 38556e62a73SSven Schnelle stmg %r8,%r9,__PT_PSW(%r11) 38656e62a73SSven Schnelle 3877041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 3887041d281SMartin Schwidefsky xgr %r0,%r0 3897041d281SMartin Schwidefsky xgr %r1,%r1 3907041d281SMartin Schwidefsky xgr %r3,%r3 3917041d281SMartin Schwidefsky xgr %r4,%r4 3927041d281SMartin Schwidefsky xgr %r5,%r5 3937041d281SMartin Schwidefsky xgr %r6,%r6 3947041d281SMartin Schwidefsky xgr %r7,%r7 39556e62a73SSven Schnelle lgr %r2,%r11 39656e62a73SSven Schnelle brasl %r14,__do_pgm_check 39756e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user space? 39856e62a73SSven Schnelle jno .Lpgm_exit_kernel 39956e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 40056e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4010cd9b723SHeiko Carstens stpt __LC_EXIT_TIMER 40256e62a73SSven Schnelle.Lpgm_exit_kernel: 40356e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 40456e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 4050cd9b723SHeiko Carstens b __LC_RETURN_LPSWE 4064bfc86ceSHeiko Carstens 4074bfc86ceSHeiko Carstens# 4084bfc86ceSHeiko Carstens# single stepped system call 4094bfc86ceSHeiko Carstens# 4104bfc86ceSHeiko Carstens.Lpgm_svcper: 4114bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 4124bfc86ceSHeiko Carstens larl %r14,.Lsysc_per 4134bfc86ceSHeiko Carstens stg %r14,__LC_RETURN_PSW+8 41456e62a73SSven Schnelle lghi %r14,1 4150b0ed657SSven Schnelle lpswe __LC_RETURN_PSW # branch to .Lsysc_per 41626a374aeSMartin SchwidefskyENDPROC(pgm_check_handler) 4174bfc86ceSHeiko Carstens 4184bfc86ceSHeiko Carstens/* 41956e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts. 4204bfc86ceSHeiko Carstens */ 42156e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler 42256e62a73SSven SchnelleENTRY(\name) 4234bfc86ceSHeiko Carstens STCK __LC_INT_CLOCK 42456e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 425d768bd89SMartin Schwidefsky BPOFF 4264bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_ASYNC 427d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 42856e62a73SSven Schnelle lmg %r8,%r9,\lc_old_psw 429b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 430b0d31159SSven Schnelle jnz 1f 431b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 432b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f 433fbbdfca5SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 434fbbdfca5SAlexander Gordeev SIEEXIT 435b0d31159SSven Schnelle#endif 436b0d31159SSven Schnelle0: CHECK_STACK __LC_SAVE_AREA_ASYNC 437b0d31159SSven Schnelle aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 438b0d31159SSven Schnelle j 2f 439b0d31159SSven Schnelle1: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 440b0d31159SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 441b0d31159SSven Schnelle lg %r15,__LC_KERNEL_STACK 442b74e409eSVasily Gorbik2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 443b74e409eSVasily Gorbik la %r11,STACK_FRAME_OVERHEAD(%r15) 4444bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 4457041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4467041d281SMartin Schwidefsky xgr %r0,%r0 4477041d281SMartin Schwidefsky xgr %r1,%r1 4487041d281SMartin Schwidefsky xgr %r3,%r3 4497041d281SMartin Schwidefsky xgr %r4,%r4 4507041d281SMartin Schwidefsky xgr %r5,%r5 4517041d281SMartin Schwidefsky xgr %r6,%r6 4527041d281SMartin Schwidefsky xgr %r7,%r7 4537041d281SMartin Schwidefsky xgr %r10,%r10 454ca1f4d70SSven Schnelle xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 4554bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 4564bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 45756e62a73SSven Schnelle tm %r8,0x0001 # coming from user space? 45856e62a73SSven Schnelle jno 1f 45987d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 46056e62a73SSven Schnelle1: lgr %r2,%r11 # pass pointer to pt_regs 46156e62a73SSven Schnelle brasl %r14,\handler 4624bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 46356e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 46456e62a73SSven Schnelle jno 2f 46587d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4666b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4674bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 46856e62a73SSven Schnelle2: lmg %r0,%r15,__PT_R0(%r11) 4690b0ed657SSven Schnelle b __LC_RETURN_LPSWE 47056e62a73SSven SchnelleENDPROC(\name) 47156e62a73SSven Schnelle.endm 4724bfc86ceSHeiko Carstens 47356e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 47456e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 4754bfc86ceSHeiko Carstens 4764bfc86ceSHeiko Carstens/* 4770b0ed657SSven Schnelle * Load idle PSW. 4784bfc86ceSHeiko Carstens */ 4794bfc86ceSHeiko CarstensENTRY(psw_idle) 480a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 4814bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 48256e62a73SSven Schnelle larl %r1,psw_idle_exit 4834bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 48472d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 48572d38b19SMartin Schwidefsky llgf %r1,0(%r1) 48672d38b19SMartin Schwidefsky ltgr %r1,%r1 48772d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 48856e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 48972d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 490419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 491d768bd89SMartin Schwidefsky BPON 4924bfc86ceSHeiko Carstens STCK __CLOCK_IDLE_ENTER(%r2) 4934bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 4944bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 49556e62a73SSven Schnelle.globl psw_idle_exit 49656e62a73SSven Schnellepsw_idle_exit: 4976dd85fbbSMartin Schwidefsky BR_EX %r14 49826a374aeSMartin SchwidefskyENDPROC(psw_idle) 4994bfc86ceSHeiko Carstens 500b5510d9bSHendrik Brueckner/* 5014bfc86ceSHeiko Carstens * Machine check handler routines 5024bfc86ceSHeiko Carstens */ 5034bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 5044bfc86ceSHeiko Carstens STCK __LC_MCCK_CLOCK 505d768bd89SMartin Schwidefsky BPOFF 5063037a52fSMartin Schwidefsky la %r1,4095 # validate r1 5073037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 5083037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 509d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 5104bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 51183abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 5124bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 5133037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 5143037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5153037a52fSMartin Schwidefsky la %r14,4095 5163037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5173037a52fSMartin Schwidefsky ptlb 5185fa2ea07SAlexander Gordeev lghi %r14,__LC_CPU_TIMER_SAVE_AREA 5194bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 52083abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID 5214bfc86ceSHeiko Carstens jo 3f 52256e62a73SSven Schnelle la %r14,__LC_SYS_ENTER_TIMER 52356e62a73SSven Schnelle clc 0(8,%r14),__LC_EXIT_TIMER 5244bfc86ceSHeiko Carstens jl 1f 5254bfc86ceSHeiko Carstens la %r14,__LC_EXIT_TIMER 5264bfc86ceSHeiko Carstens1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 5274bfc86ceSHeiko Carstens jl 2f 5284bfc86ceSHeiko Carstens la %r14,__LC_LAST_UPDATE_TIMER 5294bfc86ceSHeiko Carstens2: spt 0(%r14) 5304bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 5313037a52fSMartin Schwidefsky3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 5323037a52fSMartin Schwidefsky jno .Lmcck_panic 5333037a52fSMartin Schwidefsky tmhh %r8,0x0001 # interrupting from user ? 534d35925b3SAlexander Gordeev jnz 6f 5353037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5363037a52fSMartin Schwidefsky jno .Lmcck_panic 537b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 538d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f 539d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_skip,4f 54020232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 541d35925b3SAlexander Gordeev j 5f 542d35925b3SAlexander Gordeev4: CHKSTG .Lmcck_panic 543d35925b3SAlexander Gordeev5: larl %r14,.Lstosm_tmp 544d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 545d35925b3SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 546fbbdfca5SAlexander Gordeev SIEEXIT 547b61b1595SSven Schnelle j .Lmcck_stack 548e2c13d64SAlexander Gordeev#endif 549d35925b3SAlexander Gordeev6: CHKSTG .Lmcck_panic 550d35925b3SAlexander Gordeev larl %r14,.Lstosm_tmp 551d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 552d35925b3SAlexander Gordeev tmhh %r8,0x0001 # interrupting from user ? 553d35925b3SAlexander Gordeev jz .Lmcck_stack 554b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 555b61b1595SSven Schnelle.Lmcck_stack: 556b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 557b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 55826521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 559b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 560b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5614bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5624bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5637041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5647041d281SMartin Schwidefsky xgr %r0,%r0 5657041d281SMartin Schwidefsky xgr %r1,%r1 5667041d281SMartin Schwidefsky xgr %r3,%r3 5677041d281SMartin Schwidefsky xgr %r4,%r4 5687041d281SMartin Schwidefsky xgr %r5,%r5 5697041d281SMartin Schwidefsky xgr %r6,%r6 5707041d281SMartin Schwidefsky xgr %r7,%r7 5717041d281SMartin Schwidefsky xgr %r10,%r10 5724bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 5734bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 5744bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 5754bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5764bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 5774bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 5780b0ed657SSven Schnelle cghi %r2,0 5790b0ed657SSven Schnelle je .Lmcck_return 5804bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 5814bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 5824bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 5834bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 5844bfc86ceSHeiko Carstens lgr %r15,%r1 5854bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 5864bfc86ceSHeiko Carstens.Lmcck_return: 58787d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 5884bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 5894bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 5904bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 5914bfc86ceSHeiko Carstens jno 0f 5926b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 5934bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 5944bfc86ceSHeiko Carstens0: lmg %r11,%r15,__PT_R11(%r11) 5950b38b5e1SSven Schnelle b __LC_RETURN_MCCK_LPSWE 5964bfc86ceSHeiko Carstens 5974bfc86ceSHeiko Carstens.Lmcck_panic: 5987f6dc8d4SAlexander Gordeev /* 5997f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 6007f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 6017f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 6027f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 6037f6dc8d4SAlexander Gordeev */ 6047f6dc8d4SAlexander Gordeev lhi %r5,0 6057f6dc8d4SAlexander Gordeev lhi %r6,1 6067f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 6077f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 6087f6dc8d4SAlexander Gordeev jnz 4f 6097f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 6107f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 6117f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 6127f6dc8d4SAlexander Gordeev nilh %r4,0 6137f6dc8d4SAlexander Gordeev lhi %r0,1 6147f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 6157f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 6167f6dc8d4SAlexander Gordeev0: cr %r3,%r4 6177f6dc8d4SAlexander Gordeev je 2f 6187f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 6197f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 6207f6dc8d4SAlexander Gordeev2: ahi %r3,1 6217f6dc8d4SAlexander Gordeev brct %r0,0b 6227f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 6237f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 6247f6dc8d4SAlexander Gordeev4: j 4b 62526a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6264bfc86ceSHeiko Carstens 6274bfc86ceSHeiko CarstensENTRY(restart_int_handler) 628e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 629e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 630*915fea04SAlexander Gordeev TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4 631*915fea04SAlexander Gordeev jz 0f 632*915fea04SAlexander Gordeev la %r15,4095 633*915fea04SAlexander Gordeev lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15) 634*915fea04SAlexander Gordeev0: larl %r15,.Lstosm_tmp 635*915fea04SAlexander Gordeev stosm 0(%r15),0x04 # turn dat on, keep irqs off 6364bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 637ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 638ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 639ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 640ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6414bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6424bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6434bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 644*915fea04SAlexander Gordeev lgf %r3,__LC_RESTART_SOURCE 6454bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6464bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6474bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6484bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6494bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6504bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6514bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6524bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6534bfc86ceSHeiko Carstens brc 2,2b 6544bfc86ceSHeiko Carstens3: j 3b 65526a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6564bfc86ceSHeiko Carstens 6574bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6584bfc86ceSHeiko Carstens 659ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6604bfc86ceSHeiko Carstens/* 6614bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6624bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6634bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6644bfc86ceSHeiko Carstens */ 66526a374aeSMartin SchwidefskyENTRY(stack_overflow) 666ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6674bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6684bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6694bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6704bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6714bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 6724bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6734bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6744bfc86ceSHeiko Carstens jg kernel_stack_overflow 67526a374aeSMartin SchwidefskyENDPROC(stack_overflow) 6764bfc86ceSHeiko Carstens#endif 6774bfc86ceSHeiko Carstens 6787f6dc8d4SAlexander Gordeev .section .data, "aw" 6797f6dc8d4SAlexander Gordeev .align 4 6807f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 6817f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 682d35925b3SAlexander Gordeev.Lstosm_tmp: .byte 0 6834bfc86ceSHeiko Carstens .section .rodata, "a" 684ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 6854bfc86ceSHeiko Carstens .globl sys_call_table 6864bfc86ceSHeiko Carstenssys_call_table: 6874381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 6884bfc86ceSHeiko Carstens#undef SYSCALL 6894bfc86ceSHeiko Carstens 6904bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 6914bfc86ceSHeiko Carstens 692ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 6934bfc86ceSHeiko Carstens .globl sys_call_table_emu 6944bfc86ceSHeiko Carstenssys_call_table_emu: 6954381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 6964bfc86ceSHeiko Carstens#undef SYSCALL 6974bfc86ceSHeiko Carstens#endif 698