mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 15:44:13 +08:00
powerpc: convert interrupt handlers to use wrappers
Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210130130852.2952424-29-npiggin@gmail.com
This commit is contained in:
parent
fd3f1e0f13
commit
3a96570ffc
@ -56,35 +56,6 @@ int exit_vmx_usercopy(void);
|
|||||||
int enter_vmx_ops(void);
|
int enter_vmx_ops(void);
|
||||||
void *exit_vmx_ops(void *dest);
|
void *exit_vmx_ops(void *dest);
|
||||||
|
|
||||||
/* Traps */
|
|
||||||
long machine_check_early(struct pt_regs *regs);
|
|
||||||
long hmi_exception_realmode(struct pt_regs *regs);
|
|
||||||
void SMIException(struct pt_regs *regs);
|
|
||||||
void handle_hmi_exception(struct pt_regs *regs);
|
|
||||||
void instruction_breakpoint_exception(struct pt_regs *regs);
|
|
||||||
void RunModeException(struct pt_regs *regs);
|
|
||||||
void single_step_exception(struct pt_regs *regs);
|
|
||||||
void program_check_exception(struct pt_regs *regs);
|
|
||||||
void alignment_exception(struct pt_regs *regs);
|
|
||||||
void StackOverflow(struct pt_regs *regs);
|
|
||||||
void stack_overflow_exception(struct pt_regs *regs);
|
|
||||||
void kernel_fp_unavailable_exception(struct pt_regs *regs);
|
|
||||||
void altivec_unavailable_exception(struct pt_regs *regs);
|
|
||||||
void vsx_unavailable_exception(struct pt_regs *regs);
|
|
||||||
void fp_unavailable_tm(struct pt_regs *regs);
|
|
||||||
void altivec_unavailable_tm(struct pt_regs *regs);
|
|
||||||
void vsx_unavailable_tm(struct pt_regs *regs);
|
|
||||||
void facility_unavailable_exception(struct pt_regs *regs);
|
|
||||||
void TAUException(struct pt_regs *regs);
|
|
||||||
void altivec_assist_exception(struct pt_regs *regs);
|
|
||||||
void unrecoverable_exception(struct pt_regs *regs);
|
|
||||||
void kernel_bad_stack(struct pt_regs *regs);
|
|
||||||
void system_reset_exception(struct pt_regs *regs);
|
|
||||||
void machine_check_exception(struct pt_regs *regs);
|
|
||||||
void emulation_assist_interrupt(struct pt_regs *regs);
|
|
||||||
long do_slb_fault(struct pt_regs *regs);
|
|
||||||
void do_bad_slb_fault(struct pt_regs *regs);
|
|
||||||
|
|
||||||
/* signals, syscalls and interrupts */
|
/* signals, syscalls and interrupts */
|
||||||
long sys_swapcontext(struct ucontext __user *old_ctx,
|
long sys_swapcontext(struct ucontext __user *old_ctx,
|
||||||
struct ucontext __user *new_ctx,
|
struct ucontext __user *new_ctx,
|
||||||
|
@ -456,7 +456,6 @@ static inline unsigned long hpt_hash(unsigned long vpn,
|
|||||||
|
|
||||||
long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa,
|
long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa,
|
||||||
unsigned long rlags, unsigned long vflags, int psize, int ssize);
|
unsigned long rlags, unsigned long vflags, int psize, int ssize);
|
||||||
long do_hash_fault(struct pt_regs *regs);
|
|
||||||
extern int __hash_page_4K(unsigned long ea, unsigned long access,
|
extern int __hash_page_4K(unsigned long ea, unsigned long access,
|
||||||
unsigned long vsid, pte_t *ptep, unsigned long trap,
|
unsigned long vsid, pte_t *ptep, unsigned long trap,
|
||||||
unsigned long flags, int ssize, int subpage_prot);
|
unsigned long flags, int ssize, int subpage_prot);
|
||||||
|
@ -50,9 +50,6 @@ bool ppc_breakpoint_available(void);
|
|||||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||||
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
|
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
|
||||||
unsigned long error_code, int brkpt);
|
unsigned long error_code, int brkpt);
|
||||||
#else
|
|
||||||
|
|
||||||
void do_break(struct pt_regs *regs);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_DEBUG_H */
|
#endif /* _ASM_POWERPC_DEBUG_H */
|
||||||
|
@ -50,15 +50,6 @@
|
|||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
extern void replay_system_reset(void);
|
|
||||||
extern void replay_soft_interrupts(void);
|
|
||||||
|
|
||||||
extern void timer_interrupt(struct pt_regs *);
|
|
||||||
extern void performance_monitor_exception(struct pt_regs *regs);
|
|
||||||
extern void WatchdogException(struct pt_regs *regs);
|
|
||||||
extern void unknown_exception(struct pt_regs *regs);
|
|
||||||
void unknown_async_exception(struct pt_regs *regs);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
|
|
||||||
|
@ -232,4 +232,70 @@ __visible noinstr long func(struct pt_regs *regs) \
|
|||||||
\
|
\
|
||||||
static __always_inline long ____##func(struct pt_regs *regs)
|
static __always_inline 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_ASYNC(machine_check_exception);
|
||||||
|
#else
|
||||||
|
DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
|
||||||
|
#endif
|
||||||
|
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(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(unrecoverable_exception);
|
||||||
|
DECLARE_INTERRUPT_HANDLER(WatchdogException);
|
||||||
|
DECLARE_INTERRUPT_HANDLER(kernel_bad_stack);
|
||||||
|
|
||||||
|
/* slb.c */
|
||||||
|
DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault);
|
||||||
|
DECLARE_INTERRUPT_HANDLER(do_bad_slb_fault);
|
||||||
|
|
||||||
|
/* hash_utils.c */
|
||||||
|
DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault);
|
||||||
|
|
||||||
|
/* fault.c */
|
||||||
|
DECLARE_INTERRUPT_HANDLER_RET(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);
|
||||||
|
|
||||||
|
void replay_system_reset(void);
|
||||||
|
void replay_soft_interrupts(void);
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_INTERRUPT_H */
|
#endif /* _ASM_POWERPC_INTERRUPT_H */
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PPC_WATCHDOG
|
#ifdef CONFIG_PPC_WATCHDOG
|
||||||
extern void arch_touch_nmi_watchdog(void);
|
extern void arch_touch_nmi_watchdog(void);
|
||||||
void soft_nmi_interrupt(struct pt_regs *regs);
|
long soft_nmi_interrupt(struct pt_regs *regs);
|
||||||
#else
|
#else
|
||||||
static inline void arch_touch_nmi_watchdog(void) {}
|
static inline void arch_touch_nmi_watchdog(void) {}
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,13 +12,14 @@
|
|||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
|
|
||||||
#include <asm/dbell.h>
|
#include <asm/dbell.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/irq_regs.h>
|
#include <asm/irq_regs.h>
|
||||||
#include <asm/kvm_ppc.h>
|
#include <asm/kvm_ppc.h>
|
||||||
#include <asm/trace.h>
|
#include <asm/trace.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
void doorbell_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
|
||||||
{
|
{
|
||||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||||
|
|
||||||
@ -39,9 +40,8 @@ void doorbell_exception(struct pt_regs *regs)
|
|||||||
set_irq_regs(old_regs);
|
set_irq_regs(old_regs);
|
||||||
}
|
}
|
||||||
#else /* CONFIG_SMP */
|
#else /* CONFIG_SMP */
|
||||||
void doorbell_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
|
||||||
{
|
{
|
||||||
printk(KERN_WARNING "Received doorbell on non-smp system\n");
|
printk(KERN_WARNING "Received doorbell on non-smp system\n");
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include <linux/pgtable.h>
|
#include <linux/pgtable.h>
|
||||||
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
@ -665,7 +666,7 @@ void __do_irq(struct pt_regs *regs)
|
|||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_IRQ(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(do_IRQ)
|
||||||
{
|
{
|
||||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||||
void *cursp, *irqsp, *sirqsp;
|
void *cursp, *irqsp, *sirqsp;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <linux/ftrace.h>
|
#include <linux/ftrace.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
|
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/mce.h>
|
#include <asm/mce.h>
|
||||||
#include <asm/nmi.h>
|
#include <asm/nmi.h>
|
||||||
@ -583,7 +584,7 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info);
|
|||||||
*
|
*
|
||||||
* regs->nip and regs->msr contains srr0 and ssr1.
|
* regs->nip and regs->msr contains srr0 and ssr1.
|
||||||
*/
|
*/
|
||||||
long notrace machine_check_early(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_NMI(machine_check_early)
|
||||||
{
|
{
|
||||||
long handled = 0;
|
long handled = 0;
|
||||||
u8 ftrace_enabled = this_cpu_get_ftrace_enabled();
|
u8 ftrace_enabled = this_cpu_get_ftrace_enabled();
|
||||||
@ -717,7 +718,7 @@ long hmi_handle_debugtrig(struct pt_regs *regs)
|
|||||||
/*
|
/*
|
||||||
* Return values:
|
* Return values:
|
||||||
*/
|
*/
|
||||||
long hmi_exception_realmode(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <linux/pkeys.h>
|
#include <linux/pkeys.h>
|
||||||
#include <linux/seq_buf.h>
|
#include <linux/seq_buf.h>
|
||||||
|
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
@ -659,7 +660,7 @@ static void do_break_handler(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_break(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(do_break)
|
||||||
{
|
{
|
||||||
current->thread.trap_nr = TRAP_HWBKPT;
|
current->thread.trap_nr = TRAP_HWBKPT;
|
||||||
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, regs->dsisr,
|
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, regs->dsisr,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <asm/kup.h>
|
#include <asm/kup.h>
|
||||||
#include <asm/cputime.h>
|
#include <asm/cputime.h>
|
||||||
#include <asm/hw_irq.h>
|
#include <asm/hw_irq.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/kprobes.h>
|
#include <asm/kprobes.h>
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/reg.h>
|
#include <asm/reg.h>
|
||||||
#include <asm/nvram.h>
|
#include <asm/nvram.h>
|
||||||
@ -100,7 +101,7 @@ static void TAUupdate(int cpu)
|
|||||||
* with interrupts disabled
|
* with interrupts disabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TAUException(struct pt_regs * regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include <linux/processor.h>
|
#include <linux/processor.h>
|
||||||
#include <asm/trace.h>
|
#include <asm/trace.h>
|
||||||
|
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/nvram.h>
|
#include <asm/nvram.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
@ -571,7 +572,7 @@ void arch_irq_work_raise(void)
|
|||||||
* timer_interrupt - gets called when the decrementer overflows,
|
* timer_interrupt - gets called when the decrementer overflows,
|
||||||
* with interrupts disabled.
|
* with interrupts disabled.
|
||||||
*/
|
*/
|
||||||
void timer_interrupt(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
|
||||||
{
|
{
|
||||||
struct clock_event_device *evt = this_cpu_ptr(&decrementers);
|
struct clock_event_device *evt = this_cpu_ptr(&decrementers);
|
||||||
u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
|
u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <asm/emulated_ops.h>
|
#include <asm/emulated_ops.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/debugfs.h>
|
#include <asm/debugfs.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
@ -430,8 +431,7 @@ nonrecoverable:
|
|||||||
regs->msr &= ~MSR_RI;
|
regs->msr &= ~MSR_RI;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception)
|
||||||
void system_reset_exception(struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
unsigned long hsrr0, hsrr1;
|
unsigned long hsrr0, hsrr1;
|
||||||
bool saved_hsrrs = false;
|
bool saved_hsrrs = false;
|
||||||
@ -519,6 +519,8 @@ out:
|
|||||||
this_cpu_set_ftrace_enabled(ftrace_enabled);
|
this_cpu_set_ftrace_enabled(ftrace_enabled);
|
||||||
|
|
||||||
/* What should we do here? We could issue a shutdown or hard reset. */
|
/* What should we do here? We could issue a shutdown or hard reset. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(system_reset_exception);
|
NOKPROBE_SYMBOL(system_reset_exception);
|
||||||
|
|
||||||
@ -805,7 +807,11 @@ void die_mce(const char *str, struct pt_regs *regs, long err)
|
|||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(die_mce);
|
NOKPROBE_SYMBOL(die_mce);
|
||||||
|
|
||||||
void machine_check_exception(struct pt_regs *regs)
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
|
DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception)
|
||||||
|
#else
|
||||||
|
DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
int recover = 0;
|
int recover = 0;
|
||||||
|
|
||||||
@ -855,10 +861,16 @@ bail:
|
|||||||
die_mce("Unrecoverable Machine check", regs, SIGBUS);
|
die_mce("Unrecoverable Machine check", regs, SIGBUS);
|
||||||
|
|
||||||
if (nmi) nmi_exit();
|
if (nmi) nmi_exit();
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(machine_check_exception);
|
NOKPROBE_SYMBOL(machine_check_exception);
|
||||||
|
|
||||||
void SMIException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */
|
||||||
{
|
{
|
||||||
die("System Management Interrupt", regs, SIGABRT);
|
die("System Management Interrupt", regs, SIGABRT);
|
||||||
}
|
}
|
||||||
@ -1044,7 +1056,7 @@ static void p9_hmi_special_emu(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_VSX */
|
#endif /* CONFIG_VSX */
|
||||||
|
|
||||||
void handle_hmi_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(handle_hmi_exception)
|
||||||
{
|
{
|
||||||
struct pt_regs *old_regs;
|
struct pt_regs *old_regs;
|
||||||
|
|
||||||
@ -1073,7 +1085,7 @@ void handle_hmi_exception(struct pt_regs *regs)
|
|||||||
set_irq_regs(old_regs);
|
set_irq_regs(old_regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unknown_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(unknown_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1085,7 +1097,7 @@ void unknown_exception(struct pt_regs *regs)
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unknown_async_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1097,7 +1109,7 @@ void unknown_async_exception(struct pt_regs *regs)
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_breakpoint_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(instruction_breakpoint_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1112,12 +1124,12 @@ bail:
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunModeException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(RunModeException)
|
||||||
{
|
{
|
||||||
_exception(SIGTRAP, regs, TRAP_UNK, 0);
|
_exception(SIGTRAP, regs, TRAP_UNK, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void single_step_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(single_step_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1579,7 +1591,7 @@ sigill:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void program_check_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(program_check_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1593,7 +1605,7 @@ NOKPROBE_SYMBOL(program_check_exception);
|
|||||||
* This occurs when running in hypervisor mode on POWER6 or later
|
* This occurs when running in hypervisor mode on POWER6 or later
|
||||||
* and an illegal instruction is encountered.
|
* and an illegal instruction is encountered.
|
||||||
*/
|
*/
|
||||||
void emulation_assist_interrupt(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(emulation_assist_interrupt)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1604,7 +1616,7 @@ void emulation_assist_interrupt(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(emulation_assist_interrupt);
|
NOKPROBE_SYMBOL(emulation_assist_interrupt);
|
||||||
|
|
||||||
void alignment_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(alignment_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
int sig, code, fixed = 0;
|
int sig, code, fixed = 0;
|
||||||
@ -1654,7 +1666,7 @@ bail:
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackOverflow(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(StackOverflow)
|
||||||
{
|
{
|
||||||
pr_crit("Kernel stack overflow in process %s[%d], r1=%lx\n",
|
pr_crit("Kernel stack overflow in process %s[%d], r1=%lx\n",
|
||||||
current->comm, task_pid_nr(current), regs->gpr[1]);
|
current->comm, task_pid_nr(current), regs->gpr[1]);
|
||||||
@ -1663,7 +1675,7 @@ void StackOverflow(struct pt_regs *regs)
|
|||||||
panic("kernel stack overflow");
|
panic("kernel stack overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
void stack_overflow_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(stack_overflow_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1672,7 +1684,7 @@ void stack_overflow_exception(struct pt_regs *regs)
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernel_fp_unavailable_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1683,7 +1695,7 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs)
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void altivec_unavailable_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(altivec_unavailable_exception)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
|
||||||
@ -1702,7 +1714,7 @@ bail:
|
|||||||
exception_exit(prev_state);
|
exception_exit(prev_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vsx_unavailable_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(vsx_unavailable_exception)
|
||||||
{
|
{
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
/* A user program has executed an vsx instruction,
|
/* A user program has executed an vsx instruction,
|
||||||
@ -1733,7 +1745,7 @@ static void tm_unavailable(struct pt_regs *regs)
|
|||||||
die("Unrecoverable TM Unavailable Exception", regs, SIGABRT);
|
die("Unrecoverable TM Unavailable Exception", regs, SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void facility_unavailable_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception)
|
||||||
{
|
{
|
||||||
static char *facility_strings[] = {
|
static char *facility_strings[] = {
|
||||||
[FSCR_FP_LG] = "FPU",
|
[FSCR_FP_LG] = "FPU",
|
||||||
@ -1853,7 +1865,7 @@ out:
|
|||||||
|
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
|
|
||||||
void fp_unavailable_tm(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(fp_unavailable_tm)
|
||||||
{
|
{
|
||||||
/* Note: This does not handle any kind of FP laziness. */
|
/* Note: This does not handle any kind of FP laziness. */
|
||||||
|
|
||||||
@ -1886,7 +1898,7 @@ void fp_unavailable_tm(struct pt_regs *regs)
|
|||||||
tm_recheckpoint(¤t->thread);
|
tm_recheckpoint(¤t->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void altivec_unavailable_tm(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(altivec_unavailable_tm)
|
||||||
{
|
{
|
||||||
/* See the comments in fp_unavailable_tm(). This function operates
|
/* See the comments in fp_unavailable_tm(). This function operates
|
||||||
* the same way.
|
* the same way.
|
||||||
@ -1901,7 +1913,7 @@ void altivec_unavailable_tm(struct pt_regs *regs)
|
|||||||
current->thread.used_vr = 1;
|
current->thread.used_vr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vsx_unavailable_tm(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm)
|
||||||
{
|
{
|
||||||
/* See the comments in fp_unavailable_tm(). This works similarly,
|
/* See the comments in fp_unavailable_tm(). This works similarly,
|
||||||
* though we're loading both FP and VEC registers in here.
|
* though we're loading both FP and VEC registers in here.
|
||||||
@ -1926,7 +1938,9 @@ void vsx_unavailable_tm(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
||||||
|
|
||||||
static void performance_monitor_exception_nmi(struct pt_regs *regs)
|
#ifdef CONFIG_PPC64
|
||||||
|
DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
|
||||||
|
DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
|
||||||
{
|
{
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
|
|
||||||
@ -1935,9 +1949,13 @@ static void performance_monitor_exception_nmi(struct pt_regs *regs)
|
|||||||
perf_irq(regs);
|
perf_irq(regs);
|
||||||
|
|
||||||
nmi_exit();
|
nmi_exit();
|
||||||
}
|
|
||||||
|
|
||||||
static void performance_monitor_exception_async(struct pt_regs *regs)
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
|
||||||
|
DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async)
|
||||||
{
|
{
|
||||||
irq_enter();
|
irq_enter();
|
||||||
|
|
||||||
@ -1948,7 +1966,7 @@ static void performance_monitor_exception_async(struct pt_regs *regs)
|
|||||||
irq_exit();
|
irq_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void performance_monitor_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_RAW(performance_monitor_exception)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* On 64-bit, if perf interrupts hit in a local_irq_disable
|
* On 64-bit, if perf interrupts hit in a local_irq_disable
|
||||||
@ -1960,6 +1978,8 @@ void performance_monitor_exception(struct pt_regs *regs)
|
|||||||
performance_monitor_exception_nmi(regs);
|
performance_monitor_exception_nmi(regs);
|
||||||
else
|
else
|
||||||
performance_monitor_exception_async(regs);
|
performance_monitor_exception_async(regs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
||||||
@ -2022,7 +2042,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
|
|||||||
mtspr(SPRN_DBCR0, current->thread.debug.dbcr0);
|
mtspr(SPRN_DBCR0, current->thread.debug.dbcr0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(DebugException)
|
||||||
{
|
{
|
||||||
unsigned long debug_status = regs->dsisr;
|
unsigned long debug_status = regs->dsisr;
|
||||||
|
|
||||||
@ -2095,7 +2115,7 @@ NOKPROBE_SYMBOL(DebugException);
|
|||||||
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
|
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
|
||||||
|
|
||||||
#ifdef CONFIG_ALTIVEC
|
#ifdef CONFIG_ALTIVEC
|
||||||
void altivec_assist_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(altivec_assist_exception)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -2129,7 +2149,7 @@ void altivec_assist_exception(struct pt_regs *regs)
|
|||||||
#endif /* CONFIG_ALTIVEC */
|
#endif /* CONFIG_ALTIVEC */
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_BOOKE
|
#ifdef CONFIG_FSL_BOOKE
|
||||||
void CacheLockingException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(CacheLockingException)
|
||||||
{
|
{
|
||||||
unsigned long error_code = regs->dsisr;
|
unsigned long error_code = regs->dsisr;
|
||||||
|
|
||||||
@ -2144,7 +2164,7 @@ void CacheLockingException(struct pt_regs *regs)
|
|||||||
#endif /* CONFIG_FSL_BOOKE */
|
#endif /* CONFIG_FSL_BOOKE */
|
||||||
|
|
||||||
#ifdef CONFIG_SPE
|
#ifdef CONFIG_SPE
|
||||||
void SPEFloatingPointException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(SPEFloatingPointException)
|
||||||
{
|
{
|
||||||
extern int do_spe_mathemu(struct pt_regs *regs);
|
extern int do_spe_mathemu(struct pt_regs *regs);
|
||||||
unsigned long spefscr;
|
unsigned long spefscr;
|
||||||
@ -2196,7 +2216,7 @@ void SPEFloatingPointException(struct pt_regs *regs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPEFloatingPointRoundException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(SPEFloatingPointRoundException)
|
||||||
{
|
{
|
||||||
extern int speround_handler(struct pt_regs *regs);
|
extern int speround_handler(struct pt_regs *regs);
|
||||||
int err;
|
int err;
|
||||||
@ -2238,7 +2258,7 @@ void SPEFloatingPointRoundException(struct pt_regs *regs)
|
|||||||
* in the MSR is 0. This indicates that SRR0/1 are live, and that
|
* in the MSR is 0. This indicates that SRR0/1 are live, and that
|
||||||
* we therefore lost state by taking this exception.
|
* we therefore lost state by taking this exception.
|
||||||
*/
|
*/
|
||||||
void unrecoverable_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(unrecoverable_exception)
|
||||||
{
|
{
|
||||||
pr_emerg("Unrecoverable exception %lx at %lx (msr=%lx)\n",
|
pr_emerg("Unrecoverable exception %lx at %lx (msr=%lx)\n",
|
||||||
regs->trap, regs->nip, regs->msr);
|
regs->trap, regs->nip, regs->msr);
|
||||||
@ -2258,7 +2278,7 @@ void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchdogException(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(WatchdogException) /* XXX NMI? async? */
|
||||||
{
|
{
|
||||||
printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
|
printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
|
||||||
WatchdogHandler(regs);
|
WatchdogHandler(regs);
|
||||||
@ -2269,7 +2289,7 @@ void WatchdogException(struct pt_regs *regs)
|
|||||||
* We enter here if we discover during exception entry that we are
|
* We enter here if we discover during exception entry that we are
|
||||||
* running in supervisor mode with a userspace value in the stack pointer.
|
* running in supervisor mode with a userspace value in the stack pointer.
|
||||||
*/
|
*/
|
||||||
void kernel_bad_stack(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(kernel_bad_stack)
|
||||||
{
|
{
|
||||||
printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
|
printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
|
||||||
regs->gpr[1], regs->nip);
|
regs->gpr[1], regs->nip);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
#include <asm/nmi.h>
|
#include <asm/nmi.h>
|
||||||
|
|
||||||
@ -248,14 +249,14 @@ static void watchdog_timer_interrupt(int cpu)
|
|||||||
watchdog_smp_panic(cpu, tb);
|
watchdog_smp_panic(cpu, tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void soft_nmi_interrupt(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int cpu = raw_smp_processor_id();
|
int cpu = raw_smp_processor_id();
|
||||||
u64 tb;
|
u64 tb;
|
||||||
|
|
||||||
if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
|
if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
|
|
||||||
@ -292,6 +293,8 @@ void soft_nmi_interrupt(struct pt_regs *regs)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
nmi_exit();
|
nmi_exit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
|
static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/kvm_ppc.h>
|
#include <asm/kvm_ppc.h>
|
||||||
#include <asm/kvm_book3s.h>
|
#include <asm/kvm_book3s.h>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <asm/asm-prototypes.h>
|
#include <asm/asm-prototypes.h>
|
||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/kvm_ppc.h>
|
#include <asm/kvm_ppc.h>
|
||||||
#include <asm/kvm_book3s.h>
|
#include <asm/kvm_book3s.h>
|
||||||
#include <asm/archrandom.h>
|
#include <asm/archrandom.h>
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/kvm_ppc.h>
|
#include <asm/kvm_ppc.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/dbell.h>
|
#include <asm/dbell.h>
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <linux/pgtable.h>
|
#include <linux/pgtable.h>
|
||||||
|
|
||||||
#include <asm/debugfs.h>
|
#include <asm/debugfs.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
@ -1512,7 +1513,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hash_page);
|
EXPORT_SYMBOL_GPL(hash_page);
|
||||||
|
|
||||||
static long __do_hash_fault(struct pt_regs *regs)
|
DECLARE_INTERRUPT_HANDLER_RET(__do_hash_fault);
|
||||||
|
DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
|
||||||
{
|
{
|
||||||
unsigned long ea = regs->dar;
|
unsigned long ea = regs->dar;
|
||||||
unsigned long dsisr = regs->dsisr;
|
unsigned long dsisr = regs->dsisr;
|
||||||
@ -1565,7 +1567,11 @@ static long __do_hash_fault(struct pt_regs *regs)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
long do_hash_fault(struct pt_regs *regs)
|
/*
|
||||||
|
* The _RAW interrupt entry checks for the in_nmi() case before
|
||||||
|
* running the full handler.
|
||||||
|
*/
|
||||||
|
DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault)
|
||||||
{
|
{
|
||||||
unsigned long dsisr = regs->dsisr;
|
unsigned long dsisr = regs->dsisr;
|
||||||
long err;
|
long err;
|
||||||
@ -1587,7 +1593,7 @@ long do_hash_fault(struct pt_regs *regs)
|
|||||||
* the access, or panic if there isn't a handler.
|
* the access, or panic if there isn't a handler.
|
||||||
*/
|
*/
|
||||||
if (unlikely(in_nmi())) {
|
if (unlikely(in_nmi())) {
|
||||||
bad_page_fault(regs, SIGSEGV);
|
do_bad_page_fault_segv(regs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/asm-prototypes.h>
|
#include <asm/asm-prototypes.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
@ -813,7 +814,7 @@ static long slb_allocate_user(struct mm_struct *mm, unsigned long ea)
|
|||||||
return slb_insert_entry(ea, context, flags, ssize, false);
|
return slb_insert_entry(ea, context, flags, ssize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
long do_slb_fault(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_RAW(do_slb_fault)
|
||||||
{
|
{
|
||||||
unsigned long ea = regs->dar;
|
unsigned long ea = regs->dar;
|
||||||
unsigned long id = get_region_id(ea);
|
unsigned long id = get_region_id(ea);
|
||||||
@ -833,7 +834,7 @@ long do_slb_fault(struct pt_regs *regs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The interrupt state is not reconciled, for performance, so that
|
* This is a raw interrupt handler, for performance, so that
|
||||||
* fast_interrupt_return can be used. The handler must not touch local
|
* fast_interrupt_return can be used. The handler must not touch local
|
||||||
* irq state, or schedule. We could test for usermode and upgrade to a
|
* irq state, or schedule. We could test for usermode and upgrade to a
|
||||||
* normal process context (synchronous) interrupt for those, which
|
* normal process context (synchronous) interrupt for those, which
|
||||||
@ -868,7 +869,7 @@ long do_slb_fault(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_bad_slb_fault(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(do_bad_slb_fault)
|
||||||
{
|
{
|
||||||
int err = regs->result;
|
int err = regs->result;
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
@ -540,7 +541,7 @@ retry:
|
|||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(__do_page_fault);
|
NOKPROBE_SYMBOL(__do_page_fault);
|
||||||
|
|
||||||
long do_page_fault(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER_RET(do_page_fault)
|
||||||
{
|
{
|
||||||
const struct exception_table_entry *entry;
|
const struct exception_table_entry *entry;
|
||||||
enum ctx_state prev_state;
|
enum ctx_state prev_state;
|
||||||
@ -624,7 +625,7 @@ void bad_page_fault(struct pt_regs *regs, int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_BOOK3S_64
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
void do_bad_page_fault_segv(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(do_bad_page_fault_segv)
|
||||||
{
|
{
|
||||||
bad_page_fault(regs, SIGSEGV);
|
bad_page_fault(regs, SIGSEGV);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ static void dump_fir(int cpu)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbe_system_error_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(cbe_system_error_exception)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ void cbe_system_error_exception(struct pt_regs *regs)
|
|||||||
dump_stack();
|
dump_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbe_maintenance_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(cbe_maintenance_exception)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ void cbe_maintenance_exception(struct pt_regs *regs)
|
|||||||
dump_stack();
|
dump_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbe_thermal_exception(struct pt_regs *regs)
|
DEFINE_INTERRUPT_HANDLER(cbe_thermal_exception)
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
#ifndef RAS_H
|
#ifndef RAS_H
|
||||||
#define RAS_H
|
#define RAS_H
|
||||||
|
|
||||||
extern void cbe_system_error_exception(struct pt_regs *regs);
|
#include <asm/interrupt.h>
|
||||||
extern void cbe_maintenance_exception(struct pt_regs *regs);
|
|
||||||
extern void cbe_thermal_exception(struct pt_regs *regs);
|
DECLARE_INTERRUPT_HANDLER(cbe_system_error_exception);
|
||||||
|
DECLARE_INTERRUPT_HANDLER(cbe_maintenance_exception);
|
||||||
|
DECLARE_INTERRUPT_HANDLER(cbe_thermal_exception);
|
||||||
|
|
||||||
extern void cbe_ras_init(void);
|
extern void cbe_ras_init(void);
|
||||||
|
|
||||||
#endif /* RAS_H */
|
#endif /* RAS_H */
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <asm/asm-prototypes.h>
|
#include <asm/asm-prototypes.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
|
#include <asm/interrupt.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/opal.h>
|
#include <asm/opal.h>
|
||||||
#include <asm/cputhreads.h>
|
#include <asm/cputhreads.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user