1e754f4d1SNicholas Piggin#include <asm/asm-offsets.h> 2e754f4d1SNicholas Piggin#include <asm/bug.h> 3e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 4e754f4d1SNicholas Piggin#include <asm/exception-64s.h> 5e754f4d1SNicholas Piggin#else 6e754f4d1SNicholas Piggin#include <asm/exception-64e.h> 7e754f4d1SNicholas Piggin#endif 8e754f4d1SNicholas Piggin#include <asm/feature-fixups.h> 9e754f4d1SNicholas Piggin#include <asm/head-64.h> 10e754f4d1SNicholas Piggin#include <asm/hw_irq.h> 11e754f4d1SNicholas Piggin#include <asm/kup.h> 12e754f4d1SNicholas Piggin#include <asm/mmu.h> 13e754f4d1SNicholas Piggin#include <asm/ppc_asm.h> 14e754f4d1SNicholas Piggin#include <asm/ptrace.h> 15e754f4d1SNicholas Piggin#include <asm/tm.h> 16e754f4d1SNicholas Piggin 17e754f4d1SNicholas Piggin .section ".toc","aw" 18e754f4d1SNicholas PigginSYS_CALL_TABLE: 19e754f4d1SNicholas Piggin .tc sys_call_table[TC],sys_call_table 20e754f4d1SNicholas Piggin 21e754f4d1SNicholas Piggin#ifdef CONFIG_COMPAT 22e754f4d1SNicholas PigginCOMPAT_SYS_CALL_TABLE: 23e754f4d1SNicholas Piggin .tc compat_sys_call_table[TC],compat_sys_call_table 24e754f4d1SNicholas Piggin#endif 25e754f4d1SNicholas Piggin .previous 26e754f4d1SNicholas Piggin 27e754f4d1SNicholas Piggin .align 7 28e754f4d1SNicholas Piggin 29e754f4d1SNicholas Piggin.macro DEBUG_SRR_VALID srr 30e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_RFI_SRR_DEBUG 31e754f4d1SNicholas Piggin .ifc \srr,srr 32e754f4d1SNicholas Piggin mfspr r11,SPRN_SRR0 33e754f4d1SNicholas Piggin ld r12,_NIP(r1) 34e754f4d1SNicholas Piggin100: tdne r11,r12 35e754f4d1SNicholas Piggin EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) 36e754f4d1SNicholas Piggin mfspr r11,SPRN_SRR1 37e754f4d1SNicholas Piggin ld r12,_MSR(r1) 38e754f4d1SNicholas Piggin100: tdne r11,r12 39e754f4d1SNicholas Piggin EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) 40e754f4d1SNicholas Piggin .else 41e754f4d1SNicholas Piggin mfspr r11,SPRN_HSRR0 42e754f4d1SNicholas Piggin ld r12,_NIP(r1) 43e754f4d1SNicholas Piggin100: tdne r11,r12 44e754f4d1SNicholas Piggin EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) 45e754f4d1SNicholas Piggin mfspr r11,SPRN_HSRR1 46e754f4d1SNicholas Piggin ld r12,_MSR(r1) 47e754f4d1SNicholas Piggin100: tdne r11,r12 48e754f4d1SNicholas Piggin EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) 49e754f4d1SNicholas Piggin .endif 50e754f4d1SNicholas Piggin#endif 51e754f4d1SNicholas Piggin.endm 52e754f4d1SNicholas Piggin 53e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 54e754f4d1SNicholas Piggin.macro system_call_vectored name trapnr 55e754f4d1SNicholas Piggin .globl system_call_vectored_\name 56e754f4d1SNicholas Pigginsystem_call_vectored_\name: 57e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) 58e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 59e754f4d1SNicholas PigginBEGIN_FTR_SECTION 60e754f4d1SNicholas Piggin extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */ 61e754f4d1SNicholas Piggin bne .Ltabort_syscall 62e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_TM) 63e754f4d1SNicholas Piggin#endif 64e754f4d1SNicholas Piggin SCV_INTERRUPT_TO_KERNEL 65e754f4d1SNicholas Piggin mr r10,r1 66e754f4d1SNicholas Piggin ld r1,PACAKSAVE(r13) 67e754f4d1SNicholas Piggin std r10,0(r1) 68e754f4d1SNicholas Piggin std r11,_NIP(r1) 69e754f4d1SNicholas Piggin std r12,_MSR(r1) 70e754f4d1SNicholas Piggin std r0,GPR0(r1) 71e754f4d1SNicholas Piggin std r10,GPR1(r1) 72e754f4d1SNicholas Piggin std r2,GPR2(r1) 73e754f4d1SNicholas Piggin ld r2,PACATOC(r13) 74e754f4d1SNicholas Piggin mfcr r12 75e754f4d1SNicholas Piggin li r11,0 76e754f4d1SNicholas Piggin /* Can we avoid saving r3-r8 in common case? */ 77e754f4d1SNicholas Piggin std r3,GPR3(r1) 78e754f4d1SNicholas Piggin std r4,GPR4(r1) 79e754f4d1SNicholas Piggin std r5,GPR5(r1) 80e754f4d1SNicholas Piggin std r6,GPR6(r1) 81e754f4d1SNicholas Piggin std r7,GPR7(r1) 82e754f4d1SNicholas Piggin std r8,GPR8(r1) 83e754f4d1SNicholas Piggin /* Zero r9-r12, this should only be required when restoring all GPRs */ 84e754f4d1SNicholas Piggin std r11,GPR9(r1) 85e754f4d1SNicholas Piggin std r11,GPR10(r1) 86e754f4d1SNicholas Piggin std r11,GPR11(r1) 87e754f4d1SNicholas Piggin std r11,GPR12(r1) 88e754f4d1SNicholas Piggin std r9,GPR13(r1) 89e754f4d1SNicholas Piggin SAVE_NVGPRS(r1) 90e754f4d1SNicholas Piggin std r11,_XER(r1) 91e754f4d1SNicholas Piggin std r11,_LINK(r1) 92e754f4d1SNicholas Piggin std r11,_CTR(r1) 93e754f4d1SNicholas Piggin 94e754f4d1SNicholas Piggin li r11,\trapnr 95e754f4d1SNicholas Piggin std r11,_TRAP(r1) 96e754f4d1SNicholas Piggin std r12,_CCR(r1) 97e754f4d1SNicholas Piggin addi r10,r1,STACK_FRAME_OVERHEAD 98e754f4d1SNicholas Piggin ld r11,exception_marker@toc(r2) 99e754f4d1SNicholas Piggin std r11,-16(r10) /* "regshere" marker */ 100e754f4d1SNicholas Piggin 101e754f4d1SNicholas PigginBEGIN_FTR_SECTION 102e754f4d1SNicholas Piggin HMT_MEDIUM 103e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 104e754f4d1SNicholas Piggin 105e754f4d1SNicholas Piggin /* 106e754f4d1SNicholas Piggin * scv enters with MSR[EE]=1 and is immediately considered soft-masked. 107e754f4d1SNicholas Piggin * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED, 108e754f4d1SNicholas Piggin * and interrupts may be masked and pending already. 109e754f4d1SNicholas Piggin * system_call_exception() will call trace_hardirqs_off() which means 110e754f4d1SNicholas Piggin * interrupts could already have been blocked before trace_hardirqs_off, 111e754f4d1SNicholas Piggin * but this is the best we can do. 112e754f4d1SNicholas Piggin */ 113e754f4d1SNicholas Piggin 114e754f4d1SNicholas Piggin /* Calling convention has r9 = orig r0, r10 = regs */ 115e754f4d1SNicholas Piggin mr r9,r0 116e754f4d1SNicholas Piggin bl system_call_exception 117e754f4d1SNicholas Piggin 118e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_exit: 119e754f4d1SNicholas Piggin addi r4,r1,STACK_FRAME_OVERHEAD 120e754f4d1SNicholas Piggin li r5,1 /* scv */ 121e754f4d1SNicholas Piggin bl syscall_exit_prepare 122e754f4d1SNicholas Piggin 123e754f4d1SNicholas Piggin ld r2,_CCR(r1) 124e754f4d1SNicholas Piggin ld r4,_NIP(r1) 125e754f4d1SNicholas Piggin ld r5,_MSR(r1) 126e754f4d1SNicholas Piggin 127e754f4d1SNicholas PigginBEGIN_FTR_SECTION 128e754f4d1SNicholas Piggin stdcx. r0,0,r1 /* to clear the reservation */ 129e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) 130e754f4d1SNicholas Piggin 131e754f4d1SNicholas PigginBEGIN_FTR_SECTION 132e754f4d1SNicholas Piggin HMT_MEDIUM_LOW 133e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 134e754f4d1SNicholas Piggin 135e754f4d1SNicholas Piggin cmpdi r3,0 136e754f4d1SNicholas Piggin bne .Lsyscall_vectored_\name\()_restore_regs 137e754f4d1SNicholas Piggin 138e754f4d1SNicholas Piggin /* rfscv returns with LR->NIA and CTR->MSR */ 139e754f4d1SNicholas Piggin mtlr r4 140e754f4d1SNicholas Piggin mtctr r5 141e754f4d1SNicholas Piggin 142e754f4d1SNicholas Piggin /* Could zero these as per ABI, but we may consider a stricter ABI 143e754f4d1SNicholas Piggin * which preserves these if libc implementations can benefit, so 144e754f4d1SNicholas Piggin * restore them for now until further measurement is done. */ 145e754f4d1SNicholas Piggin ld r0,GPR0(r1) 146e754f4d1SNicholas Piggin ld r4,GPR4(r1) 147e754f4d1SNicholas Piggin ld r5,GPR5(r1) 148e754f4d1SNicholas Piggin ld r6,GPR6(r1) 149e754f4d1SNicholas Piggin ld r7,GPR7(r1) 150e754f4d1SNicholas Piggin ld r8,GPR8(r1) 151e754f4d1SNicholas Piggin /* Zero volatile regs that may contain sensitive kernel data */ 152e754f4d1SNicholas Piggin li r9,0 153e754f4d1SNicholas Piggin li r10,0 154e754f4d1SNicholas Piggin li r11,0 155e754f4d1SNicholas Piggin li r12,0 156e754f4d1SNicholas Piggin mtspr SPRN_XER,r0 157e754f4d1SNicholas Piggin 158e754f4d1SNicholas Piggin /* 159e754f4d1SNicholas Piggin * We don't need to restore AMR on the way back to userspace for KUAP. 160e754f4d1SNicholas Piggin * The value of AMR only matters while we're in the kernel. 161e754f4d1SNicholas Piggin */ 162e754f4d1SNicholas Piggin mtcr r2 163e754f4d1SNicholas Piggin ld r2,GPR2(r1) 164e754f4d1SNicholas Piggin ld r3,GPR3(r1) 165e754f4d1SNicholas Piggin ld r13,GPR13(r1) 166e754f4d1SNicholas Piggin ld r1,GPR1(r1) 167e754f4d1SNicholas Piggin RFSCV_TO_USER 168e754f4d1SNicholas Piggin b . /* prevent speculative execution */ 169e754f4d1SNicholas Piggin 170e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_restore_regs: 171e754f4d1SNicholas Piggin li r3,0 172e754f4d1SNicholas Piggin mtmsrd r3,1 173e754f4d1SNicholas Piggin mtspr SPRN_SRR0,r4 174e754f4d1SNicholas Piggin mtspr SPRN_SRR1,r5 175e754f4d1SNicholas Piggin 176e754f4d1SNicholas Piggin ld r3,_CTR(r1) 177e754f4d1SNicholas Piggin ld r4,_LINK(r1) 178e754f4d1SNicholas Piggin ld r5,_XER(r1) 179e754f4d1SNicholas Piggin 180e754f4d1SNicholas Piggin REST_NVGPRS(r1) 181e754f4d1SNicholas Piggin ld r0,GPR0(r1) 182e754f4d1SNicholas Piggin mtcr r2 183e754f4d1SNicholas Piggin mtctr r3 184e754f4d1SNicholas Piggin mtlr r4 185e754f4d1SNicholas Piggin mtspr SPRN_XER,r5 186e754f4d1SNicholas Piggin REST_10GPRS(2, r1) 187e754f4d1SNicholas Piggin REST_2GPRS(12, r1) 188e754f4d1SNicholas Piggin ld r1,GPR1(r1) 189e754f4d1SNicholas Piggin RFI_TO_USER 190e754f4d1SNicholas Piggin.endm 191e754f4d1SNicholas Piggin 192e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000 193e754f4d1SNicholas Piggin/* 194e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0 195e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector 196e754f4d1SNicholas Piggin * entry code). 197e754f4d1SNicholas Piggin */ 198e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0 199e754f4d1SNicholas Piggin 200e754f4d1SNicholas Piggin 201e754f4d1SNicholas Piggin/* 202e754f4d1SNicholas Piggin * Entered via kernel return set up by kernel/sstep.c, must match entry regs 203e754f4d1SNicholas Piggin */ 204e754f4d1SNicholas Piggin .globl system_call_vectored_emulate 205e754f4d1SNicholas Pigginsystem_call_vectored_emulate: 206e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate) 207e754f4d1SNicholas Piggin li r10,IRQS_ALL_DISABLED 208e754f4d1SNicholas Piggin stb r10,PACAIRQSOFTMASK(r13) 209e754f4d1SNicholas Piggin b system_call_vectored_common 210e754f4d1SNicholas Piggin#endif 211e754f4d1SNicholas Piggin 212e754f4d1SNicholas Piggin .balign IFETCH_ALIGN_BYTES 213e754f4d1SNicholas Piggin .globl system_call_common_real 214e754f4d1SNicholas Pigginsystem_call_common_real: 215e754f4d1SNicholas Piggin ld r10,PACAKMSR(r13) /* get MSR value for kernel */ 216e754f4d1SNicholas Piggin mtmsrd r10 217e754f4d1SNicholas Piggin 218e754f4d1SNicholas Piggin .balign IFETCH_ALIGN_BYTES 219e754f4d1SNicholas Piggin .globl system_call_common 220e754f4d1SNicholas Pigginsystem_call_common: 221e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common) 222e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 223e754f4d1SNicholas PigginBEGIN_FTR_SECTION 224e754f4d1SNicholas Piggin extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */ 225e754f4d1SNicholas Piggin bne .Ltabort_syscall 226e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_TM) 227e754f4d1SNicholas Piggin#endif 228e754f4d1SNicholas Piggin mr r10,r1 229e754f4d1SNicholas Piggin ld r1,PACAKSAVE(r13) 230e754f4d1SNicholas Piggin std r10,0(r1) 231e754f4d1SNicholas Piggin std r11,_NIP(r1) 232e754f4d1SNicholas Piggin std r12,_MSR(r1) 233e754f4d1SNicholas Piggin std r0,GPR0(r1) 234e754f4d1SNicholas Piggin std r10,GPR1(r1) 235e754f4d1SNicholas Piggin std r2,GPR2(r1) 236e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_FSL_BOOK3E 237e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION 238e754f4d1SNicholas Piggin BTB_FLUSH(r10) 239e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION 240e754f4d1SNicholas Piggin#endif 241e754f4d1SNicholas Piggin ld r2,PACATOC(r13) 242e754f4d1SNicholas Piggin mfcr r12 243e754f4d1SNicholas Piggin li r11,0 244e754f4d1SNicholas Piggin /* Can we avoid saving r3-r8 in common case? */ 245e754f4d1SNicholas Piggin std r3,GPR3(r1) 246e754f4d1SNicholas Piggin std r4,GPR4(r1) 247e754f4d1SNicholas Piggin std r5,GPR5(r1) 248e754f4d1SNicholas Piggin std r6,GPR6(r1) 249e754f4d1SNicholas Piggin std r7,GPR7(r1) 250e754f4d1SNicholas Piggin std r8,GPR8(r1) 251e754f4d1SNicholas Piggin /* Zero r9-r12, this should only be required when restoring all GPRs */ 252e754f4d1SNicholas Piggin std r11,GPR9(r1) 253e754f4d1SNicholas Piggin std r11,GPR10(r1) 254e754f4d1SNicholas Piggin std r11,GPR11(r1) 255e754f4d1SNicholas Piggin std r11,GPR12(r1) 256e754f4d1SNicholas Piggin std r9,GPR13(r1) 257e754f4d1SNicholas Piggin SAVE_NVGPRS(r1) 258e754f4d1SNicholas Piggin std r11,_XER(r1) 259e754f4d1SNicholas Piggin std r11,_CTR(r1) 260e754f4d1SNicholas Piggin mflr r10 261e754f4d1SNicholas Piggin 262e754f4d1SNicholas Piggin /* 263e754f4d1SNicholas Piggin * This clears CR0.SO (bit 28), which is the error indication on 264e754f4d1SNicholas Piggin * return from this system call. 265e754f4d1SNicholas Piggin */ 266e754f4d1SNicholas Piggin rldimi r12,r11,28,(63-28) 267e754f4d1SNicholas Piggin li r11,0xc00 268e754f4d1SNicholas Piggin std r10,_LINK(r1) 269e754f4d1SNicholas Piggin std r11,_TRAP(r1) 270e754f4d1SNicholas Piggin std r12,_CCR(r1) 271e754f4d1SNicholas Piggin addi r10,r1,STACK_FRAME_OVERHEAD 272e754f4d1SNicholas Piggin ld r11,exception_marker@toc(r2) 273e754f4d1SNicholas Piggin std r11,-16(r10) /* "regshere" marker */ 274e754f4d1SNicholas Piggin 275e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 276e754f4d1SNicholas Piggin li r11,1 277e754f4d1SNicholas Piggin stb r11,PACASRR_VALID(r13) 278e754f4d1SNicholas Piggin#endif 279e754f4d1SNicholas Piggin 280e754f4d1SNicholas Piggin /* 281e754f4d1SNicholas Piggin * We always enter kernel from userspace with irq soft-mask enabled and 282e754f4d1SNicholas Piggin * nothing pending. system_call_exception() will call 283e754f4d1SNicholas Piggin * trace_hardirqs_off(). 284e754f4d1SNicholas Piggin */ 285e754f4d1SNicholas Piggin li r11,IRQS_ALL_DISABLED 286*dd152f70SNicholas Piggin li r12,-1 /* Set MSR_EE and MSR_RI */ 287e754f4d1SNicholas Piggin stb r11,PACAIRQSOFTMASK(r13) 288*dd152f70SNicholas Piggin mtmsrd r12,1 289e754f4d1SNicholas Piggin 290e754f4d1SNicholas Piggin /* Calling convention has r9 = orig r0, r10 = regs */ 291e754f4d1SNicholas Piggin mr r9,r0 292e754f4d1SNicholas Piggin bl system_call_exception 293e754f4d1SNicholas Piggin 294e754f4d1SNicholas Piggin.Lsyscall_exit: 295e754f4d1SNicholas Piggin addi r4,r1,STACK_FRAME_OVERHEAD 296e754f4d1SNicholas Piggin li r5,0 /* !scv */ 297e754f4d1SNicholas Piggin bl syscall_exit_prepare 298e754f4d1SNicholas Piggin 299e754f4d1SNicholas Piggin ld r2,_CCR(r1) 300e754f4d1SNicholas Piggin ld r6,_LINK(r1) 301e754f4d1SNicholas Piggin mtlr r6 302e754f4d1SNicholas Piggin 303e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 304e754f4d1SNicholas Piggin lbz r4,PACASRR_VALID(r13) 305e754f4d1SNicholas Piggin cmpdi r4,0 306e754f4d1SNicholas Piggin bne 1f 307e754f4d1SNicholas Piggin li r4,0 308e754f4d1SNicholas Piggin stb r4,PACASRR_VALID(r13) 309e754f4d1SNicholas Piggin#endif 310e754f4d1SNicholas Piggin ld r4,_NIP(r1) 311e754f4d1SNicholas Piggin ld r5,_MSR(r1) 312e754f4d1SNicholas Piggin mtspr SPRN_SRR0,r4 313e754f4d1SNicholas Piggin mtspr SPRN_SRR1,r5 314e754f4d1SNicholas Piggin1: 315e754f4d1SNicholas Piggin DEBUG_SRR_VALID srr 316e754f4d1SNicholas Piggin 317e754f4d1SNicholas PigginBEGIN_FTR_SECTION 318e754f4d1SNicholas Piggin stdcx. r0,0,r1 /* to clear the reservation */ 319e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) 320e754f4d1SNicholas Piggin 321e754f4d1SNicholas Piggin cmpdi r3,0 322e754f4d1SNicholas Piggin bne .Lsyscall_restore_regs 323e754f4d1SNicholas Piggin /* Zero volatile regs that may contain sensitive kernel data */ 324e754f4d1SNicholas Piggin li r0,0 325e754f4d1SNicholas Piggin li r4,0 326e754f4d1SNicholas Piggin li r5,0 327e754f4d1SNicholas Piggin li r6,0 328e754f4d1SNicholas Piggin li r7,0 329e754f4d1SNicholas Piggin li r8,0 330e754f4d1SNicholas Piggin li r9,0 331e754f4d1SNicholas Piggin li r10,0 332e754f4d1SNicholas Piggin li r11,0 333e754f4d1SNicholas Piggin li r12,0 334e754f4d1SNicholas Piggin mtctr r0 335e754f4d1SNicholas Piggin mtspr SPRN_XER,r0 336e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont: 337e754f4d1SNicholas Piggin 338e754f4d1SNicholas PigginBEGIN_FTR_SECTION 339e754f4d1SNicholas Piggin HMT_MEDIUM_LOW 340e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 341e754f4d1SNicholas Piggin 342e754f4d1SNicholas Piggin /* 343e754f4d1SNicholas Piggin * We don't need to restore AMR on the way back to userspace for KUAP. 344e754f4d1SNicholas Piggin * The value of AMR only matters while we're in the kernel. 345e754f4d1SNicholas Piggin */ 346e754f4d1SNicholas Piggin mtcr r2 347e754f4d1SNicholas Piggin ld r2,GPR2(r1) 348e754f4d1SNicholas Piggin ld r3,GPR3(r1) 349e754f4d1SNicholas Piggin ld r13,GPR13(r1) 350e754f4d1SNicholas Piggin ld r1,GPR1(r1) 351e754f4d1SNicholas Piggin RFI_TO_USER 352e754f4d1SNicholas Piggin b . /* prevent speculative execution */ 353e754f4d1SNicholas Piggin 354e754f4d1SNicholas Piggin.Lsyscall_restore_regs: 355e754f4d1SNicholas Piggin ld r3,_CTR(r1) 356e754f4d1SNicholas Piggin ld r4,_XER(r1) 357e754f4d1SNicholas Piggin REST_NVGPRS(r1) 358e754f4d1SNicholas Piggin mtctr r3 359e754f4d1SNicholas Piggin mtspr SPRN_XER,r4 360e754f4d1SNicholas Piggin ld r0,GPR0(r1) 361e754f4d1SNicholas Piggin REST_8GPRS(4, r1) 362e754f4d1SNicholas Piggin ld r12,GPR12(r1) 363e754f4d1SNicholas Piggin b .Lsyscall_restore_regs_cont 364e754f4d1SNicholas Piggin 365e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 366e754f4d1SNicholas Piggin.Ltabort_syscall: 367e754f4d1SNicholas Piggin /* Firstly we need to enable TM in the kernel */ 368e754f4d1SNicholas Piggin mfmsr r10 369e754f4d1SNicholas Piggin li r9, 1 370e754f4d1SNicholas Piggin rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG 371e754f4d1SNicholas Piggin mtmsrd r10, 0 372e754f4d1SNicholas Piggin 373e754f4d1SNicholas Piggin /* tabort, this dooms the transaction, nothing else */ 374e754f4d1SNicholas Piggin li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT) 375e754f4d1SNicholas Piggin TABORT(R9) 376e754f4d1SNicholas Piggin 377e754f4d1SNicholas Piggin /* 378e754f4d1SNicholas Piggin * Return directly to userspace. We have corrupted user register state, 379e754f4d1SNicholas Piggin * but userspace will never see that register state. Execution will 380e754f4d1SNicholas Piggin * resume after the tbegin of the aborted transaction with the 381e754f4d1SNicholas Piggin * checkpointed register state. 382e754f4d1SNicholas Piggin */ 383e754f4d1SNicholas Piggin li r9, MSR_RI 384e754f4d1SNicholas Piggin andc r10, r10, r9 385e754f4d1SNicholas Piggin mtmsrd r10, 1 386e754f4d1SNicholas Piggin mtspr SPRN_SRR0, r11 387e754f4d1SNicholas Piggin mtspr SPRN_SRR1, r12 388e754f4d1SNicholas Piggin RFI_TO_USER 389e754f4d1SNicholas Piggin b . /* prevent speculative execution */ 390e754f4d1SNicholas Piggin#endif 391e754f4d1SNicholas Piggin 392e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 393e754f4d1SNicholas Piggin_GLOBAL(ret_from_fork_scv) 394e754f4d1SNicholas Piggin bl schedule_tail 395e754f4d1SNicholas Piggin REST_NVGPRS(r1) 396e754f4d1SNicholas Piggin li r3,0 /* fork() return value */ 397e754f4d1SNicholas Piggin b .Lsyscall_vectored_common_exit 398e754f4d1SNicholas Piggin#endif 399e754f4d1SNicholas Piggin 400e754f4d1SNicholas Piggin_GLOBAL(ret_from_fork) 401e754f4d1SNicholas Piggin bl schedule_tail 402e754f4d1SNicholas Piggin REST_NVGPRS(r1) 403e754f4d1SNicholas Piggin li r3,0 /* fork() return value */ 404e754f4d1SNicholas Piggin b .Lsyscall_exit 405e754f4d1SNicholas Piggin 406e754f4d1SNicholas Piggin_GLOBAL(ret_from_kernel_thread) 407e754f4d1SNicholas Piggin bl schedule_tail 408e754f4d1SNicholas Piggin REST_NVGPRS(r1) 409e754f4d1SNicholas Piggin mtctr r14 410e754f4d1SNicholas Piggin mr r3,r15 411e754f4d1SNicholas Piggin#ifdef PPC64_ELF_ABI_v2 412e754f4d1SNicholas Piggin mr r12,r14 413e754f4d1SNicholas Piggin#endif 414e754f4d1SNicholas Piggin bctrl 415e754f4d1SNicholas Piggin li r3,0 416e754f4d1SNicholas Piggin b .Lsyscall_exit 417e754f4d1SNicholas Piggin 418e754f4d1SNicholas Piggin /* 419e754f4d1SNicholas Piggin * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not 420e754f4d1SNicholas Piggin * touched, no exit work created, then this can be used. 421e754f4d1SNicholas Piggin */ 422e754f4d1SNicholas Piggin .balign IFETCH_ALIGN_BYTES 423e754f4d1SNicholas Piggin .globl fast_interrupt_return_srr 424e754f4d1SNicholas Pigginfast_interrupt_return_srr: 425e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr) 426e754f4d1SNicholas Piggin kuap_check_amr r3, r4 427e754f4d1SNicholas Piggin ld r5,_MSR(r1) 428e754f4d1SNicholas Piggin andi. r0,r5,MSR_PR 429e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 430e754f4d1SNicholas Piggin bne .Lfast_user_interrupt_return_amr_srr 431e754f4d1SNicholas Piggin kuap_kernel_restore r3, r4 432e754f4d1SNicholas Piggin andi. r0,r5,MSR_RI 433e754f4d1SNicholas Piggin li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ 434e754f4d1SNicholas Piggin bne+ .Lfast_kernel_interrupt_return_srr 435e754f4d1SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 436e754f4d1SNicholas Piggin bl unrecoverable_exception 437e754f4d1SNicholas Piggin b . /* should not get here */ 438e754f4d1SNicholas Piggin#else 439e754f4d1SNicholas Piggin bne .Lfast_user_interrupt_return_srr 440e754f4d1SNicholas Piggin b .Lfast_kernel_interrupt_return_srr 441e754f4d1SNicholas Piggin#endif 442e754f4d1SNicholas Piggin 443e754f4d1SNicholas Piggin.macro interrupt_return_macro srr 444e754f4d1SNicholas Piggin .balign IFETCH_ALIGN_BYTES 445e754f4d1SNicholas Piggin .globl interrupt_return_\srr 446e754f4d1SNicholas Piggininterrupt_return_\srr\(): 447e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()) 448e754f4d1SNicholas Piggin ld r4,_MSR(r1) 449e754f4d1SNicholas Piggin andi. r0,r4,MSR_PR 450e754f4d1SNicholas Piggin beq .Lkernel_interrupt_return_\srr 451e754f4d1SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 452e754f4d1SNicholas Piggin bl interrupt_exit_user_prepare 453e754f4d1SNicholas Piggin cmpdi r3,0 454e754f4d1SNicholas Piggin bne- .Lrestore_nvgprs_\srr 455e754f4d1SNicholas Piggin 456e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 457e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_amr_\srr\(): 458e754f4d1SNicholas Piggin kuap_user_restore r3, r4 459e754f4d1SNicholas Piggin#endif 460e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\(): 461e754f4d1SNicholas Piggin 462e754f4d1SNicholas PigginBEGIN_FTR_SECTION 463e754f4d1SNicholas Piggin ld r10,_PPR(r1) 464e754f4d1SNicholas Piggin mtspr SPRN_PPR,r10 465e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 466e754f4d1SNicholas Piggin 467e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 468e754f4d1SNicholas Piggin .ifc \srr,srr 469e754f4d1SNicholas Piggin lbz r4,PACASRR_VALID(r13) 470e754f4d1SNicholas Piggin .else 471e754f4d1SNicholas Piggin lbz r4,PACAHSRR_VALID(r13) 472e754f4d1SNicholas Piggin .endif 473e754f4d1SNicholas Piggin cmpdi r4,0 474e754f4d1SNicholas Piggin li r4,0 475e754f4d1SNicholas Piggin bne 1f 476e754f4d1SNicholas Piggin#endif 477e754f4d1SNicholas Piggin ld r11,_NIP(r1) 478e754f4d1SNicholas Piggin ld r12,_MSR(r1) 479e754f4d1SNicholas Piggin .ifc \srr,srr 480e754f4d1SNicholas Piggin mtspr SPRN_SRR0,r11 481e754f4d1SNicholas Piggin mtspr SPRN_SRR1,r12 482e754f4d1SNicholas Piggin1: 483e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 484e754f4d1SNicholas Piggin stb r4,PACASRR_VALID(r13) 485e754f4d1SNicholas Piggin#endif 486e754f4d1SNicholas Piggin .else 487e754f4d1SNicholas Piggin mtspr SPRN_HSRR0,r11 488e754f4d1SNicholas Piggin mtspr SPRN_HSRR1,r12 489e754f4d1SNicholas Piggin1: 490e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 491e754f4d1SNicholas Piggin stb r4,PACAHSRR_VALID(r13) 492e754f4d1SNicholas Piggin#endif 493e754f4d1SNicholas Piggin .endif 494e754f4d1SNicholas Piggin DEBUG_SRR_VALID \srr 495e754f4d1SNicholas Piggin 496e754f4d1SNicholas PigginBEGIN_FTR_SECTION 497e754f4d1SNicholas Piggin stdcx. r0,0,r1 /* to clear the reservation */ 498e754f4d1SNicholas PigginFTR_SECTION_ELSE 499e754f4d1SNicholas Piggin ldarx r0,0,r1 500e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) 501e754f4d1SNicholas Piggin 502e754f4d1SNicholas Piggin ld r3,_CCR(r1) 503e754f4d1SNicholas Piggin ld r4,_LINK(r1) 504e754f4d1SNicholas Piggin ld r5,_CTR(r1) 505e754f4d1SNicholas Piggin ld r6,_XER(r1) 506e754f4d1SNicholas Piggin li r0,0 507e754f4d1SNicholas Piggin 508e754f4d1SNicholas Piggin REST_4GPRS(7, r1) 509e754f4d1SNicholas Piggin REST_2GPRS(11, r1) 510e754f4d1SNicholas Piggin REST_GPR(13, r1) 511e754f4d1SNicholas Piggin 512e754f4d1SNicholas Piggin mtcr r3 513e754f4d1SNicholas Piggin mtlr r4 514e754f4d1SNicholas Piggin mtctr r5 515e754f4d1SNicholas Piggin mtspr SPRN_XER,r6 516e754f4d1SNicholas Piggin 517e754f4d1SNicholas Piggin REST_4GPRS(2, r1) 518e754f4d1SNicholas Piggin REST_GPR(6, r1) 519e754f4d1SNicholas Piggin REST_GPR(0, r1) 520e754f4d1SNicholas Piggin REST_GPR(1, r1) 521e754f4d1SNicholas Piggin .ifc \srr,srr 522e754f4d1SNicholas Piggin RFI_TO_USER 523e754f4d1SNicholas Piggin .else 524e754f4d1SNicholas Piggin HRFI_TO_USER 525e754f4d1SNicholas Piggin .endif 526e754f4d1SNicholas Piggin b . /* prevent speculative execution */ 527e754f4d1SNicholas Piggin 528e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\(): 529e754f4d1SNicholas Piggin REST_NVGPRS(r1) 530e754f4d1SNicholas Piggin b .Lfast_user_interrupt_return_\srr 531e754f4d1SNicholas Piggin 532e754f4d1SNicholas Piggin .balign IFETCH_ALIGN_BYTES 533e754f4d1SNicholas Piggin.Lkernel_interrupt_return_\srr\(): 534e754f4d1SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 535e754f4d1SNicholas Piggin bl interrupt_exit_kernel_prepare 536e754f4d1SNicholas Piggin 537e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\(): 538e754f4d1SNicholas Piggin cmpdi cr1,r3,0 539e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 540e754f4d1SNicholas Piggin .ifc \srr,srr 541e754f4d1SNicholas Piggin lbz r4,PACASRR_VALID(r13) 542e754f4d1SNicholas Piggin .else 543e754f4d1SNicholas Piggin lbz r4,PACAHSRR_VALID(r13) 544e754f4d1SNicholas Piggin .endif 545e754f4d1SNicholas Piggin cmpdi r4,0 546e754f4d1SNicholas Piggin li r4,0 547e754f4d1SNicholas Piggin bne 1f 548e754f4d1SNicholas Piggin#endif 549e754f4d1SNicholas Piggin ld r11,_NIP(r1) 550e754f4d1SNicholas Piggin ld r12,_MSR(r1) 551e754f4d1SNicholas Piggin .ifc \srr,srr 552e754f4d1SNicholas Piggin mtspr SPRN_SRR0,r11 553e754f4d1SNicholas Piggin mtspr SPRN_SRR1,r12 554e754f4d1SNicholas Piggin1: 555e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 556e754f4d1SNicholas Piggin stb r4,PACASRR_VALID(r13) 557e754f4d1SNicholas Piggin#endif 558e754f4d1SNicholas Piggin .else 559e754f4d1SNicholas Piggin mtspr SPRN_HSRR0,r11 560e754f4d1SNicholas Piggin mtspr SPRN_HSRR1,r12 561e754f4d1SNicholas Piggin1: 562e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 563e754f4d1SNicholas Piggin stb r4,PACAHSRR_VALID(r13) 564e754f4d1SNicholas Piggin#endif 565e754f4d1SNicholas Piggin .endif 566e754f4d1SNicholas Piggin DEBUG_SRR_VALID \srr 567e754f4d1SNicholas Piggin 568e754f4d1SNicholas PigginBEGIN_FTR_SECTION 569e754f4d1SNicholas Piggin stdcx. r0,0,r1 /* to clear the reservation */ 570e754f4d1SNicholas PigginFTR_SECTION_ELSE 571e754f4d1SNicholas Piggin ldarx r0,0,r1 572e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) 573e754f4d1SNicholas Piggin 574e754f4d1SNicholas Piggin ld r3,_LINK(r1) 575e754f4d1SNicholas Piggin ld r4,_CTR(r1) 576e754f4d1SNicholas Piggin ld r5,_XER(r1) 577e754f4d1SNicholas Piggin ld r6,_CCR(r1) 578e754f4d1SNicholas Piggin li r0,0 579e754f4d1SNicholas Piggin 580e754f4d1SNicholas Piggin REST_4GPRS(7, r1) 581e754f4d1SNicholas Piggin REST_2GPRS(11, r1) 582e754f4d1SNicholas Piggin 583e754f4d1SNicholas Piggin mtlr r3 584e754f4d1SNicholas Piggin mtctr r4 585e754f4d1SNicholas Piggin mtspr SPRN_XER,r5 586e754f4d1SNicholas Piggin 587e754f4d1SNicholas Piggin /* 588e754f4d1SNicholas Piggin * Leaving a stale exception_marker on the stack can confuse 589e754f4d1SNicholas Piggin * the reliable stack unwinder later on. Clear it. 590e754f4d1SNicholas Piggin */ 591e754f4d1SNicholas Piggin std r0,STACK_FRAME_OVERHEAD-16(r1) 592e754f4d1SNicholas Piggin 593e754f4d1SNicholas Piggin REST_4GPRS(2, r1) 594e754f4d1SNicholas Piggin 595e754f4d1SNicholas Piggin bne- cr1,1f /* emulate stack store */ 596e754f4d1SNicholas Piggin mtcr r6 597e754f4d1SNicholas Piggin REST_GPR(6, r1) 598e754f4d1SNicholas Piggin REST_GPR(0, r1) 599e754f4d1SNicholas Piggin REST_GPR(1, r1) 600e754f4d1SNicholas Piggin .ifc \srr,srr 601e754f4d1SNicholas Piggin RFI_TO_KERNEL 602e754f4d1SNicholas Piggin .else 603e754f4d1SNicholas Piggin HRFI_TO_KERNEL 604e754f4d1SNicholas Piggin .endif 605e754f4d1SNicholas Piggin b . /* prevent speculative execution */ 606e754f4d1SNicholas Piggin 607e754f4d1SNicholas Piggin1: /* 608e754f4d1SNicholas Piggin * Emulate stack store with update. New r1 value was already calculated 609e754f4d1SNicholas Piggin * and updated in our interrupt regs by emulate_loadstore, but we can't 610e754f4d1SNicholas Piggin * store the previous value of r1 to the stack before re-loading our 611e754f4d1SNicholas Piggin * registers from it, otherwise they could be clobbered. Use 612e754f4d1SNicholas Piggin * PACA_EXGEN as temporary storage to hold the store data, as 613e754f4d1SNicholas Piggin * interrupts are disabled here so it won't be clobbered. 614e754f4d1SNicholas Piggin */ 615e754f4d1SNicholas Piggin mtcr r6 616e754f4d1SNicholas Piggin std r9,PACA_EXGEN+0(r13) 617e754f4d1SNicholas Piggin addi r9,r1,INT_FRAME_SIZE /* get original r1 */ 618e754f4d1SNicholas Piggin REST_GPR(6, r1) 619e754f4d1SNicholas Piggin REST_GPR(0, r1) 620e754f4d1SNicholas Piggin REST_GPR(1, r1) 621e754f4d1SNicholas Piggin std r9,0(r1) /* perform store component of stdu */ 622e754f4d1SNicholas Piggin ld r9,PACA_EXGEN+0(r13) 623e754f4d1SNicholas Piggin 624e754f4d1SNicholas Piggin .ifc \srr,srr 625e754f4d1SNicholas Piggin RFI_TO_KERNEL 626e754f4d1SNicholas Piggin .else 627e754f4d1SNicholas Piggin HRFI_TO_KERNEL 628e754f4d1SNicholas Piggin .endif 629e754f4d1SNicholas Piggin b . /* prevent speculative execution */ 630e754f4d1SNicholas Piggin.endm 631e754f4d1SNicholas Piggin 632e754f4d1SNicholas Piggininterrupt_return_macro srr 633e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S 634e754f4d1SNicholas Piggininterrupt_return_macro hsrr 635e754f4d1SNicholas Piggin#endif 636