05e7fc4ffb50d29082523b15ca33012d8320e361
[linux-2.6-microblaze.git] / arch / powerpc / include / asm / interrupt.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _ASM_POWERPC_INTERRUPT_H
3 #define _ASM_POWERPC_INTERRUPT_H
4
5 #include <linux/context_tracking.h>
6 #include <linux/hardirq.h>
7 #include <asm/cputime.h>
8 #include <asm/ftrace.h>
9 #include <asm/kprobes.h>
10 #include <asm/runlatch.h>
11
12 static inline void nap_adjust_return(struct pt_regs *regs)
13 {
14 #ifdef CONFIG_PPC_970_NAP
15         if (unlikely(test_thread_local_flags(_TLF_NAPPING))) {
16                 /* Can avoid a test-and-clear because NMIs do not call this */
17                 clear_thread_local_flags(_TLF_NAPPING);
18                 regs->nip = (unsigned long)power4_idle_nap_return;
19         }
20 #endif
21 }
22
23 struct interrupt_state {
24 #ifdef CONFIG_PPC_BOOK3E_64
25         enum ctx_state ctx_state;
26 #endif
27 };
28
29 static inline void booke_restore_dbcr0(void)
30 {
31 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
32         unsigned long dbcr0 = current->thread.debug.dbcr0;
33
34         if (IS_ENABLED(CONFIG_PPC32) && unlikely(dbcr0 & DBCR0_IDM)) {
35                 mtspr(SPRN_DBSR, -1);
36                 mtspr(SPRN_DBCR0, global_dbcr0[smp_processor_id()]);
37         }
38 #endif
39 }
40
41 static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
42 {
43 #ifdef CONFIG_PPC32
44         if (!arch_irq_disabled_regs(regs))
45                 trace_hardirqs_off();
46
47         if (user_mode(regs)) {
48                 kuep_lock();
49                 account_cpu_user_entry();
50         } else {
51                 kuap_save_and_lock(regs);
52         }
53 #endif
54         /*
55          * Book3E reconciles irq soft mask in asm
56          */
57 #ifdef CONFIG_PPC_BOOK3S_64
58         if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
59                 trace_hardirqs_off();
60         local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
61
62         if (user_mode(regs)) {
63                 CT_WARN_ON(ct_state() != CONTEXT_USER);
64                 user_exit_irqoff();
65
66                 account_cpu_user_entry();
67                 account_stolen_time();
68         } else {
69                 /*
70                  * CT_WARN_ON comes here via program_check_exception,
71                  * so avoid recursion.
72                  */
73                 if (TRAP(regs) != 0x700)
74                         CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
75         }
76 #endif
77
78 #ifdef CONFIG_PPC_BOOK3E_64
79         state->ctx_state = exception_enter();
80         if (user_mode(regs))
81                 account_cpu_user_entry();
82 #endif
83
84         booke_restore_dbcr0();
85 }
86
87 /*
88  * Care should be taken to note that interrupt_exit_prepare and
89  * interrupt_async_exit_prepare do not necessarily return immediately to
90  * regs context (e.g., if regs is usermode, we don't necessarily return to
91  * user mode). Other interrupts might be taken between here and return,
92  * context switch / preemption may occur in the exit path after this, or a
93  * signal may be delivered, etc.
94  *
95  * The real interrupt exit code is platform specific, e.g.,
96  * interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64s.
97  *
98  * However interrupt_nmi_exit_prepare does return directly to regs, because
99  * NMIs do not do "exit work" or replay soft-masked interrupts.
100  */
101 static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
102 {
103 #ifdef CONFIG_PPC_BOOK3E_64
104         exception_exit(state->ctx_state);
105 #endif
106
107         if (user_mode(regs))
108                 kuep_unlock();
109         /*
110          * Book3S exits to user via interrupt_exit_user_prepare(), which does
111          * context tracking, which is a cleaner way to handle PREEMPT=y
112          * and avoid context entry/exit in e.g., preempt_schedule_irq()),
113          * which is likely to be where the core code wants to end up.
114          *
115          * The above comment explains why we can't do the
116          *
117          *     if (user_mode(regs))
118          *         user_exit_irqoff();
119          *
120          * sequence here.
121          */
122 }
123
124 static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
125 {
126 #ifdef CONFIG_PPC_BOOK3S_64
127         if (cpu_has_feature(CPU_FTR_CTRL) &&
128             !test_thread_local_flags(_TLF_RUNLATCH))
129                 __ppc64_runlatch_on();
130 #endif
131
132         interrupt_enter_prepare(regs, state);
133         irq_enter();
134 }
135
136 static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
137 {
138         /*
139          * Adjust at exit so the main handler sees the true NIA. This must
140          * come before irq_exit() because irq_exit can enable interrupts, and
141          * if another interrupt is taken before nap_adjust_return has run
142          * here, then that interrupt would return directly to idle nap return.
143          */
144         nap_adjust_return(regs);
145
146         irq_exit();
147         interrupt_exit_prepare(regs, state);
148 }
149
150 struct interrupt_nmi_state {
151 #ifdef CONFIG_PPC64
152 #ifdef CONFIG_PPC_BOOK3S_64
153         u8 irq_soft_mask;
154         u8 irq_happened;
155 #endif
156         u8 ftrace_enabled;
157 #endif
158 };
159
160 static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
161 {
162 #ifdef CONFIG_PPC64
163 #ifdef CONFIG_PPC_BOOK3S_64
164         state->irq_soft_mask = local_paca->irq_soft_mask;
165         state->irq_happened = local_paca->irq_happened;
166
167         /*
168          * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
169          * the right thing, and set IRQ_HARD_DIS. We do not want to reconcile
170          * because that goes through irq tracing which we don't want in NMI.
171          */
172         local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
173         local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
174
175         /* Don't do any per-CPU operations until interrupt state is fixed */
176 #endif
177         /* Allow DEC and PMI to be traced when they are soft-NMI */
178         if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260) {
179                 state->ftrace_enabled = this_cpu_get_ftrace_enabled();
180                 this_cpu_set_ftrace_enabled(0);
181         }
182 #endif
183
184         /*
185          * Do not use nmi_enter() for pseries hash guest taking a real-mode
186          * NMI because not everything it touches is within the RMA limit.
187          */
188         if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) ||
189                         !firmware_has_feature(FW_FEATURE_LPAR) ||
190                         radix_enabled() || (mfmsr() & MSR_DR))
191                 nmi_enter();
192 }
193
194 static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
195 {
196         if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) ||
197                         !firmware_has_feature(FW_FEATURE_LPAR) ||
198                         radix_enabled() || (mfmsr() & MSR_DR))
199                 nmi_exit();
200
201         /*
202          * nmi does not call nap_adjust_return because nmi should not create
203          * new work to do (must use irq_work for that).
204          */
205
206 #ifdef CONFIG_PPC64
207         if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260)
208                 this_cpu_set_ftrace_enabled(state->ftrace_enabled);
209
210 #ifdef CONFIG_PPC_BOOK3S_64
211         /* Check we didn't change the pending interrupt mask. */
212         WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != local_paca->irq_happened);
213         local_paca->irq_happened = state->irq_happened;
214         local_paca->irq_soft_mask = state->irq_soft_mask;
215 #endif
216 #endif
217 }
218
219 /*
220  * Don't use noinstr here like x86, but rather add NOKPROBE_SYMBOL to each
221  * function definition. The reason for this is the noinstr section is placed
222  * after the main text section, i.e., very far away from the interrupt entry
223  * asm. That creates problems with fitting linker stubs when building large
224  * kernels.
225  */
226 #define interrupt_handler __visible noinline notrace __no_kcsan __no_sanitize_address
227
228 /**
229  * DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function
230  * @func:       Function name of the entry point
231  * @returns:    Returns a value back to asm caller
232  */
233 #define DECLARE_INTERRUPT_HANDLER_RAW(func)                             \
234         __visible long func(struct pt_regs *regs)
235
236 /**
237  * DEFINE_INTERRUPT_HANDLER_RAW - Define raw interrupt handler function
238  * @func:       Function name of the entry point
239  * @returns:    Returns a value back to asm caller
240  *
241  * @func is called from ASM entry code.
242  *
243  * This is a plain function which does no tracing, reconciling, etc.
244  * The macro is written so it acts as function definition. Append the
245  * body with a pair of curly brackets.
246  *
247  * raw interrupt handlers must not enable or disable interrupts, or
248  * schedule, tracing and instrumentation (ftrace, lockdep, etc) would
249  * not be advisable either, although may be possible in a pinch, the
250  * trace will look odd at least.
251  *
252  * A raw handler may call one of the other interrupt handler functions
253  * to be converted into that interrupt context without these restrictions.
254  *
255  * On PPC64, _RAW handlers may return with fast_interrupt_return.
256  *
257  * Specific handlers may have additional restrictions.
258  */
259 #define DEFINE_INTERRUPT_HANDLER_RAW(func)                              \
260 static __always_inline long ____##func(struct pt_regs *regs);           \
261                                                                         \
262 interrupt_handler long func(struct pt_regs *regs)                       \
263 {                                                                       \
264         long ret;                                                       \
265                                                                         \
266         ret = ____##func (regs);                                        \
267                                                                         \
268         return ret;                                                     \
269 }                                                                       \
270 NOKPROBE_SYMBOL(func);                                                  \
271                                                                         \
272 static __always_inline long ____##func(struct pt_regs *regs)
273
274 /**
275  * DECLARE_INTERRUPT_HANDLER - Declare synchronous interrupt handler function
276  * @func:       Function name of the entry point
277  */
278 #define DECLARE_INTERRUPT_HANDLER(func)                                 \
279         __visible void func(struct pt_regs *regs)
280
281 /**
282  * DEFINE_INTERRUPT_HANDLER - Define synchronous interrupt handler function
283  * @func:       Function name of the entry point
284  *
285  * @func is called from ASM entry code.
286  *
287  * The macro is written so it acts as function definition. Append the
288  * body with a pair of curly brackets.
289  */
290 #define DEFINE_INTERRUPT_HANDLER(func)                                  \
291 static __always_inline void ____##func(struct pt_regs *regs);           \
292                                                                         \
293 interrupt_handler void func(struct pt_regs *regs)                       \
294 {                                                                       \
295         struct interrupt_state state;                                   \
296                                                                         \
297         interrupt_enter_prepare(regs, &state);                          \
298                                                                         \
299         ____##func (regs);                                              \
300                                                                         \
301         interrupt_exit_prepare(regs, &state);                           \
302 }                                                                       \
303 NOKPROBE_SYMBOL(func);                                                  \
304                                                                         \
305 static __always_inline void ____##func(struct pt_regs *regs)
306
307 /**
308  * DECLARE_INTERRUPT_HANDLER_RET - Declare synchronous interrupt handler function
309  * @func:       Function name of the entry point
310  * @returns:    Returns a value back to asm caller
311  */
312 #define DECLARE_INTERRUPT_HANDLER_RET(func)                             \
313         __visible long func(struct pt_regs *regs)
314
315 /**
316  * DEFINE_INTERRUPT_HANDLER_RET - Define synchronous interrupt handler function
317  * @func:       Function name of the entry point
318  * @returns:    Returns a value back to asm caller
319  *
320  * @func is called from ASM entry code.
321  *
322  * The macro is written so it acts as function definition. Append the
323  * body with a pair of curly brackets.
324  */
325 #define DEFINE_INTERRUPT_HANDLER_RET(func)                              \
326 static __always_inline long ____##func(struct pt_regs *regs);           \
327                                                                         \
328 interrupt_handler long func(struct pt_regs *regs)                       \
329 {                                                                       \
330         struct interrupt_state state;                                   \
331         long ret;                                                       \
332                                                                         \
333         interrupt_enter_prepare(regs, &state);                          \
334                                                                         \
335         ret = ____##func (regs);                                        \
336                                                                         \
337         interrupt_exit_prepare(regs, &state);                           \
338                                                                         \
339         return ret;                                                     \
340 }                                                                       \
341 NOKPROBE_SYMBOL(func);                                                  \
342                                                                         \
343 static __always_inline long ____##func(struct pt_regs *regs)
344
345 /**
346  * DECLARE_INTERRUPT_HANDLER_ASYNC - Declare asynchronous interrupt handler function
347  * @func:       Function name of the entry point
348  */
349 #define DECLARE_INTERRUPT_HANDLER_ASYNC(func)                           \
350         __visible void func(struct pt_regs *regs)
351
352 /**
353  * DEFINE_INTERRUPT_HANDLER_ASYNC - Define asynchronous interrupt handler function
354  * @func:       Function name of the entry point
355  *
356  * @func is called from ASM entry code.
357  *
358  * The macro is written so it acts as function definition. Append the
359  * body with a pair of curly brackets.
360  */
361 #define DEFINE_INTERRUPT_HANDLER_ASYNC(func)                            \
362 static __always_inline void ____##func(struct pt_regs *regs);           \
363                                                                         \
364 interrupt_handler void func(struct pt_regs *regs)                       \
365 {                                                                       \
366         struct interrupt_state state;                                   \
367                                                                         \
368         interrupt_async_enter_prepare(regs, &state);                    \
369                                                                         \
370         ____##func (regs);                                              \
371                                                                         \
372         interrupt_async_exit_prepare(regs, &state);                     \
373 }                                                                       \
374 NOKPROBE_SYMBOL(func);                                                  \
375                                                                         \
376 static __always_inline void ____##func(struct pt_regs *regs)
377
378 /**
379  * DECLARE_INTERRUPT_HANDLER_NMI - Declare NMI interrupt handler function
380  * @func:       Function name of the entry point
381  * @returns:    Returns a value back to asm caller
382  */
383 #define DECLARE_INTERRUPT_HANDLER_NMI(func)                             \
384         __visible long func(struct pt_regs *regs)
385
386 /**
387  * DEFINE_INTERRUPT_HANDLER_NMI - Define NMI interrupt handler function
388  * @func:       Function name of the entry point
389  * @returns:    Returns a value back to asm caller
390  *
391  * @func is called from ASM entry code.
392  *
393  * The macro is written so it acts as function definition. Append the
394  * body with a pair of curly brackets.
395  */
396 #define DEFINE_INTERRUPT_HANDLER_NMI(func)                              \
397 static __always_inline long ____##func(struct pt_regs *regs);           \
398                                                                         \
399 interrupt_handler long func(struct pt_regs *regs)                       \
400 {                                                                       \
401         struct interrupt_nmi_state state;                               \
402         long ret;                                                       \
403                                                                         \
404         interrupt_nmi_enter_prepare(regs, &state);                      \
405                                                                         \
406         ret = ____##func (regs);                                        \
407                                                                         \
408         interrupt_nmi_exit_prepare(regs, &state);                       \
409                                                                         \
410         return ret;                                                     \
411 }                                                                       \
412 NOKPROBE_SYMBOL(func);                                                  \
413                                                                         \
414 static __always_inline long ____##func(struct pt_regs *regs)
415
416
417 /* Interrupt handlers */
418 /* kernel/traps.c */
419 DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
420 #ifdef CONFIG_PPC_BOOK3S_64
421 DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception);
422 #else
423 DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
424 #endif
425 DECLARE_INTERRUPT_HANDLER(SMIException);
426 DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
427 DECLARE_INTERRUPT_HANDLER(unknown_exception);
428 DECLARE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception);
429 DECLARE_INTERRUPT_HANDLER(instruction_breakpoint_exception);
430 DECLARE_INTERRUPT_HANDLER(RunModeException);
431 DECLARE_INTERRUPT_HANDLER(single_step_exception);
432 DECLARE_INTERRUPT_HANDLER(program_check_exception);
433 DECLARE_INTERRUPT_HANDLER(emulation_assist_interrupt);
434 DECLARE_INTERRUPT_HANDLER(alignment_exception);
435 DECLARE_INTERRUPT_HANDLER(StackOverflow);
436 DECLARE_INTERRUPT_HANDLER(stack_overflow_exception);
437 DECLARE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception);
438 DECLARE_INTERRUPT_HANDLER(altivec_unavailable_exception);
439 DECLARE_INTERRUPT_HANDLER(vsx_unavailable_exception);
440 DECLARE_INTERRUPT_HANDLER(facility_unavailable_exception);
441 DECLARE_INTERRUPT_HANDLER(fp_unavailable_tm);
442 DECLARE_INTERRUPT_HANDLER(altivec_unavailable_tm);
443 DECLARE_INTERRUPT_HANDLER(vsx_unavailable_tm);
444 DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
445 DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
446 DECLARE_INTERRUPT_HANDLER_RAW(performance_monitor_exception);
447 DECLARE_INTERRUPT_HANDLER(DebugException);
448 DECLARE_INTERRUPT_HANDLER(altivec_assist_exception);
449 DECLARE_INTERRUPT_HANDLER(CacheLockingException);
450 DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException);
451 DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException);
452 DECLARE_INTERRUPT_HANDLER(WatchdogException);
453 DECLARE_INTERRUPT_HANDLER(kernel_bad_stack);
454
455 /* slb.c */
456 DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault);
457 DECLARE_INTERRUPT_HANDLER(do_bad_slb_fault);
458
459 /* hash_utils.c */
460 DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault);
461
462 /* fault.c */
463 DECLARE_INTERRUPT_HANDLER_RET(do_page_fault);
464 DECLARE_INTERRUPT_HANDLER(do_bad_page_fault_segv);
465
466 /* process.c */
467 DECLARE_INTERRUPT_HANDLER(do_break);
468
469 /* time.c */
470 DECLARE_INTERRUPT_HANDLER_ASYNC(timer_interrupt);
471
472 /* mce.c */
473 DECLARE_INTERRUPT_HANDLER_NMI(machine_check_early);
474 DECLARE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode);
475
476 DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException);
477
478 void __noreturn unrecoverable_exception(struct pt_regs *regs);
479
480 void replay_system_reset(void);
481 void replay_soft_interrupts(void);
482
483 static inline void interrupt_cond_local_irq_enable(struct pt_regs *regs)
484 {
485         if (!arch_irq_disabled_regs(regs))
486                 local_irq_enable();
487 }
488
489 #endif /* _ASM_POWERPC_INTERRUPT_H */