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 125d35925b3SAlexander Gordeev /* 126d35925b3SAlexander Gordeev * The CHKSTG macro jumps to the provided label in case the 127d35925b3SAlexander Gordeev * machine check interruption code reports one of unrecoverable 128d35925b3SAlexander Gordeev * storage errors: 129d35925b3SAlexander Gordeev * - Storage error uncorrected 130d35925b3SAlexander Gordeev * - Storage key error uncorrected 131d35925b3SAlexander Gordeev * - Storage degradation with Failing-storage-address validity 132d35925b3SAlexander Gordeev */ 133d35925b3SAlexander Gordeev .macro CHKSTG errlabel 134d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR) 135d35925b3SAlexander Gordeev jnz \errlabel 136d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD 13715256194SHeiko Carstens jz .Loklabel\@ 138d35925b3SAlexander Gordeev TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR 139d35925b3SAlexander Gordeev jnz \errlabel 14015256194SHeiko Carstens.Loklabel\@: 141d35925b3SAlexander Gordeev .endm 142d35925b3SAlexander Gordeev 143b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM) 144b5415c8fSAlexander Gordeev /* 145b5415c8fSAlexander Gordeev * The OUTSIDE macro jumps to the provided label in case the value 146b5415c8fSAlexander Gordeev * in the provided register is outside of the provided range. The 147b5415c8fSAlexander Gordeev * macro is useful for checking whether a PSW stored in a register 148b5415c8fSAlexander Gordeev * pair points inside or outside of a block of instructions. 149b5415c8fSAlexander Gordeev * @reg: register to check 150b5415c8fSAlexander Gordeev * @start: start of the range 151b5415c8fSAlexander Gordeev * @end: end of the range 152b5415c8fSAlexander Gordeev * @outside_label: jump here if @reg is outside of [@start..@end) 153b5415c8fSAlexander Gordeev */ 154b5415c8fSAlexander Gordeev .macro OUTSIDE reg,start,end,outside_label 155b5415c8fSAlexander Gordeev lgr %r14,\reg 156b5415c8fSAlexander Gordeev larl %r13,\start 157b5415c8fSAlexander Gordeev slgr %r14,%r13 1584c25f0ffSHeiko Carstens#ifdef CONFIG_AS_IS_LLVM 1594c25f0ffSHeiko Carstens clgfrl %r14,.Lrange_size\@ 1604c25f0ffSHeiko Carstens#else 1614c25f0ffSHeiko Carstens clgfi %r14,\end - \start 1624c25f0ffSHeiko Carstens#endif 163b5415c8fSAlexander Gordeev jhe \outside_label 1644c25f0ffSHeiko Carstens#ifdef CONFIG_AS_IS_LLVM 1654c25f0ffSHeiko Carstens .section .rodata, "a" 1664c25f0ffSHeiko Carstens .align 4 1674c25f0ffSHeiko Carstens.Lrange_size\@: 1684c25f0ffSHeiko Carstens .long \end - \start 1694c25f0ffSHeiko Carstens .previous 1704c25f0ffSHeiko Carstens#endif 171b5415c8fSAlexander Gordeev .endm 172fbbdfca5SAlexander Gordeev 173fbbdfca5SAlexander Gordeev .macro SIEEXIT 174fbbdfca5SAlexander Gordeev lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer 175fbbdfca5SAlexander Gordeev ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 176fbbdfca5SAlexander Gordeev lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 177fbbdfca5SAlexander Gordeev larl %r9,sie_exit # skip forward to sie_exit 178fbbdfca5SAlexander Gordeev .endm 179b5415c8fSAlexander Gordeev#endif 180b5415c8fSAlexander Gordeev 1816dd85fbbSMartin Schwidefsky GEN_BR_THUNK %r14 182f19fbd5eSMartin Schwidefsky 1834bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 18446210c44SHeiko Carstens.Ldummy: 18546210c44SHeiko Carstens /* 18656e62a73SSven Schnelle * This nop exists only in order to avoid that __bpon starts at 18746210c44SHeiko Carstens * the beginning of the kprobes text section. In that case we would 18846210c44SHeiko Carstens * have several symbols at the same address. E.g. objdump would take 18946210c44SHeiko Carstens * an arbitrary symbol name when disassembling this code. 19056e62a73SSven Schnelle * With the added nop in between the __bpon symbol is unique 19146210c44SHeiko Carstens * again. 19246210c44SHeiko Carstens */ 19346210c44SHeiko Carstens nop 0 1944bfc86ceSHeiko Carstens 195d768bd89SMartin SchwidefskyENTRY(__bpon) 196d768bd89SMartin Schwidefsky .globl __bpon 197d768bd89SMartin Schwidefsky BPON 1986dd85fbbSMartin Schwidefsky BR_EX %r14 19926a374aeSMartin SchwidefskyENDPROC(__bpon) 200d768bd89SMartin Schwidefsky 2014bfc86ceSHeiko Carstens/* 2024bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to 2034bfc86ceSHeiko Carstens * gpr2 = (task_struct *) prev 2044bfc86ceSHeiko Carstens * gpr3 = (task_struct *) next 2054bfc86ceSHeiko Carstens * Returns: 2064bfc86ceSHeiko Carstens * gpr2 = prev 2074bfc86ceSHeiko Carstens */ 2084bfc86ceSHeiko CarstensENTRY(__switch_to) 2094bfc86ceSHeiko Carstens stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 2103241d3ebSHeiko Carstens lghi %r4,__TASK_stack 2113241d3ebSHeiko Carstens lghi %r1,__TASK_thread 2129fed920eSVasily Gorbik llill %r5,STACK_INIT 2133241d3ebSHeiko Carstens stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev 2149fed920eSVasily Gorbik lg %r15,0(%r4,%r3) # start of kernel stack of next 2159fed920eSVasily Gorbik agr %r15,%r5 # end of kernel stack of next 2164bfc86ceSHeiko Carstens stg %r3,__LC_CURRENT # store task struct of next 2174bfc86ceSHeiko Carstens stg %r15,__LC_KERNEL_STACK # store end of kernel stack 2183241d3ebSHeiko Carstens lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next 2193241d3ebSHeiko Carstens aghi %r3,__TASK_pid 2203241d3ebSHeiko Carstens mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 2214bfc86ceSHeiko Carstens lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 222fad442d3SHeiko Carstens ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40 2236dd85fbbSMartin Schwidefsky BR_EX %r14 22426a374aeSMartin SchwidefskyENDPROC(__switch_to) 2254bfc86ceSHeiko Carstens 226d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 227d0fc4107SMartin Schwidefsky/* 228*6b33e68aSNico Boehr * __sie64a calling convention: 229*6b33e68aSNico Boehr * %r2 pointer to sie control block phys 230*6b33e68aSNico Boehr * %r3 pointer to sie control block virt 231*6b33e68aSNico Boehr * %r4 guest register save area 232d0fc4107SMartin Schwidefsky */ 233*6b33e68aSNico BoehrENTRY(__sie64a) 234d0fc4107SMartin Schwidefsky stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 2356b73044bSMartin Schwidefsky lg %r12,__LC_CURRENT 236*6b33e68aSNico Boehr stg %r2,__SF_SIE_CONTROL_PHYS(%r15) # save sie block physical.. 237*6b33e68aSNico Boehr stg %r3,__SF_SIE_CONTROL(%r15) # ...and virtual addresses 238*6b33e68aSNico Boehr stg %r4,__SF_SIE_SAVEAREA(%r15) # save guest register save area 23992fa7a13SMartin Schwidefsky xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 24092fa7a13SMartin Schwidefsky mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 241*6b33e68aSNico Boehr lmg %r0,%r13,0(%r4) # load guest gprs 0-13 242d0fc4107SMartin Schwidefsky lg %r14,__LC_GMAP # get gmap pointer 243d0fc4107SMartin Schwidefsky ltgr %r14,%r14 244d0fc4107SMartin Schwidefsky jz .Lsie_gmap 245d0fc4107SMartin Schwidefsky lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 246d0fc4107SMartin Schwidefsky.Lsie_gmap: 24792fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 248d0fc4107SMartin Schwidefsky oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 249d0fc4107SMartin Schwidefsky tm __SIE_PROG20+3(%r14),3 # last exit... 250d0fc4107SMartin Schwidefsky jnz .Lsie_skip 25183abeffbSHendrik Brueckner TSTMSK __LC_CPU_FLAGS,_CIF_FPU 252d0fc4107SMartin Schwidefsky jo .Lsie_skip # exit if fp/vx regs changed 253*6b33e68aSNico Boehr lg %r14,__SF_SIE_CONTROL_PHYS(%r15) # get sie block phys addr 25492fa7a13SMartin Schwidefsky BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 255c929500dSQingFeng Hao.Lsie_entry: 256d0fc4107SMartin Schwidefsky sie 0(%r14) 25729ccaa4bSAlexander Gordeev# Let the next instruction be NOP to avoid triggering a machine check 25829ccaa4bSAlexander Gordeev# and handling it in a guest as result of the instruction execution. 25929ccaa4bSAlexander Gordeev nopr 7 26029ccaa4bSAlexander Gordeev.Lsie_leave: 261d768bd89SMartin Schwidefsky BPOFF 26292fa7a13SMartin Schwidefsky BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 263d0fc4107SMartin Schwidefsky.Lsie_skip: 264*6b33e68aSNico Boehr lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 265d0fc4107SMartin Schwidefsky ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 26687d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 267d0fc4107SMartin Schwidefsky.Lsie_done: 268d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception) 269c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There 270c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. 271*6b33e68aSNico Boehr# Other instructions between __sie64a and .Lsie_done should not cause program 272c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. 273c0e7bb38SChristian Borntraeger.Lrewind_pad6: 274c0e7bb38SChristian Borntraeger nopr 7 275c0e7bb38SChristian Borntraeger.Lrewind_pad4: 276c0e7bb38SChristian Borntraeger nopr 7 277c0e7bb38SChristian Borntraeger.Lrewind_pad2: 278c0e7bb38SChristian Borntraeger nopr 7 279d0fc4107SMartin Schwidefsky .globl sie_exit 280d0fc4107SMartin Schwidefskysie_exit: 28192fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area 282d0fc4107SMartin Schwidefsky stmg %r0,%r13,0(%r14) # save guest gprs 0-13 2837041d281SMartin Schwidefsky xgr %r0,%r0 # clear guest registers to 2847041d281SMartin Schwidefsky xgr %r1,%r1 # prevent speculative use 2857041d281SMartin Schwidefsky xgr %r3,%r3 2867041d281SMartin Schwidefsky xgr %r4,%r4 2877041d281SMartin Schwidefsky xgr %r5,%r5 288d0fc4107SMartin Schwidefsky lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 28992fa7a13SMartin Schwidefsky lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 2906dd85fbbSMartin Schwidefsky BR_EX %r14 291d0fc4107SMartin Schwidefsky.Lsie_fault: 292d0fc4107SMartin Schwidefsky lghi %r14,-EFAULT 29392fa7a13SMartin Schwidefsky stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 294d0fc4107SMartin Schwidefsky j sie_exit 295d0fc4107SMartin Schwidefsky 296c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad6,.Lsie_fault) 297c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad4,.Lsie_fault) 298c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad2,.Lsie_fault) 299d0fc4107SMartin Schwidefsky EX_TABLE(sie_exit,.Lsie_fault) 300*6b33e68aSNico BoehrENDPROC(__sie64a) 301*6b33e68aSNico BoehrEXPORT_SYMBOL(__sie64a) 302711f5df7SAl ViroEXPORT_SYMBOL(sie_exit) 303d0fc4107SMartin Schwidefsky#endif 304d0fc4107SMartin Schwidefsky 3054bfc86ceSHeiko Carstens/* 3064bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and 3077b7735c5SChristian Borntraeger * are entered with interrupts disabled. 3084bfc86ceSHeiko Carstens */ 3094bfc86ceSHeiko Carstens 3104bfc86ceSHeiko CarstensENTRY(system_call) 31156e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 3124bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 313d768bd89SMartin Schwidefsky BPOFF 31456e62a73SSven Schnelle lghi %r14,0 3154bfc86ceSHeiko Carstens.Lsysc_per: 3163b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 31787d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 31856e62a73SSven Schnelle lg %r12,__LC_CURRENT 3194bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 3209365965dSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 32156e62a73SSven Schnelle stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 32256e62a73SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 323d3f46896SChristian Borntraeger # clear user controlled register to prevent speculative use 324d3f46896SChristian Borntraeger xgr %r0,%r0 32556e62a73SSven Schnelle xgr %r1,%r1 32656e62a73SSven Schnelle xgr %r4,%r4 32756e62a73SSven Schnelle xgr %r5,%r5 32856e62a73SSven Schnelle xgr %r6,%r6 32956e62a73SSven Schnelle xgr %r7,%r7 33056e62a73SSven Schnelle xgr %r8,%r8 33156e62a73SSven Schnelle xgr %r9,%r9 33256e62a73SSven Schnelle xgr %r10,%r10 33356e62a73SSven Schnelle xgr %r11,%r11 33456e62a73SSven Schnelle la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 335af9ad822SSven Schnelle mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC 3363b051e89SSven Schnelle MBEAR %r2 33756e62a73SSven Schnelle lgr %r3,%r14 33856e62a73SSven Schnelle brasl %r14,__do_syscall 33987d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 34056e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3416b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3423b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 34356e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3444bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 3453b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 34626a374aeSMartin SchwidefskyENDPROC(system_call) 3474bfc86ceSHeiko Carstens 3484bfc86ceSHeiko Carstens# 3494bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork 3504bfc86ceSHeiko Carstens# 3514bfc86ceSHeiko CarstensENTRY(ret_from_fork) 35256e62a73SSven Schnelle lgr %r3,%r11 35356e62a73SSven Schnelle brasl %r14,__ret_from_fork 35456e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 35556e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 35656e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3573b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 35856e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 35956e62a73SSven Schnelle stpt __LC_EXIT_TIMER 3603b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 36126a374aeSMartin SchwidefskyENDPROC(ret_from_fork) 36226a374aeSMartin Schwidefsky 3634bfc86ceSHeiko Carstens/* 3644bfc86ceSHeiko Carstens * Program check handler routine 3654bfc86ceSHeiko Carstens */ 3664bfc86ceSHeiko Carstens 3674bfc86ceSHeiko CarstensENTRY(pgm_check_handler) 36856e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 369d768bd89SMartin Schwidefsky BPOFF 3704bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 37156e62a73SSven Schnelle lg %r12,__LC_CURRENT 37256e62a73SSven Schnelle lghi %r10,0 3734bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_PGM_OLD_PSW 37487d59863SHeiko Carstens tmhh %r8,0x0001 # coming from user space? 37587d59863SHeiko Carstens jno .Lpgm_skip_asce 37687d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 37756e62a73SSven Schnelle j 3f # -> fault in user space 37887d59863SHeiko Carstens.Lpgm_skip_asce: 379d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 380*6b33e68aSNico Boehr # cleanup critical section for program checks in __sie64a 381b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f 382fbbdfca5SAlexander Gordeev SIEEXIT 38356e62a73SSven Schnelle lghi %r10,_PIF_GUEST_FAULT 384d0fc4107SMartin Schwidefsky#endif 3850b38b5e1SSven Schnelle1: tmhh %r8,0x4000 # PER bit set in old PSW ? 3860b38b5e1SSven Schnelle jnz 2f # -> enabled, can't be a double fault 3874bfc86ceSHeiko Carstens tm __LC_PGM_ILC+3,0x80 # check for per exception 3884bfc86ceSHeiko Carstens jnz .Lpgm_svcper # -> single stepped svc 3890b38b5e1SSven Schnelle2: CHECK_STACK __LC_SAVE_AREA_SYNC 3904bfc86ceSHeiko Carstens aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 39156e62a73SSven Schnelle # CHECK_VMAP_STACK branches to stack_overflow or 4f 39256e62a73SSven Schnelle CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f 39356e62a73SSven Schnelle3: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 3944bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 39556e62a73SSven Schnelle4: la %r11,STACK_FRAME_OVERHEAD(%r15) 39656e62a73SSven Schnelle stg %r10,__PT_FLAGS(%r11) 39756e62a73SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 3984bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 39956e62a73SSven Schnelle mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC 4003b051e89SSven Schnelle mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK 40156e62a73SSven Schnelle stmg %r8,%r9,__PT_PSW(%r11) 40256e62a73SSven Schnelle 4037041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4047041d281SMartin Schwidefsky xgr %r0,%r0 4057041d281SMartin Schwidefsky xgr %r1,%r1 4067041d281SMartin Schwidefsky xgr %r3,%r3 4077041d281SMartin Schwidefsky xgr %r4,%r4 4087041d281SMartin Schwidefsky xgr %r5,%r5 4097041d281SMartin Schwidefsky xgr %r6,%r6 4107041d281SMartin Schwidefsky xgr %r7,%r7 41156e62a73SSven Schnelle lgr %r2,%r11 41256e62a73SSven Schnelle brasl %r14,__do_pgm_check 41356e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user space? 41456e62a73SSven Schnelle jno .Lpgm_exit_kernel 41556e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 41656e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4170cd9b723SHeiko Carstens stpt __LC_EXIT_TIMER 41856e62a73SSven Schnelle.Lpgm_exit_kernel: 41956e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 4203b051e89SSven Schnelle LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15) 42156e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 4223b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 4234bfc86ceSHeiko Carstens 4244bfc86ceSHeiko Carstens# 4254bfc86ceSHeiko Carstens# single stepped system call 4264bfc86ceSHeiko Carstens# 4274bfc86ceSHeiko Carstens.Lpgm_svcper: 4284bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 4294bfc86ceSHeiko Carstens larl %r14,.Lsysc_per 4304bfc86ceSHeiko Carstens stg %r14,__LC_RETURN_PSW+8 43156e62a73SSven Schnelle lghi %r14,1 4323b051e89SSven Schnelle LBEAR __LC_PGM_LAST_BREAK 4333b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per 43426a374aeSMartin SchwidefskyENDPROC(pgm_check_handler) 4354bfc86ceSHeiko Carstens 4364bfc86ceSHeiko Carstens/* 43756e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts. 4384bfc86ceSHeiko Carstens */ 43956e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler 44056e62a73SSven SchnelleENTRY(\name) 44110bc15baSVasily Gorbik stckf __LC_INT_CLOCK 44256e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 4433b051e89SSven Schnelle STBEAR __LC_LAST_BREAK 444d768bd89SMartin Schwidefsky BPOFF 4454bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_ASYNC 446d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 44756e62a73SSven Schnelle lmg %r8,%r9,\lc_old_psw 448b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 449b0d31159SSven Schnelle jnz 1f 450b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 451b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f 452fbbdfca5SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 453fbbdfca5SAlexander Gordeev SIEEXIT 454b0d31159SSven Schnelle#endif 455b0d31159SSven Schnelle0: CHECK_STACK __LC_SAVE_AREA_ASYNC 456b0d31159SSven Schnelle aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 457b0d31159SSven Schnelle j 2f 458b0d31159SSven Schnelle1: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 459b0d31159SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 460b0d31159SSven Schnelle lg %r15,__LC_KERNEL_STACK 461b74e409eSVasily Gorbik2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 462b74e409eSVasily Gorbik la %r11,STACK_FRAME_OVERHEAD(%r15) 4634bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 4647041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4657041d281SMartin Schwidefsky xgr %r0,%r0 4667041d281SMartin Schwidefsky xgr %r1,%r1 4677041d281SMartin Schwidefsky xgr %r3,%r3 4687041d281SMartin Schwidefsky xgr %r4,%r4 4697041d281SMartin Schwidefsky xgr %r5,%r5 4707041d281SMartin Schwidefsky xgr %r6,%r6 4717041d281SMartin Schwidefsky xgr %r7,%r7 4727041d281SMartin Schwidefsky xgr %r10,%r10 473ca1f4d70SSven Schnelle xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 4744bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 4753b051e89SSven Schnelle MBEAR %r11 4764bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 47729b06ad7SHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 47856e62a73SSven Schnelle brasl %r14,\handler 4794bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 48056e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 48156e62a73SSven Schnelle jno 2f 48287d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4836b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4844bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 4853b051e89SSven Schnelle2: LBEAR __PT_LAST_BREAK(%r11) 4863b051e89SSven Schnelle lmg %r0,%r15,__PT_R0(%r11) 4873b051e89SSven Schnelle LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE 48856e62a73SSven SchnelleENDPROC(\name) 48956e62a73SSven Schnelle.endm 4904bfc86ceSHeiko Carstens 49156e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 49256e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 4934bfc86ceSHeiko Carstens 4944bfc86ceSHeiko Carstens/* 4950b0ed657SSven Schnelle * Load idle PSW. 4964bfc86ceSHeiko Carstens */ 4974bfc86ceSHeiko CarstensENTRY(psw_idle) 498a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 4994bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 50056e62a73SSven Schnelle larl %r1,psw_idle_exit 5014bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 50272d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 50372d38b19SMartin Schwidefsky llgf %r1,0(%r1) 50472d38b19SMartin Schwidefsky ltgr %r1,%r1 50572d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 50656e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 50772d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 508419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 509d768bd89SMartin Schwidefsky BPON 51010bc15baSVasily Gorbik stckf __CLOCK_IDLE_ENTER(%r2) 5114bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 5124bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 51356e62a73SSven Schnelle.globl psw_idle_exit 51456e62a73SSven Schnellepsw_idle_exit: 5156dd85fbbSMartin Schwidefsky BR_EX %r14 51626a374aeSMartin SchwidefskyENDPROC(psw_idle) 5174bfc86ceSHeiko Carstens 518b5510d9bSHendrik Brueckner/* 5194bfc86ceSHeiko Carstens * Machine check handler routines 5204bfc86ceSHeiko Carstens */ 5214bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 52210bc15baSVasily Gorbik stckf __LC_MCCK_CLOCK 523d768bd89SMartin Schwidefsky BPOFF 5243037a52fSMartin Schwidefsky la %r1,4095 # validate r1 5253037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 5263b051e89SSven Schnelle LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear 5273037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 528d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 5294bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 53083abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 5314bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 5323037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 5333037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5343037a52fSMartin Schwidefsky la %r14,4095 5353037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5363037a52fSMartin Schwidefsky ptlb 5375fa2ea07SAlexander Gordeev lghi %r14,__LC_CPU_TIMER_SAVE_AREA 5384bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 53983abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID 5404bfc86ceSHeiko Carstens jo 3f 54156e62a73SSven Schnelle la %r14,__LC_SYS_ENTER_TIMER 54256e62a73SSven Schnelle clc 0(8,%r14),__LC_EXIT_TIMER 5434bfc86ceSHeiko Carstens jl 1f 5444bfc86ceSHeiko Carstens la %r14,__LC_EXIT_TIMER 5454bfc86ceSHeiko Carstens1: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 5464bfc86ceSHeiko Carstens jl 2f 5474bfc86ceSHeiko Carstens la %r14,__LC_LAST_UPDATE_TIMER 5484bfc86ceSHeiko Carstens2: spt 0(%r14) 5494bfc86ceSHeiko Carstens mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 5503037a52fSMartin Schwidefsky3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 5513037a52fSMartin Schwidefsky jno .Lmcck_panic 5523037a52fSMartin Schwidefsky tmhh %r8,0x0001 # interrupting from user ? 553d35925b3SAlexander Gordeev jnz 6f 5543037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5553037a52fSMartin Schwidefsky jno .Lmcck_panic 556b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 557d35925b3SAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f 55829ccaa4bSAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f 55920232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 560d35925b3SAlexander Gordeev j 5f 561d35925b3SAlexander Gordeev4: CHKSTG .Lmcck_panic 562d35925b3SAlexander Gordeev5: larl %r14,.Lstosm_tmp 563d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 564d35925b3SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 565fbbdfca5SAlexander Gordeev SIEEXIT 566b61b1595SSven Schnelle j .Lmcck_stack 567e2c13d64SAlexander Gordeev#endif 568d35925b3SAlexander Gordeev6: CHKSTG .Lmcck_panic 569d35925b3SAlexander Gordeev larl %r14,.Lstosm_tmp 570d35925b3SAlexander Gordeev stosm 0(%r14),0x04 # turn dat on, keep irqs off 571d35925b3SAlexander Gordeev tmhh %r8,0x0001 # interrupting from user ? 572d35925b3SAlexander Gordeev jz .Lmcck_stack 573b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 574b61b1595SSven Schnelle.Lmcck_stack: 575b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 576b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 57726521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 578b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 579b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5804bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5814bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5827041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5837041d281SMartin Schwidefsky xgr %r0,%r0 5847041d281SMartin Schwidefsky xgr %r1,%r1 5857041d281SMartin Schwidefsky xgr %r3,%r3 5867041d281SMartin Schwidefsky xgr %r4,%r4 5877041d281SMartin Schwidefsky xgr %r5,%r5 5887041d281SMartin Schwidefsky xgr %r6,%r6 5897041d281SMartin Schwidefsky xgr %r7,%r7 5907041d281SMartin Schwidefsky xgr %r10,%r10 5914bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 5924bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 5934bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 5944bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5954bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 5964bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 5970b0ed657SSven Schnelle cghi %r2,0 5980b0ed657SSven Schnelle je .Lmcck_return 5994bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 6004bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 6014bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 6024bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 60339d62336SThomas Richter lgr %r2,%r11 6044bfc86ceSHeiko Carstens lgr %r15,%r1 6054bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 6064bfc86ceSHeiko Carstens.Lmcck_return: 60787d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 6084bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 6094bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 6104bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 6114bfc86ceSHeiko Carstens jno 0f 6126b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 6134bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 614fad442d3SHeiko Carstens0: ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193 6153b051e89SSven Schnelle LBEAR 0(%r12) 6163b051e89SSven Schnelle lmg %r11,%r15,__PT_R11(%r11) 6173b051e89SSven Schnelle LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE 6184bfc86ceSHeiko Carstens 6194bfc86ceSHeiko Carstens.Lmcck_panic: 6207f6dc8d4SAlexander Gordeev /* 6217f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 6227f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 6237f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 6247f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 6257f6dc8d4SAlexander Gordeev */ 6267f6dc8d4SAlexander Gordeev lhi %r5,0 6277f6dc8d4SAlexander Gordeev lhi %r6,1 6287f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 6297f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 6307f6dc8d4SAlexander Gordeev jnz 4f 6317f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 6327f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 6337f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 6347f6dc8d4SAlexander Gordeev nilh %r4,0 6357f6dc8d4SAlexander Gordeev lhi %r0,1 6367f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 6377f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 6387f6dc8d4SAlexander Gordeev0: cr %r3,%r4 6397f6dc8d4SAlexander Gordeev je 2f 6407f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 6417f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 6427f6dc8d4SAlexander Gordeev2: ahi %r3,1 6437f6dc8d4SAlexander Gordeev brct %r0,0b 6447f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 6457f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 6467f6dc8d4SAlexander Gordeev4: j 4b 64726a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6484bfc86ceSHeiko Carstens 6494bfc86ceSHeiko CarstensENTRY(restart_int_handler) 650fad442d3SHeiko Carstens ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40 651e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 652915fea04SAlexander Gordeev TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4 653915fea04SAlexander Gordeev jz 0f 654915fea04SAlexander Gordeev la %r15,4095 655915fea04SAlexander Gordeev lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15) 656915fea04SAlexander Gordeev0: larl %r15,.Lstosm_tmp 657915fea04SAlexander Gordeev stosm 0(%r15),0x04 # turn dat on, keep irqs off 6584bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 659ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 660ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 661ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 662ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6634bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6644bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6654bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 666915fea04SAlexander Gordeev lgf %r3,__LC_RESTART_SOURCE 6674bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6684bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6694bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6704bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6714bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6724bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6734bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6744bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6754bfc86ceSHeiko Carstens brc 2,2b 6764bfc86ceSHeiko Carstens3: j 3b 67726a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6784bfc86ceSHeiko Carstens 6794bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6804bfc86ceSHeiko Carstens 681ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6824bfc86ceSHeiko Carstens/* 6834bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6844bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6854bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6864bfc86ceSHeiko Carstens */ 68726a374aeSMartin SchwidefskyENTRY(stack_overflow) 688ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6894bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6904bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6914bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6924bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6934bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 6944bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6954bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6964bfc86ceSHeiko Carstens jg kernel_stack_overflow 69726a374aeSMartin SchwidefskyENDPROC(stack_overflow) 6984bfc86ceSHeiko Carstens#endif 6994bfc86ceSHeiko Carstens 7007f6dc8d4SAlexander Gordeev .section .data, "aw" 7017f6dc8d4SAlexander Gordeev .align 4 7027f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 7037f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 704d35925b3SAlexander Gordeev.Lstosm_tmp: .byte 0 7054bfc86ceSHeiko Carstens .section .rodata, "a" 706ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 7074bfc86ceSHeiko Carstens .globl sys_call_table 7084bfc86ceSHeiko Carstenssys_call_table: 7094381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7104bfc86ceSHeiko Carstens#undef SYSCALL 7114bfc86ceSHeiko Carstens 7124bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 7134bfc86ceSHeiko Carstens 714ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 7154bfc86ceSHeiko Carstens .globl sys_call_table_emu 7164bfc86ceSHeiko Carstenssys_call_table_emu: 7174381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7184bfc86ceSHeiko Carstens#undef SYSCALL 7194bfc86ceSHeiko Carstens#endif 720