1 // SPDX-License-Identifier: GPL-2.0-or-later
4 #include <asm/asm-prototypes.h>
6 #include <asm/cputime.h>
7 #include <asm/hw_irq.h>
8 #include <asm/kprobes.h>
10 #include <asm/ptrace.h>
12 #include <asm/signal.h>
13 #include <asm/switch_to.h>
14 #include <asm/syscall.h>
16 #include <asm/unistd.h>
18 typedef long (*syscall_fn)(long, long, long, long, long, long);
20 /* Has to run notrace because it is entered not completely "reconciled" */
21 notrace long system_call_exception(long r3, long r4, long r5,
22 long r6, long r7, long r8,
23 unsigned long r0, struct pt_regs *regs)
27 if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
28 BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
30 trace_hardirqs_off(); /* finish reconciling */
32 if (IS_ENABLED(CONFIG_PPC_BOOK3S))
33 BUG_ON(!(regs->msr & MSR_RI));
34 BUG_ON(!(regs->msr & MSR_PR));
35 BUG_ON(!FULL_REGS(regs));
36 BUG_ON(regs->softe != IRQS_ENABLED);
40 account_cpu_user_entry();
42 #ifdef CONFIG_PPC_SPLPAR
43 if (IS_ENABLED(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) &&
44 firmware_has_feature(FW_FEATURE_SPLPAR)) {
45 struct lppaca *lp = local_paca->lppaca_ptr;
47 if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx)))
48 accumulate_stolen_time();
53 * This is not required for the syscall exit path, but makes the
54 * stack frame look nicer. If this was initialised in the first stack
55 * frame, or if the unwinder was taught the first stack frame always
56 * returns to user with IRQS_ENABLED, this store could be avoided!
58 regs->softe = IRQS_ENABLED;
62 if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
63 if (unlikely(regs->trap == 0x7ff0)) {
64 /* Unsupported scv vector */
65 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
69 * We use the return value of do_syscall_trace_enter() as the
70 * syscall number. If the syscall was rejected for any reason
71 * do_syscall_trace_enter() returns an invalid syscall number
72 * and the test against NR_syscalls will fail and the return
73 * value to be used is in regs->gpr[3].
75 r0 = do_syscall_trace_enter(regs);
76 if (unlikely(r0 >= NR_syscalls))
85 } else if (unlikely(r0 >= NR_syscalls)) {
86 if (unlikely(regs->trap == 0x7ff0)) {
87 /* Unsupported scv vector */
88 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
94 /* May be faster to do array_index_nospec? */
97 if (unlikely(is_32bit_task())) {
98 f = (void *)compat_sys_call_table[r0];
100 r3 &= 0x00000000ffffffffULL;
101 r4 &= 0x00000000ffffffffULL;
102 r5 &= 0x00000000ffffffffULL;
103 r6 &= 0x00000000ffffffffULL;
104 r7 &= 0x00000000ffffffffULL;
105 r8 &= 0x00000000ffffffffULL;
108 f = (void *)sys_call_table[r0];
111 return f(r3, r4, r5, r6, r7, r8);
115 * local irqs must be disabled. Returns false if the caller must re-enable
116 * them, check for new work, and try again.
118 static notrace inline bool prep_irq_for_enabled_exit(bool clear_ri)
120 /* This must be done with RI=1 because tracing may touch vmaps */
123 /* This pattern matches prep_irq_for_idle */
125 __hard_EE_RI_disable();
127 __hard_irq_disable();
128 if (unlikely(lazy_irq_pending_nocheck())) {
129 /* Took an interrupt, may have more exit work to do. */
132 trace_hardirqs_off();
133 local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
137 local_paca->irq_happened = 0;
138 irq_soft_mask_set(IRQS_ENABLED);
144 * This should be called after a syscall returns, with r3 the return value
145 * from the syscall. If this function returns non-zero, the system call
146 * exit assembly should additionally load all GPR registers and CTR and XER
147 * from the interrupt frame.
149 * The function graph tracer can not trace the return side of this function,
150 * because RI=0 and soft mask state is "unreconciled", so it is marked notrace.
152 notrace unsigned long syscall_exit_prepare(unsigned long r3,
153 struct pt_regs *regs,
156 unsigned long *ti_flagsp = ¤t_thread_info()->flags;
157 unsigned long ti_flags;
158 unsigned long ret = 0;
164 /* Check whether the syscall is issued inside a restartable sequence */
167 ti_flags = *ti_flagsp;
169 if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && !scv) {
170 if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) {
172 regs->ccr |= 0x10000000; /* Set SO bit in CR */
176 if (unlikely(ti_flags & _TIF_PERSYSCALL_MASK)) {
177 if (ti_flags & _TIF_RESTOREALL)
178 ret = _TIF_RESTOREALL;
181 clear_bits(_TIF_PERSYSCALL_MASK, ti_flagsp);
186 if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {
187 do_syscall_trace_leave(regs);
188 ret |= _TIF_RESTOREALL;
193 ti_flags = READ_ONCE(*ti_flagsp);
194 while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) {
196 if (ti_flags & _TIF_NEED_RESCHED) {
200 * SIGPENDING must restore signal handler function
201 * argument GPRs, and some non-volatiles (e.g., r1).
202 * Restore all for now. This could be made lighter.
204 if (ti_flags & _TIF_SIGPENDING)
205 ret |= _TIF_RESTOREALL;
206 do_notify_resume(regs, ti_flags);
209 ti_flags = READ_ONCE(*ti_flagsp);
212 if (IS_ENABLED(CONFIG_PPC_BOOK3S) && IS_ENABLED(CONFIG_PPC_FPU)) {
213 if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
214 unlikely((ti_flags & _TIF_RESTORE_TM))) {
215 restore_tm_state(regs);
217 unsigned long mathflags = MSR_FP;
219 if (cpu_has_feature(CPU_FTR_VSX))
220 mathflags |= MSR_VEC | MSR_VSX;
221 else if (cpu_has_feature(CPU_FTR_ALTIVEC))
222 mathflags |= MSR_VEC;
225 * If userspace MSR has all available FP bits set,
226 * then they are live and no need to restore. If not,
227 * it means the regs were given up and restore_math
228 * may decide to restore them (to avoid taking an FP
231 if ((regs->msr & mathflags) != mathflags)
236 /* scv need not set RI=0 because SRRs are not used */
237 if (unlikely(!prep_irq_for_enabled_exit(!scv))) {
242 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
243 local_paca->tm_scratch = regs->msr;
246 account_cpu_user_exit();
251 #ifdef CONFIG_PPC_BOOK3S /* BOOK3E not yet using this */
252 notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned long msr)
254 #ifdef CONFIG_PPC_BOOK3E
255 struct thread_struct *ts = ¤t->thread;
257 unsigned long *ti_flagsp = ¤t_thread_info()->flags;
258 unsigned long ti_flags;
260 unsigned long ret = 0;
262 if (IS_ENABLED(CONFIG_PPC_BOOK3S))
263 BUG_ON(!(regs->msr & MSR_RI));
264 BUG_ON(!(regs->msr & MSR_PR));
265 BUG_ON(!FULL_REGS(regs));
266 BUG_ON(regs->softe != IRQS_ENABLED);
269 * We don't need to restore AMR on the way back to userspace for KUAP.
270 * AMR can only have been unlocked if we interrupted the kernel.
274 local_irq_save(flags);
277 ti_flags = READ_ONCE(*ti_flagsp);
278 while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) {
279 local_irq_enable(); /* returning to user: may enable */
280 if (ti_flags & _TIF_NEED_RESCHED) {
283 if (ti_flags & _TIF_SIGPENDING)
284 ret |= _TIF_RESTOREALL;
285 do_notify_resume(regs, ti_flags);
288 ti_flags = READ_ONCE(*ti_flagsp);
291 if (IS_ENABLED(CONFIG_PPC_BOOK3S) && IS_ENABLED(CONFIG_PPC_FPU)) {
292 if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
293 unlikely((ti_flags & _TIF_RESTORE_TM))) {
294 restore_tm_state(regs);
296 unsigned long mathflags = MSR_FP;
298 if (cpu_has_feature(CPU_FTR_VSX))
299 mathflags |= MSR_VEC | MSR_VSX;
300 else if (cpu_has_feature(CPU_FTR_ALTIVEC))
301 mathflags |= MSR_VEC;
303 /* See above restore_math comment */
304 if ((regs->msr & mathflags) != mathflags)
309 if (unlikely(!prep_irq_for_enabled_exit(true))) {
315 #ifdef CONFIG_PPC_BOOK3E
316 if (unlikely(ts->debug.dbcr0 & DBCR0_IDM)) {
318 * Check to see if the dbcr0 register is set up to debug.
319 * Use the internal debug mode bit to do this.
321 mtmsr(mfmsr() & ~MSR_DE);
322 mtspr(SPRN_DBCR0, ts->debug.dbcr0);
323 mtspr(SPRN_DBSR, -1);
327 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
328 local_paca->tm_scratch = regs->msr;
331 account_cpu_user_exit();
336 void unrecoverable_exception(struct pt_regs *regs);
337 void preempt_schedule_irq(void);
339 notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr)
341 unsigned long *ti_flagsp = ¤t_thread_info()->flags;
343 unsigned long ret = 0;
346 if (IS_ENABLED(CONFIG_PPC_BOOK3S) && unlikely(!(regs->msr & MSR_RI)))
347 unrecoverable_exception(regs);
348 BUG_ON(regs->msr & MSR_PR);
349 BUG_ON(!FULL_REGS(regs));
351 amr = kuap_get_and_check_amr();
353 if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) {
354 clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp);
358 local_irq_save(flags);
360 if (regs->softe == IRQS_ENABLED) {
361 /* Returning to a kernel context with local irqs enabled. */
362 WARN_ON_ONCE(!(regs->msr & MSR_EE));
364 if (IS_ENABLED(CONFIG_PREEMPT)) {
365 /* Return to preemptible kernel context */
366 if (unlikely(*ti_flagsp & _TIF_NEED_RESCHED)) {
367 if (preempt_count() == 0)
368 preempt_schedule_irq();
372 if (unlikely(!prep_irq_for_enabled_exit(true))) {
374 * Can't local_irq_restore to replay if we were in
375 * interrupt context. Must replay directly.
377 if (irqs_disabled_flags(flags)) {
378 replay_soft_interrupts();
380 local_irq_restore(flags);
381 local_irq_save(flags);
383 /* Took an interrupt, may have more exit work to do. */
387 /* Returning to a kernel context with local irqs disabled. */
388 __hard_EE_RI_disable();
389 if (regs->msr & MSR_EE)
390 local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
394 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
395 local_paca->tm_scratch = regs->msr;
399 * Don't want to mfspr(SPRN_AMR) here, because this comes after mtmsr,
400 * which would cause Read-After-Write stalls. Hence, we take the AMR
401 * value from the check above.
403 kuap_restore_amr(regs, amr);