#include <asm/asm-offsets.h>#include <asm/bug.h>#ifdef CONFIG_PPC_BOOK3S#include <asm/exception-64s.h>#else#include <asm/exception-64e.h>#endif#include <asm/feature-fixups.h>#include <asm/head-64.h>#include <asm/hw_irq.h>#include <asm/kup.h>#include <asm/mmu.h>#include <asm/ppc_asm.h>#include <asm/ptrace.h> .align 7 .macro DEBUG_SRR_VALID srr#ifdef CONFIG_PPC_RFI_SRR_DEBUG .ifc \srr,srr mfspr r11,SPRN_SRR0 ld r12,_NIP(r1) clrrdi r11,r11,2 clrrdi r12,r12,2100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) mfspr r11,SPRN_SRR1 ld r12,_MSR(r1)100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) .else mfspr r11,SPRN_HSRR0 ld r12,_NIP(r1) clrrdi r11,r11,2 clrrdi r12,r12,2100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) mfspr r11,SPRN_HSRR1 ld r12,_MSR(r1)100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) .endif#endif.endm #ifdef CONFIG_PPC_BOOK3S.macro system_call_vectored name trapnr .globl system_call_vectored_\namesystem_call_vectored_\name:_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) SCV_INTERRUPT_TO_KERNEL mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) std r11,_LINK(r1) std r11,_NIP(r1) /* Saved LR is also the next instruction */ std r12,_MSR(r1) std r0,GPR0(r1) std r10,GPR1(r1) std r2,GPR2(r1) LOAD_PACA_TOC() mfcr r12 li r11,0 /* Save syscall parameters in r3-r8 */ SAVE_GPRS(3, 8, r1) /* Zero r9-r12, this should only be required when restoring all GPRs */ std r11,GPR9(r1) std r11,GPR10(r1) std r11,GPR11(r1) std r11,GPR12(r1) std r9,GPR13(r1) SAVE_NVGPRS(r1) std r11,_XER(r1) std r11,_CTR(r1) li r11,\trapnr std r11,_TRAP(r1) std r12,_CCR(r1) std r3,ORIG_GPR3(r1) LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER) std r11,STACK_INT_FRAME_MARKER(r1) /* "regs" marker */ /* Calling convention has r3 = regs, r4 = orig r0 */ addi r3,r1,STACK_INT_FRAME_REGS mr r4,r0 BEGIN_FTR_SECTION HMT_MEDIUMEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) /* * scv enters with MSR[EE]=1 and is immediately considered soft-masked. * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED, * and interrupts may be masked and pending already. * system_call_exception() will call trace_hardirqs_off() which means * interrupts could already have been blocked before trace_hardirqs_off, * but this is the best we can do. */ /* * Zero user registers to prevent influencing speculative execution * state of kernel code. */ SANITIZE_SYSCALL_GPRS() bl CFUNC(system_call_exception) .Lsyscall_vectored_\name\()_exit: addi r4,r1,STACK_INT_FRAME_REGS li r5,1 /* scv */ bl CFUNC(syscall_exit_prepare) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */.Lsyscall_vectored_\name\()_rst_start: lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- syscall_vectored_\name\()_restart li r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) li r11,0 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS ld r2,_CCR(r1) ld r4,_NIP(r1) ld r5,_MSR(r1) BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) BEGIN_FTR_SECTION HMT_MEDIUM_LOWEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) SANITIZE_RESTORE_NVGPRS() cmpdi r3,0 bne .Lsyscall_vectored_\name\()_restore_regs /* rfscv returns with LR->NIA and CTR->MSR */ mtlr r4 mtctr r5 /* Could zero these as per ABI, but we may consider a stricter ABI * which preserves these if libc implementations can benefit, so * restore them for now until further measurement is done. */ REST_GPR(0, r1) REST_GPRS(4, 8, r1) /* Zero volatile regs that may contain sensitive kernel data */ ZEROIZE_GPRS(9, 12) mtspr SPRN_XER,r0 /* * We don't need to restore AMR on the way back to userspace for KUAP. * The value of AMR only matters while we're in the kernel. */ mtcr r2 REST_GPRS(2, 3, r1) REST_GPR(13, r1) REST_GPR(1, r1) RFSCV_TO_USER b . /* prevent speculative execution */ .Lsyscall_vectored_\name\()_restore_regs: mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r5 ld r3,_CTR(r1) ld r4,_LINK(r1) ld r5,_XER(r1) HANDLER_RESTORE_NVGPRS() REST_GPR(0, r1) mtcr r2 mtctr r3 mtlr r4 mtspr SPRN_XER,r5 REST_GPRS(2, 13, r1) REST_GPR(1, r1) RFI_TO_USER.Lsyscall_vectored_\name\()_rst_end: syscall_vectored_\name\()_restart:_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart) GET_PACA(r13) ld r1,PACA_EXIT_SAVE_R1(r13) LOAD_PACA_TOC() ld r3,RESULT(r1) addi r4,r1,STACK_INT_FRAME_REGS li r11,IRQS_ALL_DISABLED stb r11,PACAIRQSOFTMASK(r13) bl CFUNC(syscall_exit_restart) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ b .Lsyscall_vectored_\name\()_rst_start1: SOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)RESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart) .endm system_call_vectored common 0x3000 /* * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0 * which is tested by system_call_exception when r0 is -1 (as set by vector * entry code). */system_call_vectored sigill 0x7ff0 #endif /* CONFIG_PPC_BOOK3S */ .balign IFETCH_ALIGN_BYTES .globl system_call_common_realsystem_call_common_real:_ASM_NOKPROBE_SYMBOL(system_call_common_real) ld r10,PACAKMSR(r13) /* get MSR value for kernel */ mtmsrd r10 .balign IFETCH_ALIGN_BYTES .globl system_call_commonsystem_call_common:_ASM_NOKPROBE_SYMBOL(system_call_common) mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) std r11,_NIP(r1) std r12,_MSR(r1) std r0,GPR0(r1) std r10,GPR1(r1) std r2,GPR2(r1)#ifdef CONFIG_PPC_E500START_BTB_FLUSH_SECTION BTB_FLUSH(r10)END_BTB_FLUSH_SECTION#endif LOAD_PACA_TOC() mfcr r12 li r11,0 /* Save syscall parameters in r3-r8 */ SAVE_GPRS(3, 8, r1) /* Zero r9-r12, this should only be required when restoring all GPRs */ std r11,GPR9(r1) std r11,GPR10(r1) std r11,GPR11(r1) std r11,GPR12(r1) std r9,GPR13(r1) SAVE_NVGPRS(r1) std r11,_XER(r1) std r11,_CTR(r1) mflr r10 /* * This clears CR0.SO (bit 28), which is the error indication on * return from this system call. */ rldimi r12,r11,28,(63-28) li r11,0xc00 std r10,_LINK(r1) std r11,_TRAP(r1) std r12,_CCR(r1) std r3,ORIG_GPR3(r1) LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER) std r11,STACK_INT_FRAME_MARKER(r1) /* "regs" marker */ /* Calling convention has r3 = regs, r4 = orig r0 */ addi r3,r1,STACK_INT_FRAME_REGS mr r4,r0 #ifdef CONFIG_PPC_BOOK3S li r11,1 stb r11,PACASRR_VALID(r13)#endif /* * We always enter kernel from userspace with irq soft-mask enabled and * nothing pending. system_call_exception() will call * trace_hardirqs_off(). */ li r11,IRQS_ALL_DISABLED stb r11,PACAIRQSOFTMASK(r13)#ifdef CONFIG_PPC_BOOK3S li r12,-1 /* Set MSR_EE and MSR_RI */ mtmsrd r12,1#else wrteei 1#endif /* * Zero user registers to prevent influencing speculative execution * state of kernel code. */ SANITIZE_SYSCALL_GPRS() bl CFUNC(system_call_exception) .Lsyscall_exit: addi r4,r1,STACK_INT_FRAME_REGS li r5,0 /* !scv */ bl CFUNC(syscall_exit_prepare) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */#ifdef CONFIG_PPC_BOOK3S.Lsyscall_rst_start: lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- syscall_restart#endif li r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) li r11,0 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS ld r2,_CCR(r1) ld r6,_LINK(r1) mtlr r6 #ifdef CONFIG_PPC_BOOK3S lbz r4,PACASRR_VALID(r13) cmpdi r4,0 bne 1f li r4,0 stb r4,PACASRR_VALID(r13)#endif ld r4,_NIP(r1) ld r5,_MSR(r1) mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r51: DEBUG_SRR_VALID srr BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) SANITIZE_RESTORE_NVGPRS() cmpdi r3,0 bne .Lsyscall_restore_regs /* Zero volatile regs that may contain sensitive kernel data */ ZEROIZE_GPR(0) ZEROIZE_GPRS(4, 12) mtctr r0 mtspr SPRN_XER,r0.Lsyscall_restore_regs_cont: BEGIN_FTR_SECTION HMT_MEDIUM_LOWEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) /* * We don't need to restore AMR on the way back to userspace for KUAP. * The value of AMR only matters while we're in the kernel. */ mtcr r2 REST_GPRS(2, 3, r1) REST_GPR(13, r1) REST_GPR(1, r1) RFI_TO_USER b . /* prevent speculative execution */ .Lsyscall_restore_regs: ld r3,_CTR(r1) ld r4,_XER(r1) HANDLER_RESTORE_NVGPRS() mtctr r3 mtspr SPRN_XER,r4 REST_GPR(0, r1) REST_GPRS(4, 12, r1) b .Lsyscall_restore_regs_cont.Lsyscall_rst_end: #ifdef CONFIG_PPC_BOOK3Ssyscall_restart:_ASM_NOKPROBE_SYMBOL(syscall_restart) GET_PACA(r13) ld r1,PACA_EXIT_SAVE_R1(r13) LOAD_PACA_TOC() ld r3,RESULT(r1) addi r4,r1,STACK_INT_FRAME_REGS li r11,IRQS_ALL_DISABLED stb r11,PACAIRQSOFTMASK(r13) bl CFUNC(syscall_exit_restart) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ b .Lsyscall_rst_start1: SOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)#endif /* * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not * touched, no exit work created, then this can be used. */ .balign IFETCH_ALIGN_BYTES .globl fast_interrupt_return_srrfast_interrupt_return_srr:_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr) kuap_check_amr r3, r4 ld r5,_MSR(r1) andi. r0,r5,MSR_PR#ifdef CONFIG_PPC_BOOK3S beq 1f kuap_user_restore r3, r4 b .Lfast_user_interrupt_return_srr1: kuap_kernel_restore r3, r4 andi. r0,r5,MSR_RI li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ bne+ .Lfast_kernel_interrupt_return_srr addi r3,r1,STACK_INT_FRAME_REGS bl CFUNC(unrecoverable_exception) b . /* should not get here */#else bne .Lfast_user_interrupt_return_srr b .Lfast_kernel_interrupt_return_srr#endif .macro interrupt_return_macro srr .balign IFETCH_ALIGN_BYTES .globl interrupt_return_\srrinterrupt_return_\srr\():_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()) ld r4,_MSR(r1) andi. r0,r4,MSR_PR beq interrupt_return_\srr\()_kernelinterrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user) addi r3,r1,STACK_INT_FRAME_REGS bl CFUNC(interrupt_exit_user_prepare)#ifndef CONFIG_INTERRUPT_SANITIZE_REGISTERS cmpdi r3,0 bne- .Lrestore_nvgprs_\srr.Lrestore_nvgprs_\srr\()_cont:#endif std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */#ifdef CONFIG_PPC_BOOK3S.Linterrupt_return_\srr\()_user_rst_start: lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- interrupt_return_\srr\()_user_restart#endif li r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) li r11,0 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS .Lfast_user_interrupt_return_\srr\(): SANITIZE_RESTORE_NVGPRS()#ifdef CONFIG_PPC_BOOK3S .ifc \srr,srr lbz r4,PACASRR_VALID(r13) .else lbz r4,PACAHSRR_VALID(r13) .endif cmpdi r4,0 li r4,0 bne 1f#endif ld r11,_NIP(r1) ld r12,_MSR(r1) .ifc \srr,srr mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r121:#ifdef CONFIG_PPC_BOOK3S stb r4,PACASRR_VALID(r13)#endif .else mtspr SPRN_HSRR0,r11 mtspr SPRN_HSRR1,r121:#ifdef CONFIG_PPC_BOOK3S stb r4,PACAHSRR_VALID(r13)#endif .endif DEBUG_SRR_VALID \srr #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG lbz r4,PACAIRQSOFTMASK(r13) tdnei r4,IRQS_ENABLED#endif BEGIN_FTR_SECTION ld r10,_PPR(r1) mtspr SPRN_PPR,r10END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */FTR_SECTION_ELSE ldarx r0,0,r1ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) ld r3,_CCR(r1) ld r4,_LINK(r1) ld r5,_CTR(r1) ld r6,_XER(r1) li r0,0 REST_GPRS(7, 13, r1) mtcr r3 mtlr r4 mtctr r5 mtspr SPRN_XER,r6 REST_GPRS(2, 6, r1)Lines 1–500 of 772. Load more
#include <asm/asm-offsets.h> #include <asm/bug.h> #ifdef CONFIG_PPC_BOOK3S #include <asm/exception-64s.h> #else #include <asm/exception-64e.h> #endif #include <asm/feature-fixups.h> #include <asm/head-64.h> #include <asm/hw_irq.h> #include <asm/kup.h> #include <asm/mmu.h> #include <asm/ppc_asm.h> #include <asm/ptrace.h> .align 7 .macro DEBUG_SRR_VALID srr #ifdef CONFIG_PPC_RFI_SRR_DEBUG .ifc \srr,srr mfspr r11,SPRN_SRR0 ld r12,_NIP(r1) clrrdi r11,r11,2 clrrdi r12,r12,2 100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) mfspr r11,SPRN_SRR1 ld r12,_MSR(r1) 100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) .else mfspr r11,SPRN_HSRR0 ld r12,_NIP(r1) clrrdi r11,r11,2 clrrdi r12,r12,2 100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) mfspr r11,SPRN_HSRR1 ld r12,_MSR(r1) 100: tdne r11,r12 EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) .endif #endif .endm #ifdef CONFIG_PPC_BOOK3S .macro system_call_vectored name trapnr .globl system_call_vectored_\name system_call_vectored_\name: _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) SCV_INTERRUPT_TO_KERNEL mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) std r11,_LINK(r1) std r11,_NIP(r1) /* Saved LR is also the next instruction */ std r12,_MSR(r1) std r0,GPR0(r1) std r10,GPR1(r1) std r2,GPR2(r1) LOAD_PACA_TOC() mfcr r12 li r11,0 /* Save syscall parameters in r3-r8 */ SAVE_GPRS(3, 8, r1) /* Zero r9-r12, this should only be required when restoring all GPRs */ std r11,GPR9(r1) std r11,GPR10(r1) std r11,GPR11(r1) std r11,GPR12(r1) std r9,GPR13(r1) SAVE_NVGPRS(r1) std r11,_XER(r1) std r11,_CTR(r1) li r11,\trapnr std r11,_TRAP(r1) std r12,_CCR(r1) std r3,ORIG_GPR3(r1) LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER) std r11,STACK_INT_FRAME_MARKER(r1) /* "regs" marker */ /* Calling convention has r3 = regs, r4 = orig r0 */ addi r3,r1,STACK_INT_FRAME_REGS mr r4,r0 BEGIN_FTR_SECTION HMT_MEDIUM END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) /* * scv enters with MSR[EE]=1 and is immediately considered soft-masked. * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED, * and interrupts may be masked and pending already. * system_call_exception() will call trace_hardirqs_off() which means * interrupts could already have been blocked before trace_hardirqs_off, * but this is the best we can do. */ /* * Zero user registers to prevent influencing speculative execution * state of kernel code. */ SANITIZE_SYSCALL_GPRS() bl CFUNC(system_call_exception) .Lsyscall_vectored_\name\()_exit: addi r4,r1,STACK_INT_FRAME_REGS li r5,1 /* scv */ bl CFUNC(syscall_exit_prepare) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ .Lsyscall_vectored_\name\()_rst_start: lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- syscall_vectored_\name\()_restart li r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) li r11,0 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS ld r2,_CCR(r1) ld r4,_NIP(r1) ld r5,_MSR(r1) BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) BEGIN_FTR_SECTION HMT_MEDIUM_LOW END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) SANITIZE_RESTORE_NVGPRS() cmpdi r3,0 bne .Lsyscall_vectored_\name\()_restore_regs /* rfscv returns with LR->NIA and CTR->MSR */ mtlr r4 mtctr r5 /* Could zero these as per ABI, but we may consider a stricter ABI * which preserves these if libc implementations can benefit, so * restore them for now until further measurement is done. */ REST_GPR(0, r1) REST_GPRS(4, 8, r1) /* Zero volatile regs that may contain sensitive kernel data */ ZEROIZE_GPRS(9, 12) mtspr SPRN_XER,r0 /* * We don't need to restore AMR on the way back to userspace for KUAP. * The value of AMR only matters while we're in the kernel. */ mtcr r2 REST_GPRS(2, 3, r1) REST_GPR(13, r1) REST_GPR(1, r1) RFSCV_TO_USER b . /* prevent speculative execution */ .Lsyscall_vectored_\name\()_restore_regs: mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r5 ld r3,_CTR(r1) ld r4,_LINK(r1) ld r5,_XER(r1) HANDLER_RESTORE_NVGPRS() REST_GPR(0, r1) mtcr r2 mtctr r3 mtlr r4 mtspr SPRN_XER,r5 REST_GPRS(2, 13, r1) REST_GPR(1, r1) RFI_TO_USER .Lsyscall_vectored_\name\()_rst_end: syscall_vectored_\name\()_restart: _ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart) GET_PACA(r13) ld r1,PACA_EXIT_SAVE_R1(r13) LOAD_PACA_TOC() ld r3,RESULT(r1) addi r4,r1,STACK_INT_FRAME_REGS li r11,IRQS_ALL_DISABLED stb r11,PACAIRQSOFTMASK(r13) bl CFUNC(syscall_exit_restart) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ b .Lsyscall_vectored_\name\()_rst_start 1: SOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b) RESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart) .endm system_call_vectored common 0x3000 /* * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0 * which is tested by system_call_exception when r0 is -1 (as set by vector * entry code). */ system_call_vectored sigill 0x7ff0 #endif /* CONFIG_PPC_BOOK3S */ .balign IFETCH_ALIGN_BYTES .globl system_call_common_real system_call_common_real: _ASM_NOKPROBE_SYMBOL(system_call_common_real) ld r10,PACAKMSR(r13) /* get MSR value for kernel */ mtmsrd r10 .balign IFETCH_ALIGN_BYTES .globl system_call_common system_call_common: _ASM_NOKPROBE_SYMBOL(system_call_common) mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) std r11,_NIP(r1) std r12,_MSR(r1) std r0,GPR0(r1) std r10,GPR1(r1) std r2,GPR2(r1) #ifdef CONFIG_PPC_E500 START_BTB_FLUSH_SECTION BTB_FLUSH(r10) END_BTB_FLUSH_SECTION #endif LOAD_PACA_TOC() mfcr r12 li r11,0 /* Save syscall parameters in r3-r8 */ SAVE_GPRS(3, 8, r1) /* Zero r9-r12, this should only be required when restoring all GPRs */ std r11,GPR9(r1) std r11,GPR10(r1) std r11,GPR11(r1) std r11,GPR12(r1) std r9,GPR13(r1) SAVE_NVGPRS(r1) std r11,_XER(r1) std r11,_CTR(r1) mflr r10 /* * This clears CR0.SO (bit 28), which is the error indication on * return from this system call. */ rldimi r12,r11,28,(63-28) li r11,0xc00 std r10,_LINK(r1) std r11,_TRAP(r1) std r12,_CCR(r1) std r3,ORIG_GPR3(r1) LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER) std r11,STACK_INT_FRAME_MARKER(r1) /* "regs" marker */ /* Calling convention has r3 = regs, r4 = orig r0 */ addi r3,r1,STACK_INT_FRAME_REGS mr r4,r0 #ifdef CONFIG_PPC_BOOK3S li r11,1 stb r11,PACASRR_VALID(r13) #endif /* * We always enter kernel from userspace with irq soft-mask enabled and * nothing pending. system_call_exception() will call * trace_hardirqs_off(). */ li r11,IRQS_ALL_DISABLED stb r11,PACAIRQSOFTMASK(r13) #ifdef CONFIG_PPC_BOOK3S li r12,-1 /* Set MSR_EE and MSR_RI */ mtmsrd r12,1 #else wrteei 1 #endif /* * Zero user registers to prevent influencing speculative execution * state of kernel code. */ SANITIZE_SYSCALL_GPRS() bl CFUNC(system_call_exception) .Lsyscall_exit: addi r4,r1,STACK_INT_FRAME_REGS li r5,0 /* !scv */ bl CFUNC(syscall_exit_prepare) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ #ifdef CONFIG_PPC_BOOK3S .Lsyscall_rst_start: lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- syscall_restart #endif li r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) li r11,0 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS ld r2,_CCR(r1) ld r6,_LINK(r1) mtlr r6 #ifdef CONFIG_PPC_BOOK3S lbz r4,PACASRR_VALID(r13) cmpdi r4,0 bne 1f li r4,0 stb r4,PACASRR_VALID(r13) #endif ld r4,_NIP(r1) ld r5,_MSR(r1) mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r5 1: DEBUG_SRR_VALID srr BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) SANITIZE_RESTORE_NVGPRS() cmpdi r3,0 bne .Lsyscall_restore_regs /* Zero volatile regs that may contain sensitive kernel data */ ZEROIZE_GPR(0) ZEROIZE_GPRS(4, 12) mtctr r0 mtspr SPRN_XER,r0 .Lsyscall_restore_regs_cont: BEGIN_FTR_SECTION HMT_MEDIUM_LOW END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) /* * We don't need to restore AMR on the way back to userspace for KUAP. * The value of AMR only matters while we're in the kernel. */ mtcr r2 REST_GPRS(2, 3, r1) REST_GPR(13, r1) REST_GPR(1, r1) RFI_TO_USER b . /* prevent speculative execution */ .Lsyscall_restore_regs: ld r3,_CTR(r1) ld r4,_XER(r1) HANDLER_RESTORE_NVGPRS() mtctr r3 mtspr SPRN_XER,r4 REST_GPR(0, r1) REST_GPRS(4, 12, r1) b .Lsyscall_restore_regs_cont .Lsyscall_rst_end: #ifdef CONFIG_PPC_BOOK3S syscall_restart: _ASM_NOKPROBE_SYMBOL(syscall_restart) GET_PACA(r13) ld r1,PACA_EXIT_SAVE_R1(r13) LOAD_PACA_TOC() ld r3,RESULT(r1) addi r4,r1,STACK_INT_FRAME_REGS li r11,IRQS_ALL_DISABLED stb r11,PACAIRQSOFTMASK(r13) bl CFUNC(syscall_exit_restart) std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ b .Lsyscall_rst_start 1: SOFT_MASK_TABLE(.Lsyscall_rst_start, 1b) RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart) #endif /* * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not * touched, no exit work created, then this can be used. */ .balign IFETCH_ALIGN_BYTES .globl fast_interrupt_return_srr fast_interrupt_return_srr: _ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr) kuap_check_amr r3, r4 ld r5,_MSR(r1) andi. r0,r5,MSR_PR #ifdef CONFIG_PPC_BOOK3S beq 1f kuap_user_restore r3, r4 b .Lfast_user_interrupt_return_srr 1: kuap_kernel_restore r3, r4 andi. r0,r5,MSR_RI li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ bne+ .Lfast_kernel_interrupt_return_srr addi r3,r1,STACK_INT_FRAME_REGS bl CFUNC(unrecoverable_exception) b . /* should not get here */ #else bne .Lfast_user_interrupt_return_srr b .Lfast_kernel_interrupt_return_srr #endif .macro interrupt_return_macro srr .balign IFETCH_ALIGN_BYTES .globl interrupt_return_\srr interrupt_return_\srr\(): _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()) ld r4,_MSR(r1) andi. r0,r4,MSR_PR beq interrupt_return_\srr\()_kernel interrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user) addi r3,r1,STACK_INT_FRAME_REGS bl CFUNC(interrupt_exit_user_prepare) #ifndef CONFIG_INTERRUPT_SANITIZE_REGISTERS cmpdi r3,0 bne- .Lrestore_nvgprs_\srr .Lrestore_nvgprs_\srr\()_cont: #endif std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */ #ifdef CONFIG_PPC_BOOK3S .Linterrupt_return_\srr\()_user_rst_start: lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- interrupt_return_\srr\()_user_restart #endif li r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) li r11,0 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS .Lfast_user_interrupt_return_\srr\(): SANITIZE_RESTORE_NVGPRS() #ifdef CONFIG_PPC_BOOK3S .ifc \srr,srr lbz r4,PACASRR_VALID(r13) .else lbz r4,PACAHSRR_VALID(r13) .endif cmpdi r4,0 li r4,0 bne 1f #endif ld r11,_NIP(r1) ld r12,_MSR(r1) .ifc \srr,srr mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r12 1: #ifdef CONFIG_PPC_BOOK3S stb r4,PACASRR_VALID(r13) #endif .else mtspr SPRN_HSRR0,r11 mtspr SPRN_HSRR1,r12 1: #ifdef CONFIG_PPC_BOOK3S stb r4,PACAHSRR_VALID(r13) #endif .endif DEBUG_SRR_VALID \srr #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG lbz r4,PACAIRQSOFTMASK(r13) tdnei r4,IRQS_ENABLED #endif BEGIN_FTR_SECTION ld r10,_PPR(r1) mtspr SPRN_PPR,r10 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) BEGIN_FTR_SECTION stdcx. r0,0,r1 /* to clear the reservation */ FTR_SECTION_ELSE ldarx r0,0,r1 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) ld r3,_CCR(r1) ld r4,_LINK(r1) ld r5,_CTR(r1) ld r6,_XER(r1) li r0,0 REST_GPRS(7, 13, r1) mtcr r3 mtlr r4 mtctr r5 mtspr SPRN_XER,r6 REST_GPRS(2, 6, r1)