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> 173037a52fSMartin Schwidefsky#include <asm/ctl_reg.h> 18dc24b7b4SHendrik Brueckner#include <asm/dwarf.h> 194bfc86ceSHeiko Carstens#include <asm/errno.h> 204bfc86ceSHeiko Carstens#include <asm/ptrace.h> 214bfc86ceSHeiko Carstens#include <asm/thread_info.h> 224bfc86ceSHeiko Carstens#include <asm/asm-offsets.h> 234bfc86ceSHeiko Carstens#include <asm/unistd.h> 244bfc86ceSHeiko Carstens#include <asm/page.h> 254bfc86ceSHeiko Carstens#include <asm/sigp.h> 264bfc86ceSHeiko Carstens#include <asm/irq.h> 279977e886SHendrik Brueckner#include <asm/vx-insn.h> 2883abeffbSHendrik Brueckner#include <asm/setup.h> 2983abeffbSHendrik Brueckner#include <asm/nmi.h> 30711f5df7SAl Viro#include <asm/export.h> 316dd85fbbSMartin Schwidefsky#include <asm/nospec-insn.h> 324bfc86ceSHeiko Carstens 334bfc86ceSHeiko Carstens__PT_R0 = __PT_GPRS 344bfc86ceSHeiko Carstens__PT_R1 = __PT_GPRS + 8 354bfc86ceSHeiko Carstens__PT_R2 = __PT_GPRS + 16 364bfc86ceSHeiko Carstens__PT_R3 = __PT_GPRS + 24 374bfc86ceSHeiko Carstens__PT_R4 = __PT_GPRS + 32 384bfc86ceSHeiko Carstens__PT_R5 = __PT_GPRS + 40 394bfc86ceSHeiko Carstens__PT_R6 = __PT_GPRS + 48 404bfc86ceSHeiko Carstens__PT_R7 = __PT_GPRS + 56 414bfc86ceSHeiko Carstens__PT_R8 = __PT_GPRS + 64 424bfc86ceSHeiko Carstens__PT_R9 = __PT_GPRS + 72 434bfc86ceSHeiko Carstens__PT_R10 = __PT_GPRS + 80 444bfc86ceSHeiko Carstens__PT_R11 = __PT_GPRS + 88 454bfc86ceSHeiko Carstens__PT_R12 = __PT_GPRS + 96 464bfc86ceSHeiko Carstens__PT_R13 = __PT_GPRS + 104 474bfc86ceSHeiko Carstens__PT_R14 = __PT_GPRS + 112 484bfc86ceSHeiko Carstens__PT_R15 = __PT_GPRS + 120 494bfc86ceSHeiko Carstens 503a890380SHeiko CarstensSTACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER 514bfc86ceSHeiko CarstensSTACK_SIZE = 1 << STACK_SHIFT 524bfc86ceSHeiko CarstensSTACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE 534bfc86ceSHeiko Carstens 54e5b98199SMartin Schwidefsky_LPP_OFFSET = __LC_LPP 55e5b98199SMartin Schwidefsky 56ce3dc447SMartin Schwidefsky .macro CHECK_STACK savearea 574bfc86ceSHeiko Carstens#ifdef CONFIG_CHECK_STACK 58ce3dc447SMartin Schwidefsky tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 594bfc86ceSHeiko Carstens lghi %r14,\savearea 604bfc86ceSHeiko Carstens jz stack_overflow 614bfc86ceSHeiko Carstens#endif 624bfc86ceSHeiko Carstens .endm 634bfc86ceSHeiko Carstens 64ce3dc447SMartin Schwidefsky .macro CHECK_VMAP_STACK savearea,oklabel 65ce3dc447SMartin Schwidefsky#ifdef CONFIG_VMAP_STACK 66ce3dc447SMartin Schwidefsky lgr %r14,%r15 67ce3dc447SMartin Schwidefsky nill %r14,0x10000 - STACK_SIZE 68ce3dc447SMartin Schwidefsky oill %r14,STACK_INIT 69ce3dc447SMartin Schwidefsky clg %r14,__LC_KERNEL_STACK 70ce3dc447SMartin Schwidefsky je \oklabel 71ce3dc447SMartin Schwidefsky clg %r14,__LC_ASYNC_STACK 72ce3dc447SMartin Schwidefsky je \oklabel 73b61b1595SSven Schnelle clg %r14,__LC_MCCK_STACK 74b61b1595SSven Schnelle je \oklabel 75ce3dc447SMartin Schwidefsky clg %r14,__LC_NODAT_STACK 76ce3dc447SMartin Schwidefsky je \oklabel 77ce3dc447SMartin Schwidefsky clg %r14,__LC_RESTART_STACK 78ce3dc447SMartin Schwidefsky je \oklabel 79ce3dc447SMartin Schwidefsky lghi %r14,\savearea 80ce3dc447SMartin Schwidefsky j stack_overflow 81ce3dc447SMartin Schwidefsky#else 82ce3dc447SMartin Schwidefsky j \oklabel 83ce3dc447SMartin Schwidefsky#endif 84ce3dc447SMartin Schwidefsky .endm 85ce3dc447SMartin Schwidefsky 864bfc86ceSHeiko Carstens .macro STCK savearea 8778f65709SHeiko Carstens ALTERNATIVE ".insn s,0xb2050000,\savearea", \ 8878f65709SHeiko Carstens ".insn s,0xb27c0000,\savearea", 25 894bfc86ceSHeiko Carstens .endm 904bfc86ceSHeiko Carstens 9183abeffbSHendrik Brueckner /* 9283abeffbSHendrik Brueckner * The TSTMSK macro generates a test-under-mask instruction by 9383abeffbSHendrik Brueckner * calculating the memory offset for the specified mask value. 9483abeffbSHendrik Brueckner * Mask value can be any constant. The macro shifts the mask 9583abeffbSHendrik Brueckner * value to calculate the memory offset for the test-under-mask 9683abeffbSHendrik Brueckner * instruction. 9783abeffbSHendrik Brueckner */ 9883abeffbSHendrik Brueckner .macro TSTMSK addr, mask, size=8, bytepos=0 9983abeffbSHendrik Brueckner .if (\bytepos < \size) && (\mask >> 8) 10083abeffbSHendrik Brueckner .if (\mask & 0xff) 10183abeffbSHendrik Brueckner .error "Mask exceeds byte boundary" 10283abeffbSHendrik Brueckner .endif 10383abeffbSHendrik Brueckner TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)" 10483abeffbSHendrik Brueckner .exitm 10583abeffbSHendrik Brueckner .endif 10683abeffbSHendrik Brueckner .ifeq \mask 10783abeffbSHendrik Brueckner .error "Mask must not be zero" 10883abeffbSHendrik Brueckner .endif 10983abeffbSHendrik Brueckner off = \size - \bytepos - 1 11083abeffbSHendrik Brueckner tm off+\addr, \mask 11183abeffbSHendrik Brueckner .endm 11283abeffbSHendrik Brueckner 113d768bd89SMartin Schwidefsky .macro BPOFF 114b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8c000", 82 115d768bd89SMartin Schwidefsky .endm 116d768bd89SMartin Schwidefsky 117d768bd89SMartin Schwidefsky .macro BPON 118b058661aSMartin Schwidefsky ALTERNATIVE "", ".long 0xb2e8d000", 82 119d768bd89SMartin Schwidefsky .endm 120d768bd89SMartin Schwidefsky 1216b73044bSMartin Schwidefsky .macro BPENTER tif_ptr,tif_mask 122b058661aSMartin Schwidefsky ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .long 0xb2e8d000", \ 123b058661aSMartin Schwidefsky "", 82 1246b73044bSMartin Schwidefsky .endm 1256b73044bSMartin Schwidefsky 1266b73044bSMartin Schwidefsky .macro BPEXIT tif_ptr,tif_mask 1276b73044bSMartin Schwidefsky TSTMSK \tif_ptr,\tif_mask 128b058661aSMartin Schwidefsky ALTERNATIVE "jz .+8; .long 0xb2e8c000", \ 129b058661aSMartin Schwidefsky "jnz .+8; .long 0xb2e8d000", 82 1306b73044bSMartin Schwidefsky .endm 1316b73044bSMartin Schwidefsky 132b5415c8fSAlexander Gordeev#if IS_ENABLED(CONFIG_KVM) 133b5415c8fSAlexander Gordeev /* 134b5415c8fSAlexander Gordeev * The OUTSIDE macro jumps to the provided label in case the value 135b5415c8fSAlexander Gordeev * in the provided register is outside of the provided range. The 136b5415c8fSAlexander Gordeev * macro is useful for checking whether a PSW stored in a register 137b5415c8fSAlexander Gordeev * pair points inside or outside of a block of instructions. 138b5415c8fSAlexander Gordeev * @reg: register to check 139b5415c8fSAlexander Gordeev * @start: start of the range 140b5415c8fSAlexander Gordeev * @end: end of the range 141b5415c8fSAlexander Gordeev * @outside_label: jump here if @reg is outside of [@start..@end) 142b5415c8fSAlexander Gordeev */ 143b5415c8fSAlexander Gordeev .macro OUTSIDE reg,start,end,outside_label 144b5415c8fSAlexander Gordeev lgr %r14,\reg 145b5415c8fSAlexander Gordeev larl %r13,\start 146b5415c8fSAlexander Gordeev slgr %r14,%r13 147b5415c8fSAlexander Gordeev lghi %r13,\end - \start 148b5415c8fSAlexander Gordeev clgr %r14,%r13 149b5415c8fSAlexander Gordeev jhe \outside_label 150b5415c8fSAlexander Gordeev .endm 151fbbdfca5SAlexander Gordeev 152fbbdfca5SAlexander Gordeev .macro SIEEXIT 153fbbdfca5SAlexander Gordeev lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer 154fbbdfca5SAlexander Gordeev ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 155fbbdfca5SAlexander Gordeev lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 156fbbdfca5SAlexander Gordeev larl %r9,sie_exit # skip forward to sie_exit 157fbbdfca5SAlexander Gordeev .endm 158b5415c8fSAlexander Gordeev#endif 159b5415c8fSAlexander Gordeev 1606dd85fbbSMartin Schwidefsky GEN_BR_THUNK %r14 16133ea0487SSven Schnelle GEN_BR_THUNK %r14,%r13 162f19fbd5eSMartin Schwidefsky 1634bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 16446210c44SHeiko Carstens.Ldummy: 16546210c44SHeiko Carstens /* 16656e62a73SSven Schnelle * This nop exists only in order to avoid that __bpon starts at 16746210c44SHeiko Carstens * the beginning of the kprobes text section. In that case we would 16846210c44SHeiko Carstens * have several symbols at the same address. E.g. objdump would take 16946210c44SHeiko Carstens * an arbitrary symbol name when disassembling this code. 17056e62a73SSven Schnelle * With the added nop in between the __bpon symbol is unique 17146210c44SHeiko Carstens * again. 17246210c44SHeiko Carstens */ 17346210c44SHeiko Carstens nop 0 1744bfc86ceSHeiko Carstens 175d768bd89SMartin SchwidefskyENTRY(__bpon) 176d768bd89SMartin Schwidefsky .globl __bpon 177d768bd89SMartin Schwidefsky BPON 1786dd85fbbSMartin Schwidefsky BR_EX %r14 17926a374aeSMartin SchwidefskyENDPROC(__bpon) 180d768bd89SMartin Schwidefsky 1814bfc86ceSHeiko Carstens/* 1824bfc86ceSHeiko Carstens * Scheduler resume function, called by switch_to 1834bfc86ceSHeiko Carstens * gpr2 = (task_struct *) prev 1844bfc86ceSHeiko Carstens * gpr3 = (task_struct *) next 1854bfc86ceSHeiko Carstens * Returns: 1864bfc86ceSHeiko Carstens * gpr2 = prev 1874bfc86ceSHeiko Carstens */ 1884bfc86ceSHeiko CarstensENTRY(__switch_to) 1894bfc86ceSHeiko Carstens stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 1903241d3ebSHeiko Carstens lghi %r4,__TASK_stack 1913241d3ebSHeiko Carstens lghi %r1,__TASK_thread 1929fed920eSVasily Gorbik llill %r5,STACK_INIT 1933241d3ebSHeiko Carstens stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev 1949fed920eSVasily Gorbik lg %r15,0(%r4,%r3) # start of kernel stack of next 1959fed920eSVasily Gorbik agr %r15,%r5 # end of kernel stack of next 1964bfc86ceSHeiko Carstens stg %r3,__LC_CURRENT # store task struct of next 1974bfc86ceSHeiko Carstens stg %r15,__LC_KERNEL_STACK # store end of kernel stack 1983241d3ebSHeiko Carstens lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next 1993241d3ebSHeiko Carstens aghi %r3,__TASK_pid 2003241d3ebSHeiko Carstens mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 2014bfc86ceSHeiko Carstens lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 202e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 2036dd85fbbSMartin Schwidefsky BR_EX %r14 20426a374aeSMartin SchwidefskyENDPROC(__switch_to) 2054bfc86ceSHeiko Carstens 206d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 207d0fc4107SMartin Schwidefsky/* 208d0fc4107SMartin Schwidefsky * sie64a calling convention: 209d0fc4107SMartin Schwidefsky * %r2 pointer to sie control block 210d0fc4107SMartin Schwidefsky * %r3 guest register save area 211d0fc4107SMartin Schwidefsky */ 212d0fc4107SMartin SchwidefskyENTRY(sie64a) 213d0fc4107SMartin Schwidefsky stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 2146b73044bSMartin Schwidefsky lg %r12,__LC_CURRENT 21592fa7a13SMartin Schwidefsky stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer 21692fa7a13SMartin Schwidefsky stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area 21792fa7a13SMartin Schwidefsky xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0 21892fa7a13SMartin Schwidefsky mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags 219d0fc4107SMartin Schwidefsky lmg %r0,%r13,0(%r3) # load guest gprs 0-13 220d0fc4107SMartin Schwidefsky lg %r14,__LC_GMAP # get gmap pointer 221d0fc4107SMartin Schwidefsky ltgr %r14,%r14 222d0fc4107SMartin Schwidefsky jz .Lsie_gmap 223d0fc4107SMartin Schwidefsky lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 224d0fc4107SMartin Schwidefsky.Lsie_gmap: 22592fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer 226d0fc4107SMartin Schwidefsky oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 227d0fc4107SMartin Schwidefsky tm __SIE_PROG20+3(%r14),3 # last exit... 228d0fc4107SMartin Schwidefsky jnz .Lsie_skip 22983abeffbSHendrik Brueckner TSTMSK __LC_CPU_FLAGS,_CIF_FPU 230d0fc4107SMartin Schwidefsky jo .Lsie_skip # exit if fp/vx regs changed 23192fa7a13SMartin Schwidefsky BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 232c929500dSQingFeng Hao.Lsie_entry: 233d0fc4107SMartin Schwidefsky sie 0(%r14) 234d768bd89SMartin Schwidefsky BPOFF 23592fa7a13SMartin Schwidefsky BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 236d0fc4107SMartin Schwidefsky.Lsie_skip: 237d0fc4107SMartin Schwidefsky ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 23887d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce 239d0fc4107SMartin Schwidefsky.Lsie_done: 240d0fc4107SMartin Schwidefsky# some program checks are suppressing. C code (e.g. do_protection_exception) 241c0e7bb38SChristian Borntraeger# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There 242c0e7bb38SChristian Borntraeger# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. 243c0e7bb38SChristian Borntraeger# Other instructions between sie64a and .Lsie_done should not cause program 244c0e7bb38SChristian Borntraeger# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. 245c0e7bb38SChristian Borntraeger.Lrewind_pad6: 246c0e7bb38SChristian Borntraeger nopr 7 247c0e7bb38SChristian Borntraeger.Lrewind_pad4: 248c0e7bb38SChristian Borntraeger nopr 7 249c0e7bb38SChristian Borntraeger.Lrewind_pad2: 250c0e7bb38SChristian Borntraeger nopr 7 251d0fc4107SMartin Schwidefsky .globl sie_exit 252d0fc4107SMartin Schwidefskysie_exit: 25392fa7a13SMartin Schwidefsky lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area 254d0fc4107SMartin Schwidefsky stmg %r0,%r13,0(%r14) # save guest gprs 0-13 2557041d281SMartin Schwidefsky xgr %r0,%r0 # clear guest registers to 2567041d281SMartin Schwidefsky xgr %r1,%r1 # prevent speculative use 2577041d281SMartin Schwidefsky xgr %r3,%r3 2587041d281SMartin Schwidefsky xgr %r4,%r4 2597041d281SMartin Schwidefsky xgr %r5,%r5 260d0fc4107SMartin Schwidefsky lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 26192fa7a13SMartin Schwidefsky lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 2626dd85fbbSMartin Schwidefsky BR_EX %r14 263d0fc4107SMartin Schwidefsky.Lsie_fault: 264d0fc4107SMartin Schwidefsky lghi %r14,-EFAULT 26592fa7a13SMartin Schwidefsky stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 266d0fc4107SMartin Schwidefsky j sie_exit 267d0fc4107SMartin Schwidefsky 268c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad6,.Lsie_fault) 269c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad4,.Lsie_fault) 270c0e7bb38SChristian Borntraeger EX_TABLE(.Lrewind_pad2,.Lsie_fault) 271d0fc4107SMartin Schwidefsky EX_TABLE(sie_exit,.Lsie_fault) 27226a374aeSMartin SchwidefskyENDPROC(sie64a) 273711f5df7SAl ViroEXPORT_SYMBOL(sie64a) 274711f5df7SAl ViroEXPORT_SYMBOL(sie_exit) 275d0fc4107SMartin Schwidefsky#endif 276d0fc4107SMartin Schwidefsky 2774bfc86ceSHeiko Carstens/* 2784bfc86ceSHeiko Carstens * SVC interrupt handler routine. System calls are synchronous events and 2797b7735c5SChristian Borntraeger * are entered with interrupts disabled. 2804bfc86ceSHeiko Carstens */ 2814bfc86ceSHeiko Carstens 2824bfc86ceSHeiko CarstensENTRY(system_call) 28356e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 2844bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 285d768bd89SMartin Schwidefsky BPOFF 28656e62a73SSven Schnelle lghi %r14,0 2874bfc86ceSHeiko Carstens.Lsysc_per: 28887d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 28956e62a73SSven Schnelle lg %r12,__LC_CURRENT 2904bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 2919365965dSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 29256e62a73SSven Schnelle stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 29356e62a73SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 294d3f46896SChristian Borntraeger # clear user controlled register to prevent speculative use 295d3f46896SChristian Borntraeger xgr %r0,%r0 29656e62a73SSven Schnelle xgr %r1,%r1 29756e62a73SSven Schnelle xgr %r4,%r4 29856e62a73SSven Schnelle xgr %r5,%r5 29956e62a73SSven Schnelle xgr %r6,%r6 30056e62a73SSven Schnelle xgr %r7,%r7 30156e62a73SSven Schnelle xgr %r8,%r8 30256e62a73SSven Schnelle xgr %r9,%r9 30356e62a73SSven Schnelle xgr %r10,%r10 30456e62a73SSven Schnelle xgr %r11,%r11 30556e62a73SSven Schnelle la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 306af9ad822SSven Schnelle mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC 30756e62a73SSven Schnelle lgr %r3,%r14 30856e62a73SSven Schnelle brasl %r14,__do_syscall 30987d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 31056e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 3116b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 31256e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3134bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 3140b0ed657SSven Schnelle b __LC_RETURN_LPSWE 31526a374aeSMartin SchwidefskyENDPROC(system_call) 3164bfc86ceSHeiko Carstens 3174bfc86ceSHeiko Carstens# 3184bfc86ceSHeiko Carstens# a new process exits the kernel with ret_from_fork 3194bfc86ceSHeiko Carstens# 3204bfc86ceSHeiko CarstensENTRY(ret_from_fork) 32156e62a73SSven Schnelle lgr %r3,%r11 32256e62a73SSven Schnelle brasl %r14,__ret_from_fork 32356e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 32456e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 32556e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 32656e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 32756e62a73SSven Schnelle stpt __LC_EXIT_TIMER 32856e62a73SSven Schnelle b __LC_RETURN_LPSWE 32926a374aeSMartin SchwidefskyENDPROC(ret_from_fork) 33026a374aeSMartin Schwidefsky 3314bfc86ceSHeiko Carstens/* 3324bfc86ceSHeiko Carstens * Program check handler routine 3334bfc86ceSHeiko Carstens */ 3344bfc86ceSHeiko Carstens 3354bfc86ceSHeiko CarstensENTRY(pgm_check_handler) 33656e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 337d768bd89SMartin Schwidefsky BPOFF 3384bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_SYNC 33956e62a73SSven Schnelle lg %r12,__LC_CURRENT 34056e62a73SSven Schnelle lghi %r10,0 3414bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_PGM_OLD_PSW 34287d59863SHeiko Carstens tmhh %r8,0x0001 # coming from user space? 34387d59863SHeiko Carstens jno .Lpgm_skip_asce 34487d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 34556e62a73SSven Schnelle j 3f # -> fault in user space 34687d59863SHeiko Carstens.Lpgm_skip_asce: 347d0fc4107SMartin Schwidefsky#if IS_ENABLED(CONFIG_KVM) 3480a5e2ec2SMartin Schwidefsky # cleanup critical section for program checks in sie64a 349b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f 350fbbdfca5SAlexander Gordeev SIEEXIT 35156e62a73SSven Schnelle lghi %r10,_PIF_GUEST_FAULT 352d0fc4107SMartin Schwidefsky#endif 3530b38b5e1SSven Schnelle1: tmhh %r8,0x4000 # PER bit set in old PSW ? 3540b38b5e1SSven Schnelle jnz 2f # -> enabled, can't be a double fault 3554bfc86ceSHeiko Carstens tm __LC_PGM_ILC+3,0x80 # check for per exception 3564bfc86ceSHeiko Carstens jnz .Lpgm_svcper # -> single stepped svc 3570b38b5e1SSven Schnelle2: CHECK_STACK __LC_SAVE_AREA_SYNC 3584bfc86ceSHeiko Carstens aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 35956e62a73SSven Schnelle # CHECK_VMAP_STACK branches to stack_overflow or 4f 36056e62a73SSven Schnelle CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f 36156e62a73SSven Schnelle3: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 3624bfc86ceSHeiko Carstens lg %r15,__LC_KERNEL_STACK 36356e62a73SSven Schnelle4: la %r11,STACK_FRAME_OVERHEAD(%r15) 36456e62a73SSven Schnelle stg %r10,__PT_FLAGS(%r11) 36556e62a73SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 3664bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 36756e62a73SSven Schnelle mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC 36856e62a73SSven Schnelle stmg %r8,%r9,__PT_PSW(%r11) 36956e62a73SSven Schnelle 3707041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 3717041d281SMartin Schwidefsky xgr %r0,%r0 3727041d281SMartin Schwidefsky xgr %r1,%r1 3737041d281SMartin Schwidefsky xgr %r3,%r3 3747041d281SMartin Schwidefsky xgr %r4,%r4 3757041d281SMartin Schwidefsky xgr %r5,%r5 3767041d281SMartin Schwidefsky xgr %r6,%r6 3777041d281SMartin Schwidefsky xgr %r7,%r7 37856e62a73SSven Schnelle lgr %r2,%r11 37956e62a73SSven Schnelle brasl %r14,__do_pgm_check 38056e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user space? 38156e62a73SSven Schnelle jno .Lpgm_exit_kernel 38256e62a73SSven Schnelle lctlg %c1,%c1,__LC_USER_ASCE 38356e62a73SSven Schnelle BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 3840cd9b723SHeiko Carstens stpt __LC_EXIT_TIMER 38556e62a73SSven Schnelle.Lpgm_exit_kernel: 38656e62a73SSven Schnelle mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15) 38756e62a73SSven Schnelle lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 3880cd9b723SHeiko Carstens b __LC_RETURN_LPSWE 3894bfc86ceSHeiko Carstens 3904bfc86ceSHeiko Carstens# 3914bfc86ceSHeiko Carstens# single stepped system call 3924bfc86ceSHeiko Carstens# 3934bfc86ceSHeiko Carstens.Lpgm_svcper: 3944bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 3954bfc86ceSHeiko Carstens larl %r14,.Lsysc_per 3964bfc86ceSHeiko Carstens stg %r14,__LC_RETURN_PSW+8 39756e62a73SSven Schnelle lghi %r14,1 3980b0ed657SSven Schnelle lpswe __LC_RETURN_PSW # branch to .Lsysc_per 39926a374aeSMartin SchwidefskyENDPROC(pgm_check_handler) 4004bfc86ceSHeiko Carstens 4014bfc86ceSHeiko Carstens/* 40256e62a73SSven Schnelle * Interrupt handler macro used for external and IO interrupts. 4034bfc86ceSHeiko Carstens */ 40456e62a73SSven Schnelle.macro INT_HANDLER name,lc_old_psw,handler 40556e62a73SSven SchnelleENTRY(\name) 4064bfc86ceSHeiko Carstens STCK __LC_INT_CLOCK 40756e62a73SSven Schnelle stpt __LC_SYS_ENTER_TIMER 408d768bd89SMartin Schwidefsky BPOFF 4094bfc86ceSHeiko Carstens stmg %r8,%r15,__LC_SAVE_AREA_ASYNC 410d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 41156e62a73SSven Schnelle lmg %r8,%r9,\lc_old_psw 412b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 413b0d31159SSven Schnelle jnz 1f 414b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 415b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f 416fbbdfca5SAlexander Gordeev BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 417fbbdfca5SAlexander Gordeev SIEEXIT 418b0d31159SSven Schnelle#endif 419b0d31159SSven Schnelle0: CHECK_STACK __LC_SAVE_AREA_ASYNC 420b0d31159SSven Schnelle aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 421b0d31159SSven Schnelle j 2f 422b0d31159SSven Schnelle1: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 423b0d31159SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 424b0d31159SSven Schnelle lg %r15,__LC_KERNEL_STACK 425b74e409eSVasily Gorbik2: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 426b74e409eSVasily Gorbik la %r11,STACK_FRAME_OVERHEAD(%r15) 4274bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 4287041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 4297041d281SMartin Schwidefsky xgr %r0,%r0 4307041d281SMartin Schwidefsky xgr %r1,%r1 4317041d281SMartin Schwidefsky xgr %r3,%r3 4327041d281SMartin Schwidefsky xgr %r4,%r4 4337041d281SMartin Schwidefsky xgr %r5,%r5 4347041d281SMartin Schwidefsky xgr %r6,%r6 4357041d281SMartin Schwidefsky xgr %r7,%r7 4367041d281SMartin Schwidefsky xgr %r10,%r10 437ca1f4d70SSven Schnelle xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 4384bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 4394bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 44056e62a73SSven Schnelle tm %r8,0x0001 # coming from user space? 44156e62a73SSven Schnelle jno 1f 44287d59863SHeiko Carstens lctlg %c1,%c1,__LC_KERNEL_ASCE 44356e62a73SSven Schnelle1: lgr %r2,%r11 # pass pointer to pt_regs 44456e62a73SSven Schnelle brasl %r14,\handler 4454bfc86ceSHeiko Carstens mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 44656e62a73SSven Schnelle tmhh %r8,0x0001 # returning to user ? 44756e62a73SSven Schnelle jno 2f 44887d59863SHeiko Carstens lctlg %c1,%c1,__LC_USER_ASCE 4496b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 4504bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 45156e62a73SSven Schnelle2: lmg %r0,%r15,__PT_R0(%r11) 4520b0ed657SSven Schnelle b __LC_RETURN_LPSWE 45356e62a73SSven SchnelleENDPROC(\name) 45456e62a73SSven Schnelle.endm 4554bfc86ceSHeiko Carstens 45656e62a73SSven SchnelleINT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq 45756e62a73SSven SchnelleINT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq 4584bfc86ceSHeiko Carstens 4594bfc86ceSHeiko Carstens/* 4600b0ed657SSven Schnelle * Load idle PSW. 4614bfc86ceSHeiko Carstens */ 4624bfc86ceSHeiko CarstensENTRY(psw_idle) 463a994eddbSVasily Gorbik stg %r14,(__SF_GPRS+8*8)(%r15) 4644bfc86ceSHeiko Carstens stg %r3,__SF_EMPTY(%r15) 46556e62a73SSven Schnelle larl %r1,psw_idle_exit 4664bfc86ceSHeiko Carstens stg %r1,__SF_EMPTY+8(%r15) 46772d38b19SMartin Schwidefsky larl %r1,smp_cpu_mtid 46872d38b19SMartin Schwidefsky llgf %r1,0(%r1) 46972d38b19SMartin Schwidefsky ltgr %r1,%r1 47072d38b19SMartin Schwidefsky jz .Lpsw_idle_stcctm 47156e62a73SSven Schnelle .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2) 47272d38b19SMartin Schwidefsky.Lpsw_idle_stcctm: 473419123f9SMartin Schwidefsky oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT 474d768bd89SMartin Schwidefsky BPON 4754bfc86ceSHeiko Carstens STCK __CLOCK_IDLE_ENTER(%r2) 4764bfc86ceSHeiko Carstens stpt __TIMER_IDLE_ENTER(%r2) 4774bfc86ceSHeiko Carstens lpswe __SF_EMPTY(%r15) 47856e62a73SSven Schnelle.globl psw_idle_exit 47956e62a73SSven Schnellepsw_idle_exit: 4806dd85fbbSMartin Schwidefsky BR_EX %r14 48126a374aeSMartin SchwidefskyENDPROC(psw_idle) 4824bfc86ceSHeiko Carstens 483b5510d9bSHendrik Brueckner/* 4844bfc86ceSHeiko Carstens * Machine check handler routines 4854bfc86ceSHeiko Carstens */ 4864bfc86ceSHeiko CarstensENTRY(mcck_int_handler) 4874bfc86ceSHeiko Carstens STCK __LC_MCCK_CLOCK 488d768bd89SMartin Schwidefsky BPOFF 4893037a52fSMartin Schwidefsky la %r1,4095 # validate r1 4903037a52fSMartin Schwidefsky spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer 4913037a52fSMartin Schwidefsky sckc __LC_CLOCK_COMPARATOR # validate comparator 4923037a52fSMartin Schwidefsky lam %a0,%a15,__LC_AREGS_SAVE_AREA-4095(%r1) # validate acrs 4933037a52fSMartin Schwidefsky lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs 494d5c352cdSHeiko Carstens lg %r12,__LC_CURRENT 4954bfc86ceSHeiko Carstens lmg %r8,%r9,__LC_MCK_OLD_PSW 49683abeffbSHendrik Brueckner TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE 4974bfc86ceSHeiko Carstens jo .Lmcck_panic # yes -> rest of mcck code invalid 4983037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID 4993037a52fSMartin Schwidefsky jno .Lmcck_panic # control registers invalid -> panic 5003037a52fSMartin Schwidefsky la %r14,4095 5013037a52fSMartin Schwidefsky lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs 5023037a52fSMartin Schwidefsky ptlb 5032a2d7befSVasily Gorbik lg %r11,__LC_MCESAD-4095(%r14) # extended machine check save area 5043037a52fSMartin Schwidefsky nill %r11,0xfc00 # MCESA_ORIGIN_MASK 5053037a52fSMartin Schwidefsky TSTMSK __LC_CREGS_SAVE_AREA+16-4095(%r14),CR2_GUARDED_STORAGE 5063037a52fSMartin Schwidefsky jno 0f 5073037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_GS_VALID 5083037a52fSMartin Schwidefsky jno 0f 5093037a52fSMartin Schwidefsky .insn rxy,0xe3000000004d,0,__MCESA_GS_SAVE_AREA(%r11) # LGSC 5103037a52fSMartin Schwidefsky0: l %r14,__LC_FP_CREG_SAVE_AREA-4095(%r14) 5113037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_FC_VALID 5123037a52fSMartin Schwidefsky jo 0f 5133037a52fSMartin Schwidefsky sr %r14,%r14 5143037a52fSMartin Schwidefsky0: sfpc %r14 5153037a52fSMartin Schwidefsky TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX 5163037a52fSMartin Schwidefsky jo 0f 5173037a52fSMartin Schwidefsky lghi %r14,__LC_FPREGS_SAVE_AREA 5183037a52fSMartin Schwidefsky ld %f0,0(%r14) 5193037a52fSMartin Schwidefsky ld %f1,8(%r14) 5203037a52fSMartin Schwidefsky ld %f2,16(%r14) 5213037a52fSMartin Schwidefsky ld %f3,24(%r14) 5223037a52fSMartin Schwidefsky ld %f4,32(%r14) 5233037a52fSMartin Schwidefsky ld %f5,40(%r14) 5243037a52fSMartin Schwidefsky ld %f6,48(%r14) 5253037a52fSMartin Schwidefsky ld %f7,56(%r14) 5263037a52fSMartin Schwidefsky ld %f8,64(%r14) 5273037a52fSMartin Schwidefsky ld %f9,72(%r14) 5283037a52fSMartin Schwidefsky ld %f10,80(%r14) 5293037a52fSMartin Schwidefsky ld %f11,88(%r14) 5303037a52fSMartin Schwidefsky ld %f12,96(%r14) 5313037a52fSMartin Schwidefsky ld %f13,104(%r14) 5323037a52fSMartin Schwidefsky ld %f14,112(%r14) 5333037a52fSMartin Schwidefsky ld %f15,120(%r14) 5343037a52fSMartin Schwidefsky j 1f 5353037a52fSMartin Schwidefsky0: VLM %v0,%v15,0,%r11 5363037a52fSMartin Schwidefsky VLM %v16,%v31,256,%r11 5373037a52fSMartin Schwidefsky1: 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 ? 5533037a52fSMartin Schwidefsky jnz 4f 5543037a52fSMartin Schwidefsky TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 5553037a52fSMartin Schwidefsky jno .Lmcck_panic 556ce3dc447SMartin Schwidefsky4: ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off 557b0d31159SSven Schnelle tmhh %r8,0x0001 # interrupting from user ? 558b0d31159SSven Schnelle#if IS_ENABLED(CONFIG_KVM) 559e2c13d64SAlexander Gordeev jnz .Lmcck_user 560b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack 561b5415c8fSAlexander Gordeev OUTSIDE %r9,.Lsie_entry,.Lsie_skip,5f 56220232b18SAlexander Gordeev oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 563fbbdfca5SAlexander Gordeev5: BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 564fbbdfca5SAlexander Gordeev SIEEXIT 565b61b1595SSven Schnelle j .Lmcck_stack 566e2c13d64SAlexander Gordeev#else 567e2c13d64SAlexander Gordeev jz .Lmcck_stack 568e2c13d64SAlexander Gordeev#endif 569b0d31159SSven Schnelle.Lmcck_user: 570b0d31159SSven Schnelle BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 571b61b1595SSven Schnelle.Lmcck_stack: 572b61b1595SSven Schnelle lg %r15,__LC_MCCK_STACK 573b61b1595SSven Schnelle la %r11,STACK_FRAME_OVERHEAD(%r15) 57426521412SSven Schnelle stctg %c1,%c1,__PT_CR1(%r11) 575b61b1595SSven Schnelle lctlg %c1,%c1,__LC_KERNEL_ASCE 576b61b1595SSven Schnelle xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5774bfc86ceSHeiko Carstens lghi %r14,__LC_GPREGS_SAVE_AREA+64 5784bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 5797041d281SMartin Schwidefsky # clear user controlled registers to prevent speculative use 5807041d281SMartin Schwidefsky xgr %r0,%r0 5817041d281SMartin Schwidefsky xgr %r1,%r1 5827041d281SMartin Schwidefsky xgr %r3,%r3 5837041d281SMartin Schwidefsky xgr %r4,%r4 5847041d281SMartin Schwidefsky xgr %r5,%r5 5857041d281SMartin Schwidefsky xgr %r6,%r6 5867041d281SMartin Schwidefsky xgr %r7,%r7 5877041d281SMartin Schwidefsky xgr %r10,%r10 5884bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 5894bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 5904bfc86ceSHeiko Carstens xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 5914bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 5924bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 5934bfc86ceSHeiko Carstens brasl %r14,s390_do_machine_check 5940b0ed657SSven Schnelle cghi %r2,0 5950b0ed657SSven Schnelle je .Lmcck_return 5964bfc86ceSHeiko Carstens lg %r1,__LC_KERNEL_STACK # switch to kernel stack 5974bfc86ceSHeiko Carstens mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 5984bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 5994bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r1) 6004bfc86ceSHeiko Carstens lgr %r15,%r1 6014bfc86ceSHeiko Carstens brasl %r14,s390_handle_mcck 6024bfc86ceSHeiko Carstens.Lmcck_return: 60387d59863SHeiko Carstens lctlg %c1,%c1,__PT_CR1(%r11) 6044bfc86ceSHeiko Carstens lmg %r0,%r10,__PT_R0(%r11) 6054bfc86ceSHeiko Carstens mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 6064bfc86ceSHeiko Carstens tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 6074bfc86ceSHeiko Carstens jno 0f 6086b73044bSMartin Schwidefsky BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP 6094bfc86ceSHeiko Carstens stpt __LC_EXIT_TIMER 6104bfc86ceSHeiko Carstens0: lmg %r11,%r15,__PT_R11(%r11) 6110b38b5e1SSven Schnelle b __LC_RETURN_MCCK_LPSWE 6124bfc86ceSHeiko Carstens 6134bfc86ceSHeiko Carstens.Lmcck_panic: 614*7f6dc8d4SAlexander Gordeev /* 615*7f6dc8d4SAlexander Gordeev * Iterate over all possible CPU addresses in the range 0..0xffff 616*7f6dc8d4SAlexander Gordeev * and stop each CPU using signal processor. Use compare and swap 617*7f6dc8d4SAlexander Gordeev * to allow just one CPU-stopper and prevent concurrent CPUs from 618*7f6dc8d4SAlexander Gordeev * stopping each other while leaving the others running. 619*7f6dc8d4SAlexander Gordeev */ 620*7f6dc8d4SAlexander Gordeev lhi %r5,0 621*7f6dc8d4SAlexander Gordeev lhi %r6,1 622*7f6dc8d4SAlexander Gordeev larl %r7,.Lstop_lock 623*7f6dc8d4SAlexander Gordeev cs %r5,%r6,0(%r7) # single CPU-stopper only 624*7f6dc8d4SAlexander Gordeev jnz 4f 625*7f6dc8d4SAlexander Gordeev larl %r7,.Lthis_cpu 626*7f6dc8d4SAlexander Gordeev stap 0(%r7) # this CPU address 627*7f6dc8d4SAlexander Gordeev lh %r4,0(%r7) 628*7f6dc8d4SAlexander Gordeev nilh %r4,0 629*7f6dc8d4SAlexander Gordeev lhi %r0,1 630*7f6dc8d4SAlexander Gordeev sll %r0,16 # CPU counter 631*7f6dc8d4SAlexander Gordeev lhi %r3,0 # next CPU address 632*7f6dc8d4SAlexander Gordeev0: cr %r3,%r4 633*7f6dc8d4SAlexander Gordeev je 2f 634*7f6dc8d4SAlexander Gordeev1: sigp %r1,%r3,SIGP_STOP # stop next CPU 635*7f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,1b 636*7f6dc8d4SAlexander Gordeev2: ahi %r3,1 637*7f6dc8d4SAlexander Gordeev brct %r0,0b 638*7f6dc8d4SAlexander Gordeev3: sigp %r1,%r4,SIGP_STOP # stop this CPU 639*7f6dc8d4SAlexander Gordeev brc SIGP_CC_BUSY,3b 640*7f6dc8d4SAlexander Gordeev4: j 4b 64126a374aeSMartin SchwidefskyENDPROC(mcck_int_handler) 6424bfc86ceSHeiko Carstens 6434bfc86ceSHeiko Carstens# 6444bfc86ceSHeiko Carstens# PSW restart interrupt handler 6454bfc86ceSHeiko Carstens# 6464bfc86ceSHeiko CarstensENTRY(restart_int_handler) 647e5b98199SMartin Schwidefsky ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 648e5b98199SMartin Schwidefsky stg %r15,__LC_SAVE_AREA_RESTART 6494bfc86ceSHeiko Carstens lg %r15,__LC_RESTART_STACK 650ce3dc447SMartin Schwidefsky xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15) 651ce3dc447SMartin Schwidefsky stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15) 652ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 653ce3dc447SMartin Schwidefsky mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW 6544bfc86ceSHeiko Carstens xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15) 6554bfc86ceSHeiko Carstens lg %r1,__LC_RESTART_FN # load fn, parm & source cpu 6564bfc86ceSHeiko Carstens lg %r2,__LC_RESTART_DATA 6574bfc86ceSHeiko Carstens lg %r3,__LC_RESTART_SOURCE 6584bfc86ceSHeiko Carstens ltgr %r3,%r3 # test source cpu address 6594bfc86ceSHeiko Carstens jm 1f # negative -> skip source stop 6604bfc86ceSHeiko Carstens0: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu 6614bfc86ceSHeiko Carstens brc 10,0b # wait for status stored 6624bfc86ceSHeiko Carstens1: basr %r14,%r1 # call function 6634bfc86ceSHeiko Carstens stap __SF_EMPTY(%r15) # store cpu address 6644bfc86ceSHeiko Carstens llgh %r3,__SF_EMPTY(%r15) 6654bfc86ceSHeiko Carstens2: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu 6664bfc86ceSHeiko Carstens brc 2,2b 6674bfc86ceSHeiko Carstens3: j 3b 66826a374aeSMartin SchwidefskyENDPROC(restart_int_handler) 6694bfc86ceSHeiko Carstens 6704bfc86ceSHeiko Carstens .section .kprobes.text, "ax" 6714bfc86ceSHeiko Carstens 672ce3dc447SMartin Schwidefsky#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 6734bfc86ceSHeiko Carstens/* 6744bfc86ceSHeiko Carstens * The synchronous or the asynchronous stack overflowed. We are dead. 6754bfc86ceSHeiko Carstens * No need to properly save the registers, we are going to panic anyway. 6764bfc86ceSHeiko Carstens * Setup a pt_regs so that show_trace can provide a good call trace. 6774bfc86ceSHeiko Carstens */ 67826a374aeSMartin SchwidefskyENTRY(stack_overflow) 679ce3dc447SMartin Schwidefsky lg %r15,__LC_NODAT_STACK # change to panic stack 6804bfc86ceSHeiko Carstens la %r11,STACK_FRAME_OVERHEAD(%r15) 6814bfc86ceSHeiko Carstens stmg %r0,%r7,__PT_R0(%r11) 6824bfc86ceSHeiko Carstens stmg %r8,%r9,__PT_PSW(%r11) 6834bfc86ceSHeiko Carstens mvc __PT_R8(64,%r11),0(%r14) 6844bfc86ceSHeiko Carstens stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 6854bfc86ceSHeiko Carstens xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 6864bfc86ceSHeiko Carstens lgr %r2,%r11 # pass pointer to pt_regs 6874bfc86ceSHeiko Carstens jg kernel_stack_overflow 68826a374aeSMartin SchwidefskyENDPROC(stack_overflow) 6894bfc86ceSHeiko Carstens#endif 6904bfc86ceSHeiko Carstens 691*7f6dc8d4SAlexander Gordeev .section .data, "aw" 692*7f6dc8d4SAlexander Gordeev .align 4 693*7f6dc8d4SAlexander Gordeev.Lstop_lock: .long 0 694*7f6dc8d4SAlexander Gordeev.Lthis_cpu: .short 0 695*7f6dc8d4SAlexander Gordeev 6964bfc86ceSHeiko Carstens .section .rodata, "a" 697ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390x_ ## esame 6984bfc86ceSHeiko Carstens .globl sys_call_table 6994bfc86ceSHeiko Carstenssys_call_table: 7004381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7014bfc86ceSHeiko Carstens#undef SYSCALL 7024bfc86ceSHeiko Carstens 7034bfc86ceSHeiko Carstens#ifdef CONFIG_COMPAT 7044bfc86ceSHeiko Carstens 705ff4a742dSGerald Schaefer#define SYSCALL(esame,emu) .quad __s390_ ## emu 7064bfc86ceSHeiko Carstens .globl sys_call_table_emu 7074bfc86ceSHeiko Carstenssys_call_table_emu: 7084381f9f1SHendrik Brueckner#include "asm/syscall_table.h" 7094bfc86ceSHeiko Carstens#undef SYSCALL 7104bfc86ceSHeiko Carstens#endif 711