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 323a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER 334bfc86ceSHeiko CarstensSTACK_SIZE = 1 << STACK_SHIFT 344bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE 354bfc86ceSHeiko Carstens 36e5b98199SMartin Schwidefsky_LPP_OFFSET = __LC_LPP 37e5b98199SMartin Schwidefsky 383b051e89SSven Schnelle .macro STBEAR address 39fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193 403b051e89SSven Schnelle .endm 413b051e89SSven Schnelle 423b051e89SSven Schnelle .macro LBEAR address 43fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193 443b051e89SSven Schnelle .endm 453b051e89SSven Schnelle 463b051e89SSven Schnelle .macro LPSWEY address,lpswe 47fad442d3SHeiko Carstens ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193 483b051e89SSven Schnelle .endm 493b051e89SSven Schnelle 503b051e89SSven Schnelle .macro MBEAR reg 51fad442d3SHeiko Carstens ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193 523b051e89SSven Schnelle .endm 533b051e89SSven Schnelle 54ce3dc447SMartin Schwidefsky .macro CHECK_STACK savearea 554bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK 56ce3dc447SMartin Schwidefsky tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 574bfc86ceSHeiko Carstens lghi %r14,\savearea 584bfc86ceSHeiko Carstens jz stack_overflow 594bfc86ceSHeiko Carstens#endif 604bfc86ceSHeiko Carstens .endm 614bfc86ceSHeiko Carstens 62ce3dc447SMartin Schwidefsky .macro CHECK_VMAP_STACK savearea,oklabel 63ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK 64ce3dc447SMartin Schwidefsky lgr %r14,%r15 65ce3dc447SMartin Schwidefsky nill %r14,0x10000 - STACK_SIZE 66ce3dc447SMartin Schwidefsky oill %r14,STACK_INIT 67ce3dc447SMartin Schwidefsky clg %r14,__LC_KERNEL_STACK 68ce3dc447SMartin Schwidefsky je \oklabel 69ce3dc447SMartin Schwidefsky clg %r14,__LC_ASYNC_STACK 70ce3dc447SMartin Schwidefsky je \oklabel 71b61b1595SSven Schnelle clg %r14,__LC_MCCK_STACK 72b61b1595SSven Schnelle je \oklabel 73ce3dc447SMartin Schwidefsky clg %r14,__LC_NODAT_STACK 74ce3dc447SMartin Schwidefsky je \oklabel 75ce3dc447SMartin Schwidefsky clg %r14,__LC_RESTART_STACK 76ce3dc447SMartin Schwidefsky je \oklabel 77ce3dc447SMartin Schwidefsky lghi %r14,\savearea 78ce3dc447SMartin Schwidefsky j stack_overflow 79ce3dc447SMartin Schwidefsky#else 80ce3dc447SMartin Schwidefsky j \oklabel 81ce3dc447SMartin Schwidefsky#endif 82ce3dc447SMartin Schwidefsky .endm 83ce3dc447SMartin Schwidefsky 8483abeffbSHendrik Brueckner /* 8583abeffbSHendrik Brueckner * The TSTMSK macro generates a test-under-mask instruction by 8683abeffbSHendrik Brueckner * calculating the memory offset for the specified mask value. 8783abeffbSHendrik Brueckner * Mask value can be any constant. The macro shifts the mask 8883abeffbSHendrik Brueckner * value to calculate the memory offset for the test-under-mask 8983abeffbSHendrik Brueckner * instruction. 9083abeffbSHendrik Brueckner */ 9183abeffbSHendrik Brueckner .macro TSTMSK addr, mask, size=8, bytepos=0 9283abeffbSHendrik Brueckner .if (\bytepos < \size) && (\mask >> 8) 9383abeffbSHendrik Brueckner .if (\mask & 0xff) 9483abeffbSHendrik Brueckner .error "Mask exceeds byte boundary" 9583abeffbSHendrik Brueckner .endif 9683abeffbSHendrik Brueckner TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)" 9783abeffbSHendrik Brueckner .exitm 9883abeffbSHendrik Brueckner .endif 9983abeffbSHendrik Brueckner .ifeq \mask 10083abeffbSHendrik Brueckner .error "Mask must not be zero" 10183abeffbSHendrik Brueckner .endif 10283abeffbSHendrik Brueckner off = \size - \bytepos - 1 10383abeffbSHendrik Brueckner tm off+\addr, \mask 10483abeffbSHendrik Brueckner .endm 10583abeffbSHendrik Brueckner 106d768bd89SMartin Schwidefsky .macro BPOFF 107fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82 108d768bd89SMartin Schwidefsky .endm 109d768bd89SMartin Schwidefsky 110d768bd89SMartin Schwidefsky .macro BPON 111fad442d3SHeiko Carstens ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82 112d768bd89SMartin Schwidefsky .endm 113d768bd89SMartin Schwidefsky 1146b73044bSMartin Schwidefsky .macro BPENTER tif_ptr,tif_mask 1156982dba1SHeiko Carstens ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \ 116fad442d3SHeiko Carstens "j .+12; nop; nop", 82 1176b73044bSMartin Schwidefsky .endm 1186b73044bSMartin Schwidefsky 1196b73044bSMartin Schwidefsky .macro BPEXIT tif_ptr,tif_mask 1206b73044bSMartin Schwidefsky TSTMSK \tif_ptr,\tif_mask 1216982dba1SHeiko Carstens ALTERNATIVE "jz .+8; .insn rrf,0xb2e80000,0,0,12,0", \ 1226982dba1SHeiko Carstens "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82 1236b73044bSMartin Schwidefsky .endm 1246b73044bSMartin Schwidefsky 125b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM) 126b5415c8fSAlexander Gordeev /* 127b5415c8fSAlexander Gordeev * The OUTSIDE macro jumps to the provided label in case the value 128b5415c8fSAlexander Gordeev * in the provided register is outside of the provided range. The 129b5415c8fSAlexander Gordeev * macro is useful for checking whether a PSW stored in a register 130b5415c8fSAlexander Gordeev * pair points inside or outside of a block of instructions. 131b5415c8fSAlexander Gordeev * @reg: register to check 132b5415c8fSAlexander Gordeev * @start: start of the range 133b5415c8fSAlexander Gordeev * @end: end of the range 134b5415c8fSAlexander Gordeev * @outside_label: jump here if @reg is outside of [@start..@end) 135b5415c8fSAlexander Gordeev */ 136b5415c8fSAlexander Gordeev .macro OUTSIDE reg,start,end,outside_label 137b5415c8fSAlexander Gordeev lgr %r14,\reg 138b5415c8fSAlexander Gordeev larl %r13,\start 139b5415c8fSAlexander Gordeev slgr %r14,%r13 1404c25f0ffSHeiko Carstens#ifdef CONFIG_AS_IS_LLVM 1414c25f0ffSHeiko Carstens clgfrl %r14,.Lrange_size\@ 1424c25f0ffSHeiko Carstens#else 1434c25f0ffSHeiko Carstens clgfi %r14,\end - \start 1444c25f0ffSHeiko Carstens#endif 145b5415c8fSAlexander Gordeev jhe \outside_label 1464c25f0ffSHeiko Carstens#ifdef CONFIG_AS_IS_LLVM 1474c25f0ffSHeiko Carstens .section .rodata, "a" 1484c25f0ffSHeiko Carstens .align 4 1494c25f0ffSHeiko Carstens.Lrange_size\@: 1504c25f0ffSHeiko Carstens .long \end - \start 1514c25f0ffSHeiko Carstens .previous 1524c25f0ffSHeiko Carstens#endif 153b5415c8fSAlexander Gordeev .endm 154fbbdfca5SAlexander Gordeev 155fbbdfca5SAlexander Gordeev .macro SIEEXIT 156fbbdfca5SAlexander Gordeev lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer 157fbbdfca5SAlexander Gordeev ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 158fbbdfca5SAlexander Gordeev lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 159fbbdfca5SAlexander Gordeev larl %r9,sie_exit # skip forward to sie_exit 160fbbdfca5SAlexander Gordeev .endm 161b5415c8fSAlexander Gordeev#endif 162b5415c8fSAlexander Gordeev 1636dd85fbbSMartin Schwidefsky GEN_BR_THUNK %r14 164f19fbd5eSMartin Schwidefsky 1654bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 16646210c44SHeiko Carstens.Ldummy: 16746210c44SHeiko Carstens /* 16856e62a73SSven Schnelle * This nop exists only in order to avoid that __bpon starts at 16946210c44SHeiko Carstens * the beginning of the kprobes text section. In that case we would 17046210c44SHeiko Carstens * have several symbols at the same address. E.g. objdump would take 17146210c44SHeiko Carstens * an arbitrary symbol name when disassembling this code. 17256e62a73SSven Schnelle * With the added nop in between the __bpon symbol is unique 17346210c44SHeiko Carstens * again. 17446210c44SHeiko Carstens */ 17546210c44SHeiko Carstens nop 0 1764bfc86ceSHeiko Carstens 177d768bd89SMartin SchwidefskyENTRY(__bpon) 178d768bd89SMartin Schwidefsky .globl __bpon 179d768bd89SMartin Schwidefsky BPON 1806dd85fbbSMartin Schwidefsky BR_EX %r14 18126a374aeSMartin SchwidefskyENDPROC(__bpon) 182d768bd89SMartin Schwidefsky 1834bfc86ceSHeiko Carstens/* 1844bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to 1854bfc86ceSHeiko Carstens * gpr2 = (task_struct *) prev 1864bfc86ceSHeiko Carstens * gpr3 = (task_struct *) next 1874bfc86ceSHeiko Carstens * Returns: 1884bfc86ceSHeiko Carstens * gpr2 = prev 1894bfc86ceSHeiko Carstens */ 1904bfc86ceSHeiko CarstensENTRY(__switch_to) 1914bfc86ceSHeiko Carstens stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 1923241d3ebSHeiko Carstens lghi %r4,__TASK_stack 1933241d3ebSHeiko Carstens lghi %r1,__TASK_thread 1949fed920eSVasily Gorbik llill %r5,STACK_INIT 1953241d3ebSHeiko Carstens stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev 1969fed920eSVasily Gorbik lg %r15,0(%r4,%r3) # start of kernel stack of next 1979fed920eSVasily Gorbik agr %r15,%r5 # end of kernel stack of next 1984bfc86ceSHeiko Carstens stg %r3,__LC_CURRENT # store task struct of next 1994bfc86ceSHeiko Carstens stg %r15,__LC_KERNEL_STACK # store end of kernel stack 2003241d3ebSHeiko Carstens lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next 2013241d3ebSHeiko Carstens aghi %r3,__TASK_pid 2023241d3ebSHeiko Carstens mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 2034bfc86ceSHeiko Carstens lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 204fad442d3SHeiko Carstens ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40 2056dd85fbbSMartin Schwidefsky BR_EX %r14 20626a374aeSMartin SchwidefskyENDPROC(__switch_to) 2074bfc86ceSHeiko Carstens 208d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 209d0fc4107SMartin Schwidefsky/* 210d0fc4107SMartin Schwidefsky * sie64a calling convention: 211d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block 212d0fc4107SMartin Schwidefsky * %r3 guest register save area 213d0fc4107SMartin Schwidefsky */ 214d0fc4107SMartin SchwidefskyENTRY(sie64a) 215d0fc4107SMartin Schwidefsky stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 2166b73044bSMartin Schwidefsky lg %r12,__LC_CURRENT 21792fa7a13SMartin Schwidefsky stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer 21892fa7a13SMartin Schwidefsky stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area 21992fa7a13SMartin Schwidefsky xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 22092fa7a13SMartin Schwidefsky mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 221d0fc4107SMartin Schwidefsky lmg %r0,%r13,0(%r3) # load guest gprs 0-13 222d0fc4107SMartin Schwidefsky lg %r14,__LC_GMAP # get gmap pointer 223d0fc4107SMartin Schwidefsky ltgr %r14,%r14 224d0fc4107SMartin Schwidefsky jz .Lsie_gmap 225d0fc4107SMartin Schwidefsky lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 226d0fc4107SMartin Schwidefsky.Lsie_gmap: 22792fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 228d0fc4107SMartin Schwidefsky oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 229d0fc4107SMartin Schwidefsky tm __SIE_PROG20+3(%r14),3 # last exit... 230d0fc4107SMartin Schwidefsky jnz .Lsie_skip 23183abeffbSHendrik Brueckner TSTMSK __LC_CPU_FLAGS,_CIF_FPU 232d0fc4107SMartin Schwidefsky jo .Lsie_skip # exit if fp/vx regs changed 23392fa7a13SMartin Schwidefsky BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 234c929500dSQingFeng Hao.Lsie_entry: 235d0fc4107SMartin Schwidefsky sie 0(%r14) 23629ccaa4bSAlexander Gordeev# Let the next instruction be NOP to avoid triggering a machine check 23729ccaa4bSAlexander Gordeev# and handling it in a guest as result of the instruction execution. 23829ccaa4bSAlexander Gordeev nopr 7 23929ccaa4bSAlexander Gordeev.Lsie_leave: 240d768bd89SMartin Schwidefsky BPOFF 24192fa7a13SMartin Schwidefsky BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 242d0fc4107SMartin Schwidefsky.Lsie_skip: 243d0fc4107SMartin Schwidefsky ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 24487d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 245d0fc4107SMartin Schwidefsky.Lsie_done: 246d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception) 247c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There 248c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. 249c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program 250c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. 251c0e7bb38SChristian Borntraeger.Lrewind_pad6: 252c0e7bb38SChristian Borntraeger nopr 7 253c0e7bb38SChristian Borntraeger.Lrewind_pad4: 254c0e7bb38SChristian Borntraeger nopr 7 255c0e7bb38SChristian Borntraeger.Lrewind_pad2: 256c0e7bb38SChristian Borntraeger nopr 7 257d0fc4107SMartin Schwidefsky .globl sie_exit 258d0fc4107SMartin Schwidefskysie_exit: 25992fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area 260d0fc4107SMartin Schwidefsky stmg %r0,%r13,0(%r14) # save guest gprs 0-13 2617041d281SMartin Schwidefsky xgr %r0,%r0 # clear guest registers to 2627041d281SMartin Schwidefsky xgr %r1,%r1 # prevent speculative use 2637041d281SMartin Schwidefsky xgr %r3,%r3 2647041d281SMartin Schwidefsky xgr %r4,%r4 2657041d281SMartin Schwidefsky xgr %r5,%r5 266d0fc4107SMartin Schwidefsky lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 26792fa7a13SMartin Schwidefsky lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 2686dd85fbbSMartin Schwidefsky BR_EX %r14 269d0fc4107SMartin Schwidefsky.Lsie_fault: 270d0fc4107SMartin Schwidefsky lghi %r14,-EFAULT 27192fa7a13SMartin Schwidefsky stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 272d0fc4107SMartin Schwidefsky j sie_exit 273d0fc4107SMartin Schwidefsky 274c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad6,.Lsie_fault) 275c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad4,.Lsie_fault) 276c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad2,.Lsie_fault) 277d0fc4107SMartin Schwidefsky EX_TABLE(sie_exit,.Lsie_fault) 27826a374aeSMartin SchwidefskyENDPROC(sie64a) 279711f5df7SAl ViroEXPORT_SYMBOL(sie64a) 280711f5df7SAl ViroEXPORT_SYMBOL(sie_exit) 281d0fc4107SMartin Schwidefsky#endif 282d0fc4107SMartin Schwidefsky 2834bfc86ceSHeiko Carstens/* 2844bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and 2857b7735c5SChristian Borntraeger * are entered with interrupts disabled. 2864bfc86ceSHeiko Carstens */ 2874bfc86ceSHeiko Carstens 2884bfc86ceSHeiko CarstensENTRY(system_call) 28956e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 2904bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 291d768bd89SMartin Schwidefsky BPOFF 29256e62a73SSven Schnelle lghi %r14,0 2934bfc86ceSHeiko Carstens.Lsysc_per: 2943b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 29587d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 29656e62a73SSven Schnelle lg %r12,__LC_CURRENT 2974bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 2989365965dSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 29956e62a73SSven Schnelle stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 30056e62a73SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 301d3f46896SChristian Borntraeger # clear user controlled register to prevent speculative use 302d3f46896SChristian Borntraeger xgr %r0,%r0 30356e62a73SSven Schnelle xgr %r1,%r1 30456e62a73SSven Schnelle xgr %r4,%r4 30556e62a73SSven Schnelle xgr %r5,%r5 30656e62a73SSven Schnelle xgr %r6,%r6 30756e62a73SSven Schnelle xgr %r7,%r7 30856e62a73SSven Schnelle xgr %r8,%r8 30956e62a73SSven Schnelle xgr %r9,%r9 31056e62a73SSven Schnelle xgr %r10,%r10 31156e62a73SSven Schnelle xgr %r11,%r11 31256e62a73SSven Schnelle la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 313af9ad822SSven Schnelle mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC 3143b051e89SSven Schnelle MBEAR %r2 31556e62a73SSven Schnelle lgr %r3,%r14 31656e62a73SSven Schnelle brasl %r14,__do_syscall 31787d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 31856e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3196b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3203b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 32156e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3224bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 3233b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 32426a374aeSMartin SchwidefskyENDPROC(system_call) 3254bfc86ceSHeiko Carstens 3264bfc86ceSHeiko Carstens# 3274bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork 3284bfc86ceSHeiko Carstens# 3294bfc86ceSHeiko CarstensENTRY(ret_from_fork) 33056e62a73SSven Schnelle lgr %r3,%r11 33156e62a73SSven Schnelle brasl %r14,__ret_from_fork 33256e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 33356e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 33456e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3353b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 33656e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 33756e62a73SSven Schnelle stpt __LC_EXIT_TIMER 3383b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 33926a374aeSMartin SchwidefskyENDPROC(ret_from_fork) 34026a374aeSMartin Schwidefsky 3414bfc86ceSHeiko Carstens/* 3424bfc86ceSHeiko Carstens * Program check handler routine 3434bfc86ceSHeiko Carstens */ 3444bfc86ceSHeiko Carstens 3454bfc86ceSHeiko CarstensENTRY(pgm_check_handler) 34656e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 347d768bd89SMartin Schwidefsky BPOFF 3484bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 34956e62a73SSven Schnelle lg %r12,__LC_CURRENT 35056e62a73SSven Schnelle lghi %r10,0 3514bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_PGM_OLD_PSW 35287d59863SHeiko Carstens tmhh %r8,0x0001 # coming from user space? 35387d59863SHeiko Carstens jno .Lpgm_skip_asce 35487d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 35556e62a73SSven Schnelle j 3f # -> fault in user space 35687d59863SHeiko Carstens.Lpgm_skip_asce: 357d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 3580a5e2ec2SMartin Schwidefsky # cleanup critical section for program checks in sie64a 359b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f 360fbbdfca5SAlexander Gordeev SIEEXIT 36156e62a73SSven Schnelle lghi %r10,_PIF_GUEST_FAULT 362d0fc4107SMartin Schwidefsky#endif 3630b38b5e1SSven Schnelle1: tmhh %r8,0x4000 # PER bit set in old PSW ? 3640b38b5e1SSven Schnelle jnz 2f # -> enabled, can't be a double fault 3654bfc86ceSHeiko Carstens tm __LC_PGM_ILC+3,0x80 # check for per exception 3664bfc86ceSHeiko Carstens jnz .Lpgm_svcper # -> single stepped svc 3670b38b5e1SSven Schnelle2: CHECK_STACK __LC_SAVE_AREA_SYNC 3684bfc86ceSHeiko Carstens aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 36956e62a73SSven Schnelle # CHECK_VMAP_STACK branches to stack_overflow or 4f 37056e62a73SSven Schnelle CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f 37156e62a73SSven Schnelle3: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 3724bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 37356e62a73SSven Schnelle4: la %r11,STACK_FRAME_OVERHEAD(%r15) 37456e62a73SSven Schnelle stg %r10,__PT_FLAGS(%r11) 37556e62a73SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 3764bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 37756e62a73SSven Schnelle mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC 3783b051e89SSven Schnelle mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK 37956e62a73SSven Schnelle stmg %r8,%r9,__PT_PSW(%r11) 38056e62a73SSven Schnelle 3817041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 3827041d281SMartin Schwidefsky xgr %r0,%r0 3837041d281SMartin Schwidefsky xgr %r1,%r1 3847041d281SMartin Schwidefsky xgr %r3,%r3 3857041d281SMartin Schwidefsky xgr %r4,%r4 3867041d281SMartin Schwidefsky xgr %r5,%r5 3877041d281SMartin Schwidefsky xgr %r6,%r6 3887041d281SMartin Schwidefsky xgr %r7,%r7 38956e62a73SSven Schnelle lgr %r2,%r11 39056e62a73SSven Schnelle brasl %r14,__do_pgm_check 39156e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user space? 39256e62a73SSven Schnelle jno .Lpgm_exit_kernel 39356e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 39456e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3950cd9b723SHeiko Carstens stpt __LC_EXIT_TIMER 39656e62a73SSven Schnelle.Lpgm_exit_kernel: 39756e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3983b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 39956e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 4003b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 4014bfc86ceSHeiko Carstens 4024bfc86ceSHeiko Carstens# 4034bfc86ceSHeiko Carstens# single stepped system call 4044bfc86ceSHeiko Carstens# 4054bfc86ceSHeiko Carstens.Lpgm_svcper: 4064bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 4074bfc86ceSHeiko Carstens larl %r14,.Lsysc_per 4084bfc86ceSHeiko Carstens stg %r14,__LC_RETURN_PSW+8 40956e62a73SSven Schnelle lghi %r14,1 4103b051e89SSven Schnelle LBEAR __LC_PGM_LAST_BREAK 4113b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per 41226a374aeSMartin SchwidefskyENDPROC(pgm_check_handler) 4134bfc86ceSHeiko Carstens 4144bfc86ceSHeiko Carstens/* 41556e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts. 4164bfc86ceSHeiko Carstens */ 41756e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler 41856e62a73SSven SchnelleENTRY(\name) 41910bc15baSVasily Gorbik stckf __LC_INT_CLOCK 42056e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 4213b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 422d768bd89SMartin Schwidefsky BPOFF 4234bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_ASYNC 424d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 42556e62a73SSven Schnelle lmg %r8,%r9,\lc_old_psw 426b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 427b0d31159SSven Schnelle jnz 1f 428b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 429b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f 430fbbdfca5SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 431fbbdfca5SAlexander Gordeev SIEEXIT 432b0d31159SSven Schnelle#endif 433b0d31159SSven Schnelle0: CHECK_STACK __LC_SAVE_AREA_ASYNC 434b0d31159SSven Schnelle aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 435b0d31159SSven Schnelle j 2f 436b0d31159SSven Schnelle1: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 437b0d31159SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 438b0d31159SSven Schnelle lg %r15,__LC_KERNEL_STACK 439b74e409eSVasily Gorbik2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 440b74e409eSVasily Gorbik la %r11,STACK_FRAME_OVERHEAD(%r15) 4414bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 4427041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4437041d281SMartin Schwidefsky xgr %r0,%r0 4447041d281SMartin Schwidefsky xgr %r1,%r1 4457041d281SMartin Schwidefsky xgr %r3,%r3 4467041d281SMartin Schwidefsky xgr %r4,%r4 4477041d281SMartin Schwidefsky xgr %r5,%r5 4487041d281SMartin Schwidefsky xgr %r6,%r6 4497041d281SMartin Schwidefsky xgr %r7,%r7 4507041d281SMartin Schwidefsky xgr %r10,%r10 451ca1f4d70SSven Schnelle xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 4524bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 4533b051e89SSven Schnelle MBEAR %r11 4544bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 45529b06ad7SHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 45656e62a73SSven Schnelle brasl %r14,\handler 4574bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 45856e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 45956e62a73SSven Schnelle jno 2f 46087d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4616b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4624bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 4633b051e89SSven Schnelle2: LBEAR __PT_LAST_BREAK(%r11) 4643b051e89SSven Schnelle lmg %r0,%r15,__PT_R0(%r11) 4653b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 46656e62a73SSven SchnelleENDPROC(\name) 46756e62a73SSven Schnelle.endm 4684bfc86ceSHeiko Carstens 46956e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 47056e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 4714bfc86ceSHeiko Carstens 4724bfc86ceSHeiko Carstens/* 4730b0ed657SSven Schnelle * Load idle PSW. 4744bfc86ceSHeiko Carstens */ 4754bfc86ceSHeiko CarstensENTRY(psw_idle) 476a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 4774bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 47856e62a73SSven Schnelle larl %r1,psw_idle_exit 4794bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 48072d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 48172d38b19SMartin Schwidefsky llgf %r1,0(%r1) 48272d38b19SMartin Schwidefsky ltgr %r1,%r1 48372d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 48456e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 48572d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 486419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 487d768bd89SMartin Schwidefsky BPON 48810bc15baSVasily Gorbik stckf __CLOCK_IDLE_ENTER(%r2) 4894bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 4904bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 49156e62a73SSven Schnelle.globl psw_idle_exit 49256e62a73SSven Schnellepsw_idle_exit: 4936dd85fbbSMartin Schwidefsky BR_EX %r14 49426a374aeSMartin SchwidefskyENDPROC(psw_idle) 4954bfc86ceSHeiko Carstens 496b5510d9bSHendrik Brueckner/* 4974bfc86ceSHeiko Carstens * Machine check handler routines 4984bfc86ceSHeiko Carstens */ 4994bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 50010bc15baSVasily Gorbik stckf __LC_MCCK_CLOCK 501d768bd89SMartin Schwidefsky BPOFF 5023037a52fSMartin Schwidefsky la %r1,4095 # validate r1 5033037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 5043b051e89SSven Schnelle LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear 5053037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 506d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 5074bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 50883abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 5094bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 5103037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 5113037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5123037a52fSMartin Schwidefsky la %r14,4095 5133037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5143037a52fSMartin Schwidefsky ptlb 5155fa2ea07SAlexander Gordeev lghi %r14,__LC_CPU_TIMER_SAVE_AREA 5164bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 51783abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID 5184bfc86ceSHeiko Carstens jo 3f 51956e62a73SSven Schnelle la %r14,__LC_SYS_ENTER_TIMER 52056e62a73SSven Schnelle clc 0(8,%r14),__LC_EXIT_TIMER 5214bfc86ceSHeiko Carstens jl 1f 5224bfc86ceSHeiko Carstens la %r14,__LC_EXIT_TIMER 5234bfc86ceSHeiko Carstens1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 5244bfc86ceSHeiko Carstens jl 2f 5254bfc86ceSHeiko Carstens la %r14,__LC_LAST_UPDATE_TIMER 5264bfc86ceSHeiko Carstens2: spt 0(%r14) 5274bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 5283037a52fSMartin Schwidefsky3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 5293037a52fSMartin Schwidefsky jno .Lmcck_panic 5303037a52fSMartin Schwidefsky tmhh %r8,0x0001 # interrupting from user ? 531*742aed05SHeiko Carstens jnz .Lmcck_user 5323037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5333037a52fSMartin Schwidefsky jno .Lmcck_panic 534b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 535*742aed05SHeiko Carstens OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack 53629ccaa4bSAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f 53720232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 538*742aed05SHeiko Carstens4: BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 539fbbdfca5SAlexander Gordeev SIEEXIT 540b61b1595SSven Schnelle j .Lmcck_stack 541e2c13d64SAlexander Gordeev#endif 542*742aed05SHeiko Carstens.Lmcck_user: 543b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 544b61b1595SSven Schnelle.Lmcck_stack: 545b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 546b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 54726521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 548b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 549b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5504bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5514bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5527041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5537041d281SMartin Schwidefsky xgr %r0,%r0 5547041d281SMartin Schwidefsky xgr %r1,%r1 5557041d281SMartin Schwidefsky xgr %r3,%r3 5567041d281SMartin Schwidefsky xgr %r4,%r4 5577041d281SMartin Schwidefsky xgr %r5,%r5 5587041d281SMartin Schwidefsky xgr %r6,%r6 5597041d281SMartin Schwidefsky xgr %r7,%r7 5607041d281SMartin Schwidefsky xgr %r10,%r10 5614bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 5624bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 5634bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 5644bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5654bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 5664bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 5670b0ed657SSven Schnelle cghi %r2,0 5680b0ed657SSven Schnelle je .Lmcck_return 5694bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 5704bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 5714bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 5724bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 57339d62336SThomas Richter lgr %r2,%r11 5744bfc86ceSHeiko Carstens lgr %r15,%r1 5754bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 5764bfc86ceSHeiko Carstens.Lmcck_return: 57787d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 5784bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 5794bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 5804bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 5814bfc86ceSHeiko Carstens jno 0f 5826b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 5834bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 584fad442d3SHeiko Carstens0: ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193 5853b051e89SSven Schnelle LBEAR 0(%r12) 5863b051e89SSven Schnelle lmg %r11,%r15,__PT_R11(%r11) 5873b051e89SSven Schnelle LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE 5884bfc86ceSHeiko Carstens 5894bfc86ceSHeiko Carstens.Lmcck_panic: 5907f6dc8d4SAlexander Gordeev /* 5917f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 5927f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 5937f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 5947f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 5957f6dc8d4SAlexander Gordeev */ 5967f6dc8d4SAlexander Gordeev lhi %r5,0 5977f6dc8d4SAlexander Gordeev lhi %r6,1 5987f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 5997f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 6007f6dc8d4SAlexander Gordeev jnz 4f 6017f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 6027f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 6037f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 6047f6dc8d4SAlexander Gordeev nilh %r4,0 6057f6dc8d4SAlexander Gordeev lhi %r0,1 6067f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 6077f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 6087f6dc8d4SAlexander Gordeev0: cr %r3,%r4 6097f6dc8d4SAlexander Gordeev je 2f 6107f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 6117f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 6127f6dc8d4SAlexander Gordeev2: ahi %r3,1 6137f6dc8d4SAlexander Gordeev brct %r0,0b 6147f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 6157f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 6167f6dc8d4SAlexander Gordeev4: j 4b 61726a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6184bfc86ceSHeiko Carstens 6194bfc86ceSHeiko CarstensENTRY(restart_int_handler) 620fad442d3SHeiko Carstens ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40 621e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 622915fea04SAlexander Gordeev TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4 623915fea04SAlexander Gordeev jz 0f 624915fea04SAlexander Gordeev la %r15,4095 625915fea04SAlexander Gordeev lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15) 626915fea04SAlexander Gordeev0: larl %r15,.Lstosm_tmp 627915fea04SAlexander Gordeev stosm 0(%r15),0x04 # turn dat on, keep irqs off 6284bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 629ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 630ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 631ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 632ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6334bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6344bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6354bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 636915fea04SAlexander Gordeev lgf %r3,__LC_RESTART_SOURCE 6374bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6384bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6394bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6404bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6414bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6424bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6434bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6444bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6454bfc86ceSHeiko Carstens brc 2,2b 6464bfc86ceSHeiko Carstens3: j 3b 64726a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6484bfc86ceSHeiko Carstens 6494bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6504bfc86ceSHeiko Carstens 651ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6524bfc86ceSHeiko Carstens/* 6534bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6544bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6554bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6564bfc86ceSHeiko Carstens */ 65726a374aeSMartin SchwidefskyENTRY(stack_overflow) 658ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6594bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6604bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6614bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6624bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6634bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 6644bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6654bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6664bfc86ceSHeiko Carstens jg kernel_stack_overflow 66726a374aeSMartin SchwidefskyENDPROC(stack_overflow) 6684bfc86ceSHeiko Carstens#endif 6694bfc86ceSHeiko Carstens 6707f6dc8d4SAlexander Gordeev .section .data, "aw" 6717f6dc8d4SAlexander Gordeev .align 4 6727f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 6737f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 674d35925b3SAlexander Gordeev.Lstosm_tmp: .byte 0 6754bfc86ceSHeiko Carstens .section .rodata, "a" 676ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 6774bfc86ceSHeiko Carstens .globl sys_call_table 6784bfc86ceSHeiko Carstenssys_call_table: 6794381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 6804bfc86ceSHeiko Carstens#undef SYSCALL 6814bfc86ceSHeiko Carstens 6824bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 6834bfc86ceSHeiko Carstens 684ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 6854bfc86ceSHeiko Carstens .globl sys_call_table_emu 6864bfc86ceSHeiko Carstenssys_call_table_emu: 6874381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 6884bfc86ceSHeiko Carstens#undef SYSCALL 6894bfc86ceSHeiko Carstens#endif 690