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