1 #include <asm/asm-offsets.h>
3 #ifdef CONFIG_PPC_BOOK3S
4 #include <asm/exception-64s.h>
6 #include <asm/exception-64e.h>
8 #include <asm/feature-fixups.h>
9 #include <asm/head-64.h>
10 #include <asm/hw_irq.h>
13 #include <asm/ppc_asm.h>
14 #include <asm/ptrace.h>
19 .tc sys_call_table[TC],sys_call_table
22 COMPAT_SYS_CALL_TABLE:
23 .tc compat_sys_call_table[TC],compat_sys_call_table
29 .macro DEBUG_SRR_VALID srr
30 #ifdef CONFIG_PPC_RFI_SRR_DEBUG
35 EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
39 EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
44 EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
48 EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
53 #ifdef CONFIG_PPC_BOOK3S
54 .macro system_call_vectored name trapnr
55 .globl system_call_vectored_\name
56 system_call_vectored_\name:
57 _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
58 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
60 extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
62 END_FTR_SECTION_IFSET(CPU_FTR_TM)
64 SCV_INTERRUPT_TO_KERNEL
76 /* Can we avoid saving r3-r8 in common case? */
83 /* Zero r9-r12, this should only be required when restoring all GPRs */
97 addi r10,r1,STACK_FRAME_OVERHEAD
98 ld r11,exception_marker@toc(r2)
99 std r11,-16(r10) /* "regshere" marker */
103 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
106 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
107 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
108 * and interrupts may be masked and pending already.
109 * system_call_exception() will call trace_hardirqs_off() which means
110 * interrupts could already have been blocked before trace_hardirqs_off,
111 * but this is the best we can do.
114 /* Calling convention has r9 = orig r0, r10 = regs */
116 bl system_call_exception
118 .Lsyscall_vectored_\name\()_exit:
119 addi r4,r1,STACK_FRAME_OVERHEAD
121 bl syscall_exit_prepare
122 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
123 .Lsyscall_vectored_\name\()_rst_start:
124 lbz r11,PACAIRQHAPPENED(r13)
125 andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
126 bne- syscall_vectored_\name\()_restart
128 stb r11,PACAIRQSOFTMASK(r13)
130 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
137 stdcx. r0,0,r1 /* to clear the reservation */
138 END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
142 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
145 bne .Lsyscall_vectored_\name\()_restore_regs
147 /* rfscv returns with LR->NIA and CTR->MSR */
151 /* Could zero these as per ABI, but we may consider a stricter ABI
152 * which preserves these if libc implementations can benefit, so
153 * restore them for now until further measurement is done. */
160 /* Zero volatile regs that may contain sensitive kernel data */
168 * We don't need to restore AMR on the way back to userspace for KUAP.
169 * The value of AMR only matters while we're in the kernel.
177 b . /* prevent speculative execution */
179 .Lsyscall_vectored_\name\()_restore_regs:
197 .Lsyscall_vectored_\name\()_rst_end:
199 syscall_vectored_\name\()_restart:
200 _ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
202 ld r1,PACA_EXIT_SAVE_R1(r13)
205 addi r4,r1,STACK_FRAME_OVERHEAD
206 li r11,IRQS_ALL_DISABLED
207 stb r11,PACAIRQSOFTMASK(r13)
208 bl syscall_exit_restart
209 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
210 b .Lsyscall_vectored_\name\()_rst_start
213 SOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
214 RESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
218 system_call_vectored common 0x3000
221 * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
222 * which is tested by system_call_exception when r0 is -1 (as set by vector
225 system_call_vectored sigill 0x7ff0
229 * Entered via kernel return set up by kernel/sstep.c, must match entry regs
231 .globl system_call_vectored_emulate
232 system_call_vectored_emulate:
233 _ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate)
234 li r10,IRQS_ALL_DISABLED
235 stb r10,PACAIRQSOFTMASK(r13)
236 b system_call_vectored_common
237 #endif /* CONFIG_PPC_BOOK3S */
239 .balign IFETCH_ALIGN_BYTES
240 .globl system_call_common_real
241 system_call_common_real:
242 _ASM_NOKPROBE_SYMBOL(system_call_common_real)
243 ld r10,PACAKMSR(r13) /* get MSR value for kernel */
246 .balign IFETCH_ALIGN_BYTES
247 .globl system_call_common
249 _ASM_NOKPROBE_SYMBOL(system_call_common)
250 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
252 extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
254 END_FTR_SECTION_IFSET(CPU_FTR_TM)
264 #ifdef CONFIG_PPC_FSL_BOOK3E
265 START_BTB_FLUSH_SECTION
267 END_BTB_FLUSH_SECTION
272 /* Can we avoid saving r3-r8 in common case? */
279 /* Zero r9-r12, this should only be required when restoring all GPRs */
291 * This clears CR0.SO (bit 28), which is the error indication on
292 * return from this system call.
294 rldimi r12,r11,28,(63-28)
299 addi r10,r1,STACK_FRAME_OVERHEAD
300 ld r11,exception_marker@toc(r2)
301 std r11,-16(r10) /* "regshere" marker */
303 #ifdef CONFIG_PPC_BOOK3S
305 stb r11,PACASRR_VALID(r13)
309 * We always enter kernel from userspace with irq soft-mask enabled and
310 * nothing pending. system_call_exception() will call
311 * trace_hardirqs_off().
313 li r11,IRQS_ALL_DISABLED
314 stb r11,PACAIRQSOFTMASK(r13)
315 #ifdef CONFIG_PPC_BOOK3S
316 li r12,-1 /* Set MSR_EE and MSR_RI */
322 /* Calling convention has r9 = orig r0, r10 = regs */
324 bl system_call_exception
327 addi r4,r1,STACK_FRAME_OVERHEAD
329 bl syscall_exit_prepare
330 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
331 #ifdef CONFIG_PPC_BOOK3S
333 lbz r11,PACAIRQHAPPENED(r13)
334 andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
338 stb r11,PACAIRQSOFTMASK(r13)
340 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
346 #ifdef CONFIG_PPC_BOOK3S
347 lbz r4,PACASRR_VALID(r13)
351 stb r4,PACASRR_VALID(r13)
361 stdcx. r0,0,r1 /* to clear the reservation */
362 END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
365 bne .Lsyscall_restore_regs
366 /* Zero volatile regs that may contain sensitive kernel data */
379 .Lsyscall_restore_regs_cont:
383 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
386 * We don't need to restore AMR on the way back to userspace for KUAP.
387 * The value of AMR only matters while we're in the kernel.
395 b . /* prevent speculative execution */
397 .Lsyscall_restore_regs:
406 b .Lsyscall_restore_regs_cont
409 #ifdef CONFIG_PPC_BOOK3S
411 _ASM_NOKPROBE_SYMBOL(syscall_restart)
413 ld r1,PACA_EXIT_SAVE_R1(r13)
416 addi r4,r1,STACK_FRAME_OVERHEAD
417 li r11,IRQS_ALL_DISABLED
418 stb r11,PACAIRQSOFTMASK(r13)
419 bl syscall_exit_restart
420 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
421 b .Lsyscall_rst_start
424 SOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
425 RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
428 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
430 _ASM_NOKPROBE_SYMBOL(tabort_syscall)
431 /* Firstly we need to enable TM in the kernel */
434 rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG
437 /* tabort, this dooms the transaction, nothing else */
438 li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
442 * Return directly to userspace. We have corrupted user register state,
443 * but userspace will never see that register state. Execution will
444 * resume after the tbegin of the aborted transaction with the
445 * checkpointed register state.
453 b . /* prevent speculative execution */
457 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
458 * touched, no exit work created, then this can be used.
460 .balign IFETCH_ALIGN_BYTES
461 .globl fast_interrupt_return_srr
462 fast_interrupt_return_srr:
463 _ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
464 kuap_check_amr r3, r4
467 #ifdef CONFIG_PPC_BOOK3S
469 kuap_user_restore r3, r4
470 b .Lfast_user_interrupt_return_srr
471 1: kuap_kernel_restore r3, r4
473 li r3,0 /* 0 return value, no EMULATE_STACK_STORE */
474 bne+ .Lfast_kernel_interrupt_return_srr
475 addi r3,r1,STACK_FRAME_OVERHEAD
476 bl unrecoverable_exception
477 b . /* should not get here */
479 bne .Lfast_user_interrupt_return_srr
480 b .Lfast_kernel_interrupt_return_srr
483 .macro interrupt_return_macro srr
484 .balign IFETCH_ALIGN_BYTES
485 .globl interrupt_return_\srr
486 interrupt_return_\srr\():
487 _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
490 beq interrupt_return_\srr\()_kernel
491 interrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
492 _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
493 addi r3,r1,STACK_FRAME_OVERHEAD
494 bl interrupt_exit_user_prepare
496 bne- .Lrestore_nvgprs_\srr
497 .Lrestore_nvgprs_\srr\()_cont:
498 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
499 #ifdef CONFIG_PPC_BOOK3S
500 .Linterrupt_return_\srr\()_user_rst_start:
501 lbz r11,PACAIRQHAPPENED(r13)
502 andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
503 bne- interrupt_return_\srr\()_user_restart
506 stb r11,PACAIRQSOFTMASK(r13)
508 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
510 .Lfast_user_interrupt_return_\srr\():
511 #ifdef CONFIG_PPC_BOOK3S
513 lbz r4,PACASRR_VALID(r13)
515 lbz r4,PACAHSRR_VALID(r13)
527 #ifdef CONFIG_PPC_BOOK3S
528 stb r4,PACASRR_VALID(r13)
534 #ifdef CONFIG_PPC_BOOK3S
535 stb r4,PACAHSRR_VALID(r13)
540 #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
541 lbz r4,PACAIRQSOFTMASK(r13)
542 tdnei r4,IRQS_ENABLED
548 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
551 stdcx. r0,0,r1 /* to clear the reservation */
554 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
580 b . /* prevent speculative execution */
581 .Linterrupt_return_\srr\()_user_rst_end:
583 .Lrestore_nvgprs_\srr\():
585 b .Lrestore_nvgprs_\srr\()_cont
587 #ifdef CONFIG_PPC_BOOK3S
588 interrupt_return_\srr\()_user_restart:
589 _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
591 ld r1,PACA_EXIT_SAVE_R1(r13)
593 addi r3,r1,STACK_FRAME_OVERHEAD
594 li r11,IRQS_ALL_DISABLED
595 stb r11,PACAIRQSOFTMASK(r13)
596 bl interrupt_exit_user_restart
597 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
598 b .Linterrupt_return_\srr\()_user_rst_start
601 SOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
602 RESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
605 .balign IFETCH_ALIGN_BYTES
606 interrupt_return_\srr\()_kernel:
607 _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
608 addi r3,r1,STACK_FRAME_OVERHEAD
609 bl interrupt_exit_kernel_prepare
611 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
612 .Linterrupt_return_\srr\()_kernel_rst_start:
614 cmpwi r11,IRQS_ENABLED
615 stb r11,PACAIRQSOFTMASK(r13)
617 #ifdef CONFIG_PPC_BOOK3S
618 lbz r11,PACAIRQHAPPENED(r13)
619 andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
620 bne- interrupt_return_\srr\()_kernel_restart
623 stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
626 .Lfast_kernel_interrupt_return_\srr\():
628 #ifdef CONFIG_PPC_BOOK3S
630 lbz r4,PACASRR_VALID(r13)
632 lbz r4,PACAHSRR_VALID(r13)
644 #ifdef CONFIG_PPC_BOOK3S
645 stb r4,PACASRR_VALID(r13)
651 #ifdef CONFIG_PPC_BOOK3S
652 stb r4,PACAHSRR_VALID(r13)
658 stdcx. r0,0,r1 /* to clear the reservation */
661 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
677 * Leaving a stale exception_marker on the stack can confuse
678 * the reliable stack unwinder later on. Clear it.
680 std r0,STACK_FRAME_OVERHEAD-16(r1)
684 bne- cr1,1f /* emulate stack store */
694 b . /* prevent speculative execution */
697 * Emulate stack store with update. New r1 value was already calculated
698 * and updated in our interrupt regs by emulate_loadstore, but we can't
699 * store the previous value of r1 to the stack before re-loading our
700 * registers from it, otherwise they could be clobbered. Use
701 * PACA_EXGEN as temporary storage to hold the store data, as
702 * interrupts are disabled here so it won't be clobbered.
705 std r9,PACA_EXGEN+0(r13)
706 addi r9,r1,INT_FRAME_SIZE /* get original r1 */
710 std r9,0(r1) /* perform store component of stdu */
711 ld r9,PACA_EXGEN+0(r13)
718 b . /* prevent speculative execution */
719 .Linterrupt_return_\srr\()_kernel_rst_end:
721 #ifdef CONFIG_PPC_BOOK3S
722 interrupt_return_\srr\()_kernel_restart:
723 _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
725 ld r1,PACA_EXIT_SAVE_R1(r13)
727 addi r3,r1,STACK_FRAME_OVERHEAD
728 li r11,IRQS_ALL_DISABLED
729 stb r11,PACAIRQSOFTMASK(r13)
730 bl interrupt_exit_kernel_restart
731 std r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
732 b .Linterrupt_return_\srr\()_kernel_rst_start
735 SOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
736 RESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
741 interrupt_return_macro srr
742 #ifdef CONFIG_PPC_BOOK3S
743 interrupt_return_macro hsrr
745 .globl __end_soft_masked
747 DEFINE_FIXED_SYMBOL(__end_soft_masked)
748 #endif /* CONFIG_PPC_BOOK3S */
750 #ifdef CONFIG_PPC_BOOK3S
751 _GLOBAL(ret_from_fork_scv)
754 li r3,0 /* fork() return value */
755 b .Lsyscall_vectored_common_exit
758 _GLOBAL(ret_from_fork)
761 li r3,0 /* fork() return value */
764 _GLOBAL(ret_from_kernel_thread)
769 #ifdef PPC64_ELF_ABI_v2