1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _ASM_POWERPC_INTERRUPT_H
3 #define _ASM_POWERPC_INTERRUPT_H
4 
5 /* BookE/4xx */
6 #define INTERRUPT_CRITICAL_INPUT  0x100
7 
8 /* BookE */
9 #define INTERRUPT_DEBUG           0xd00
10 #ifdef CONFIG_BOOKE
11 #define INTERRUPT_PERFMON         0x260
12 #define INTERRUPT_DOORBELL        0x280
13 #endif
14 
15 /* BookS/4xx/8xx */
16 #define INTERRUPT_MACHINE_CHECK   0x200
17 
18 /* BookS/8xx */
19 #define INTERRUPT_SYSTEM_RESET    0x100
20 
21 /* BookS */
22 #define INTERRUPT_DATA_SEGMENT    0x380
23 #define INTERRUPT_INST_SEGMENT    0x480
24 #define INTERRUPT_TRACE           0xd00
25 #define INTERRUPT_H_DATA_STORAGE  0xe00
26 #define INTERRUPT_HMI			0xe60
27 #define INTERRUPT_H_FAC_UNAVAIL   0xf80
28 #ifdef CONFIG_PPC_BOOK3S
29 #define INTERRUPT_DOORBELL        0xa00
30 #define INTERRUPT_PERFMON         0xf00
31 #define INTERRUPT_ALTIVEC_UNAVAIL	0xf20
32 #endif
33 
34 /* BookE/BookS/4xx/8xx */
35 #define INTERRUPT_DATA_STORAGE    0x300
36 #define INTERRUPT_INST_STORAGE    0x400
37 #define INTERRUPT_EXTERNAL		0x500
38 #define INTERRUPT_ALIGNMENT       0x600
39 #define INTERRUPT_PROGRAM         0x700
40 #define INTERRUPT_SYSCALL         0xc00
41 #define INTERRUPT_TRACE			0xd00
42 
43 /* BookE/BookS/44x */
44 #define INTERRUPT_FP_UNAVAIL      0x800
45 
46 /* BookE/BookS/44x/8xx */
47 #define INTERRUPT_DECREMENTER     0x900
48 
49 #ifndef INTERRUPT_PERFMON
50 #define INTERRUPT_PERFMON         0x0
51 #endif
52 
53 /* 8xx */
54 #define INTERRUPT_SOFT_EMU_8xx		0x1000
55 #define INTERRUPT_INST_TLB_MISS_8xx	0x1100
56 #define INTERRUPT_DATA_TLB_MISS_8xx	0x1200
57 #define INTERRUPT_INST_TLB_ERROR_8xx	0x1300
58 #define INTERRUPT_DATA_TLB_ERROR_8xx	0x1400
59 #define INTERRUPT_DATA_BREAKPOINT_8xx	0x1c00
60 #define INTERRUPT_INST_BREAKPOINT_8xx	0x1d00
61 
62 /* 603 */
63 #define INTERRUPT_INST_TLB_MISS_603		0x1000
64 #define INTERRUPT_DATA_LOAD_TLB_MISS_603	0x1100
65 #define INTERRUPT_DATA_STORE_TLB_MISS_603	0x1200
66 
67 #ifndef __ASSEMBLY__
68 
69 #include <linux/context_tracking.h>
70 #include <linux/hardirq.h>
71 #include <asm/cputime.h>
72 #include <asm/ftrace.h>
73 #include <asm/kprobes.h>
74 #include <asm/runlatch.h>
75 
76 #ifdef CONFIG_PPC_BOOK3S_64
77 extern char __end_soft_masked[];
78 bool search_kernel_soft_mask_table(unsigned long addr);
79 unsigned long search_kernel_restart_table(unsigned long addr);
80 
81 DECLARE_STATIC_KEY_FALSE(interrupt_exit_not_reentrant);
82 
83 static inline bool is_implicit_soft_masked(struct pt_regs *regs)
84 {
85 	if (regs->msr & MSR_PR)
86 		return false;
87 
88 	if (regs->nip >= (unsigned long)__end_soft_masked)
89 		return false;
90 
91 	return search_kernel_soft_mask_table(regs->nip);
92 }
93 
94 static inline void srr_regs_clobbered(void)
95 {
96 	local_paca->srr_valid = 0;
97 	local_paca->hsrr_valid = 0;
98 }
99 #else
100 static inline bool is_implicit_soft_masked(struct pt_regs *regs)
101 {
102 	return false;
103 }
104 
105 static inline void srr_regs_clobbered(void)
106 {
107 }
108 #endif
109 
110 static inline void nap_adjust_return(struct pt_regs *regs)
111 {
112 #ifdef CONFIG_PPC_970_NAP
113 	if (unlikely(test_thread_local_flags(_TLF_NAPPING))) {
114 		/* Can avoid a test-and-clear because NMIs do not call this */
115 		clear_thread_local_flags(_TLF_NAPPING);
116 		regs_set_return_ip(regs, (unsigned long)power4_idle_nap_return);
117 	}
118 #endif
119 }
120 
121 struct interrupt_state {
122 };
123 
124 static inline void booke_restore_dbcr0(void)
125 {
126 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
127 	unsigned long dbcr0 = current->thread.debug.dbcr0;
128 
129 	if (IS_ENABLED(CONFIG_PPC32) && unlikely(dbcr0 & DBCR0_IDM)) {
130 		mtspr(SPRN_DBSR, -1);
131 		mtspr(SPRN_DBCR0, global_dbcr0[smp_processor_id()]);
132 	}
133 #endif
134 }
135 
136 static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
137 {
138 #ifdef CONFIG_PPC32
139 	if (!arch_irq_disabled_regs(regs))
140 		trace_hardirqs_off();
141 
142 	if (user_mode(regs))
143 		kuap_lock();
144 	else
145 		kuap_save_and_lock(regs);
146 
147 	if (user_mode(regs))
148 		account_cpu_user_entry();
149 #endif
150 
151 #ifdef CONFIG_PPC64
152 	bool trace_enable = false;
153 
154 	if (IS_ENABLED(CONFIG_TRACE_IRQFLAGS)) {
155 		if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
156 			trace_enable = true;
157 	} else {
158 		irq_soft_mask_set(IRQS_ALL_DISABLED);
159 	}
160 
161 	/*
162 	 * If the interrupt was taken with HARD_DIS clear, then enable MSR[EE].
163 	 * Asynchronous interrupts get here with HARD_DIS set (see below), so
164 	 * this enables MSR[EE] for synchronous interrupts. IRQs remain
165 	 * soft-masked. The interrupt handler may later call
166 	 * interrupt_cond_local_irq_enable() to achieve a regular process
167 	 * context.
168 	 */
169 	if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) {
170 		if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
171 			BUG_ON(!(regs->msr & MSR_EE));
172 		__hard_irq_enable();
173 	} else {
174 		__hard_RI_enable();
175 	}
176 
177 	/* Do this when RI=1 because it can cause SLB faults */
178 	if (trace_enable)
179 		trace_hardirqs_off();
180 
181 	if (user_mode(regs)) {
182 		kuap_lock();
183 		CT_WARN_ON(ct_state() != CONTEXT_USER);
184 		user_exit_irqoff();
185 
186 		account_cpu_user_entry();
187 		account_stolen_time();
188 	} else {
189 		kuap_save_and_lock(regs);
190 		/*
191 		 * CT_WARN_ON comes here via program_check_exception,
192 		 * so avoid recursion.
193 		 */
194 		if (TRAP(regs) != INTERRUPT_PROGRAM) {
195 			CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
196 			BUG_ON(is_implicit_soft_masked(regs));
197 		}
198 #ifdef CONFIG_PPC_BOOK3S
199 		/* Move this under a debugging check */
200 		if (arch_irq_disabled_regs(regs))
201 			BUG_ON(search_kernel_restart_table(regs->nip));
202 #endif
203 	}
204 	if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
205 		BUG_ON(!arch_irq_disabled_regs(regs) && !(regs->msr & MSR_EE));
206 #endif
207 
208 	booke_restore_dbcr0();
209 }
210 
211 /*
212  * Care should be taken to note that interrupt_exit_prepare and
213  * interrupt_async_exit_prepare do not necessarily return immediately to
214  * regs context (e.g., if regs is usermode, we don't necessarily return to
215  * user mode). Other interrupts might be taken between here and return,
216  * context switch / preemption may occur in the exit path after this, or a
217  * signal may be delivered, etc.
218  *
219  * The real interrupt exit code is platform specific, e.g.,
220  * interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64s.
221  *
222  * However interrupt_nmi_exit_prepare does return directly to regs, because
223  * NMIs do not do "exit work" or replay soft-masked interrupts.
224  */
225 static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
226 {
227 }
228 
229 static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
230 {
231 #ifdef CONFIG_PPC64
232 	/* Ensure interrupt_enter_prepare does not enable MSR[EE] */
233 	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
234 #endif
235 	interrupt_enter_prepare(regs, state);
236 #ifdef CONFIG_PPC_BOOK3S_64
237 	/*
238 	 * RI=1 is set by interrupt_enter_prepare, so this thread flags access
239 	 * has to come afterward (it can cause SLB faults).
240 	 */
241 	if (cpu_has_feature(CPU_FTR_CTRL) &&
242 	    !test_thread_local_flags(_TLF_RUNLATCH))
243 		__ppc64_runlatch_on();
244 #endif
245 	irq_enter();
246 }
247 
248 static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct interrupt_state *state)
249 {
250 	/*
251 	 * Adjust at exit so the main handler sees the true NIA. This must
252 	 * come before irq_exit() because irq_exit can enable interrupts, and
253 	 * if another interrupt is taken before nap_adjust_return has run
254 	 * here, then that interrupt would return directly to idle nap return.
255 	 */
256 	nap_adjust_return(regs);
257 
258 	irq_exit();
259 	interrupt_exit_prepare(regs, state);
260 }
261 
262 struct interrupt_nmi_state {
263 #ifdef CONFIG_PPC64
264 	u8 irq_soft_mask;
265 	u8 irq_happened;
266 	u8 ftrace_enabled;
267 	u64 softe;
268 #endif
269 };
270 
271 static inline bool nmi_disables_ftrace(struct pt_regs *regs)
272 {
273 	/* Allow DEC and PMI to be traced when they are soft-NMI */
274 	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
275 		if (TRAP(regs) == INTERRUPT_DECREMENTER)
276 		       return false;
277 		if (TRAP(regs) == INTERRUPT_PERFMON)
278 		       return false;
279 	}
280 	if (IS_ENABLED(CONFIG_PPC_BOOK3E)) {
281 		if (TRAP(regs) == INTERRUPT_PERFMON)
282 			return false;
283 	}
284 
285 	return true;
286 }
287 
288 static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
289 {
290 #ifdef CONFIG_PPC64
291 	state->irq_soft_mask = local_paca->irq_soft_mask;
292 	state->irq_happened = local_paca->irq_happened;
293 	state->softe = regs->softe;
294 
295 	/*
296 	 * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
297 	 * the right thing, and set IRQ_HARD_DIS. We do not want to reconcile
298 	 * because that goes through irq tracing which we don't want in NMI.
299 	 */
300 	local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
301 	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
302 
303 	if (!(regs->msr & MSR_EE) || is_implicit_soft_masked(regs)) {
304 		/*
305 		 * Adjust regs->softe to be soft-masked if it had not been
306 		 * reconcied (e.g., interrupt entry with MSR[EE]=0 but softe
307 		 * not yet set disabled), or if it was in an implicit soft
308 		 * masked state. This makes arch_irq_disabled_regs(regs)
309 		 * behave as expected.
310 		 */
311 		regs->softe = IRQS_ALL_DISABLED;
312 	}
313 
314 	__hard_RI_enable();
315 
316 	/* Don't do any per-CPU operations until interrupt state is fixed */
317 
318 	if (nmi_disables_ftrace(regs)) {
319 		state->ftrace_enabled = this_cpu_get_ftrace_enabled();
320 		this_cpu_set_ftrace_enabled(0);
321 	}
322 #endif
323 
324 	/*
325 	 * Do not use nmi_enter() for pseries hash guest taking a real-mode
326 	 * NMI because not everything it touches is within the RMA limit.
327 	 */
328 	if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) ||
329 			!firmware_has_feature(FW_FEATURE_LPAR) ||
330 			radix_enabled() || (mfmsr() & MSR_DR))
331 		nmi_enter();
332 }
333 
334 static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
335 {
336 	if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) ||
337 			!firmware_has_feature(FW_FEATURE_LPAR) ||
338 			radix_enabled() || (mfmsr() & MSR_DR))
339 		nmi_exit();
340 
341 	/*
342 	 * nmi does not call nap_adjust_return because nmi should not create
343 	 * new work to do (must use irq_work for that).
344 	 */
345 
346 #ifdef CONFIG_PPC64
347 #ifdef CONFIG_PPC_BOOK3S
348 	if (arch_irq_disabled_regs(regs)) {
349 		unsigned long rst = search_kernel_restart_table(regs->nip);
350 		if (rst)
351 			regs_set_return_ip(regs, rst);
352 	}
353 #endif
354 
355 	if (nmi_disables_ftrace(regs))
356 		this_cpu_set_ftrace_enabled(state->ftrace_enabled);
357 
358 	/* Check we didn't change the pending interrupt mask. */
359 	WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != local_paca->irq_happened);
360 	regs->softe = state->softe;
361 	local_paca->irq_happened = state->irq_happened;
362 	local_paca->irq_soft_mask = state->irq_soft_mask;
363 #endif
364 }
365 
366 /*
367  * Don't use noinstr here like x86, but rather add NOKPROBE_SYMBOL to each
368  * function definition. The reason for this is the noinstr section is placed
369  * after the main text section, i.e., very far away from the interrupt entry
370  * asm. That creates problems with fitting linker stubs when building large
371  * kernels.
372  */
373 #define interrupt_handler __visible noinline notrace __no_kcsan __no_sanitize_address
374 
375 /**
376  * DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function
377  * @func:	Function name of the entry point
378  * @returns:	Returns a value back to asm caller
379  */
380 #define DECLARE_INTERRUPT_HANDLER_RAW(func)				\
381 	__visible long func(struct pt_regs *regs)
382 
383 /**
384  * DEFINE_INTERRUPT_HANDLER_RAW - Define raw interrupt handler function
385  * @func:	Function name of the entry point
386  * @returns:	Returns a value back to asm caller
387  *
388  * @func is called from ASM entry code.
389  *
390  * This is a plain function which does no tracing, reconciling, etc.
391  * The macro is written so it acts as function definition. Append the
392  * body with a pair of curly brackets.
393  *
394  * raw interrupt handlers must not enable or disable interrupts, or
395  * schedule, tracing and instrumentation (ftrace, lockdep, etc) would
396  * not be advisable either, although may be possible in a pinch, the
397  * trace will look odd at least.
398  *
399  * A raw handler may call one of the other interrupt handler functions
400  * to be converted into that interrupt context without these restrictions.
401  *
402  * On PPC64, _RAW handlers may return with fast_interrupt_return.
403  *
404  * Specific handlers may have additional restrictions.
405  */
406 #define DEFINE_INTERRUPT_HANDLER_RAW(func)				\
407 static __always_inline long ____##func(struct pt_regs *regs);		\
408 									\
409 interrupt_handler long func(struct pt_regs *regs)			\
410 {									\
411 	long ret;							\
412 									\
413 	__hard_RI_enable();						\
414 									\
415 	ret = ____##func (regs);					\
416 									\
417 	return ret;							\
418 }									\
419 NOKPROBE_SYMBOL(func);							\
420 									\
421 static __always_inline long ____##func(struct pt_regs *regs)
422 
423 /**
424  * DECLARE_INTERRUPT_HANDLER - Declare synchronous interrupt handler function
425  * @func:	Function name of the entry point
426  */
427 #define DECLARE_INTERRUPT_HANDLER(func)					\
428 	__visible void func(struct pt_regs *regs)
429 
430 /**
431  * DEFINE_INTERRUPT_HANDLER - Define synchronous interrupt handler function
432  * @func:	Function name of the entry point
433  *
434  * @func is called from ASM entry code.
435  *
436  * The macro is written so it acts as function definition. Append the
437  * body with a pair of curly brackets.
438  */
439 #define DEFINE_INTERRUPT_HANDLER(func)					\
440 static __always_inline void ____##func(struct pt_regs *regs);		\
441 									\
442 interrupt_handler void func(struct pt_regs *regs)			\
443 {									\
444 	struct interrupt_state state;					\
445 									\
446 	interrupt_enter_prepare(regs, &state);				\
447 									\
448 	____##func (regs);						\
449 									\
450 	interrupt_exit_prepare(regs, &state);				\
451 }									\
452 NOKPROBE_SYMBOL(func);							\
453 									\
454 static __always_inline void ____##func(struct pt_regs *regs)
455 
456 /**
457  * DECLARE_INTERRUPT_HANDLER_RET - Declare synchronous interrupt handler function
458  * @func:	Function name of the entry point
459  * @returns:	Returns a value back to asm caller
460  */
461 #define DECLARE_INTERRUPT_HANDLER_RET(func)				\
462 	__visible long func(struct pt_regs *regs)
463 
464 /**
465  * DEFINE_INTERRUPT_HANDLER_RET - Define synchronous interrupt handler function
466  * @func:	Function name of the entry point
467  * @returns:	Returns a value back to asm caller
468  *
469  * @func is called from ASM entry code.
470  *
471  * The macro is written so it acts as function definition. Append the
472  * body with a pair of curly brackets.
473  */
474 #define DEFINE_INTERRUPT_HANDLER_RET(func)				\
475 static __always_inline long ____##func(struct pt_regs *regs);		\
476 									\
477 interrupt_handler long func(struct pt_regs *regs)			\
478 {									\
479 	struct interrupt_state state;					\
480 	long ret;							\
481 									\
482 	interrupt_enter_prepare(regs, &state);				\
483 									\
484 	ret = ____##func (regs);					\
485 									\
486 	interrupt_exit_prepare(regs, &state);				\
487 									\
488 	return ret;							\
489 }									\
490 NOKPROBE_SYMBOL(func);							\
491 									\
492 static __always_inline long ____##func(struct pt_regs *regs)
493 
494 /**
495  * DECLARE_INTERRUPT_HANDLER_ASYNC - Declare asynchronous interrupt handler function
496  * @func:	Function name of the entry point
497  */
498 #define DECLARE_INTERRUPT_HANDLER_ASYNC(func)				\
499 	__visible void func(struct pt_regs *regs)
500 
501 /**
502  * DEFINE_INTERRUPT_HANDLER_ASYNC - Define asynchronous interrupt handler function
503  * @func:	Function name of the entry point
504  *
505  * @func is called from ASM entry code.
506  *
507  * The macro is written so it acts as function definition. Append the
508  * body with a pair of curly brackets.
509  */
510 #define DEFINE_INTERRUPT_HANDLER_ASYNC(func)				\
511 static __always_inline void ____##func(struct pt_regs *regs);		\
512 									\
513 interrupt_handler void func(struct pt_regs *regs)			\
514 {									\
515 	struct interrupt_state state;					\
516 									\
517 	interrupt_async_enter_prepare(regs, &state);			\
518 									\
519 	____##func (regs);						\
520 									\
521 	interrupt_async_exit_prepare(regs, &state);			\
522 }									\
523 NOKPROBE_SYMBOL(func);							\
524 									\
525 static __always_inline void ____##func(struct pt_regs *regs)
526 
527 /**
528  * DECLARE_INTERRUPT_HANDLER_NMI - Declare NMI interrupt handler function
529  * @func:	Function name of the entry point
530  * @returns:	Returns a value back to asm caller
531  */
532 #define DECLARE_INTERRUPT_HANDLER_NMI(func)				\
533 	__visible long func(struct pt_regs *regs)
534 
535 /**
536  * DEFINE_INTERRUPT_HANDLER_NMI - Define NMI interrupt handler function
537  * @func:	Function name of the entry point
538  * @returns:	Returns a value back to asm caller
539  *
540  * @func is called from ASM entry code.
541  *
542  * The macro is written so it acts as function definition. Append the
543  * body with a pair of curly brackets.
544  */
545 #define DEFINE_INTERRUPT_HANDLER_NMI(func)				\
546 static __always_inline long ____##func(struct pt_regs *regs);		\
547 									\
548 interrupt_handler long func(struct pt_regs *regs)			\
549 {									\
550 	struct interrupt_nmi_state state;				\
551 	long ret;							\
552 									\
553 	interrupt_nmi_enter_prepare(regs, &state);			\
554 									\
555 	ret = ____##func (regs);					\
556 									\
557 	interrupt_nmi_exit_prepare(regs, &state);			\
558 									\
559 	return ret;							\
560 }									\
561 NOKPROBE_SYMBOL(func);							\
562 									\
563 static __always_inline long ____##func(struct pt_regs *regs)
564 
565 
566 /* Interrupt handlers */
567 /* kernel/traps.c */
568 DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
569 #ifdef CONFIG_PPC_BOOK3S_64
570 DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async);
571 #endif
572 DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
573 DECLARE_INTERRUPT_HANDLER(SMIException);
574 DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
575 DECLARE_INTERRUPT_HANDLER(unknown_exception);
576 DECLARE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception);
577 DECLARE_INTERRUPT_HANDLER_NMI(unknown_nmi_exception);
578 DECLARE_INTERRUPT_HANDLER(instruction_breakpoint_exception);
579 DECLARE_INTERRUPT_HANDLER(RunModeException);
580 DECLARE_INTERRUPT_HANDLER(single_step_exception);
581 DECLARE_INTERRUPT_HANDLER(program_check_exception);
582 DECLARE_INTERRUPT_HANDLER(emulation_assist_interrupt);
583 DECLARE_INTERRUPT_HANDLER(alignment_exception);
584 DECLARE_INTERRUPT_HANDLER(StackOverflow);
585 DECLARE_INTERRUPT_HANDLER(stack_overflow_exception);
586 DECLARE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception);
587 DECLARE_INTERRUPT_HANDLER(altivec_unavailable_exception);
588 DECLARE_INTERRUPT_HANDLER(vsx_unavailable_exception);
589 DECLARE_INTERRUPT_HANDLER(facility_unavailable_exception);
590 DECLARE_INTERRUPT_HANDLER(fp_unavailable_tm);
591 DECLARE_INTERRUPT_HANDLER(altivec_unavailable_tm);
592 DECLARE_INTERRUPT_HANDLER(vsx_unavailable_tm);
593 DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
594 DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
595 DECLARE_INTERRUPT_HANDLER_RAW(performance_monitor_exception);
596 DECLARE_INTERRUPT_HANDLER(DebugException);
597 DECLARE_INTERRUPT_HANDLER(altivec_assist_exception);
598 DECLARE_INTERRUPT_HANDLER(CacheLockingException);
599 DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException);
600 DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException);
601 DECLARE_INTERRUPT_HANDLER_NMI(WatchdogException);
602 DECLARE_INTERRUPT_HANDLER(kernel_bad_stack);
603 
604 /* slb.c */
605 DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault);
606 DECLARE_INTERRUPT_HANDLER(do_bad_segment_interrupt);
607 
608 /* hash_utils.c */
609 DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault);
610 
611 /* fault.c */
612 DECLARE_INTERRUPT_HANDLER(do_page_fault);
613 DECLARE_INTERRUPT_HANDLER(do_bad_page_fault_segv);
614 
615 /* process.c */
616 DECLARE_INTERRUPT_HANDLER(do_break);
617 
618 /* time.c */
619 DECLARE_INTERRUPT_HANDLER_ASYNC(timer_interrupt);
620 
621 /* mce.c */
622 DECLARE_INTERRUPT_HANDLER_NMI(machine_check_early);
623 DECLARE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode);
624 
625 DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException);
626 
627 /* irq.c */
628 DECLARE_INTERRUPT_HANDLER_ASYNC(do_IRQ);
629 
630 void __noreturn unrecoverable_exception(struct pt_regs *regs);
631 
632 void replay_system_reset(void);
633 void replay_soft_interrupts(void);
634 
635 static inline void interrupt_cond_local_irq_enable(struct pt_regs *regs)
636 {
637 	if (!arch_irq_disabled_regs(regs))
638 		local_irq_enable();
639 }
640 
641 #endif /* __ASSEMBLY__ */
642 
643 #endif /* _ASM_POWERPC_INTERRUPT_H */
644