From: Reza Arbab <ar...@linux.ibm.com> Signed-off-by: Reza Arbab <ar...@linux.ibm.com> --- arch/powerpc/include/asm/asm-prototypes.h | 1 + arch/powerpc/include/asm/mce.h | 4 ++++ arch/powerpc/kernel/exceptions-64s.S | 4 ++++ arch/powerpc/kernel/mce.c | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+)
diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h index ec1c97a8e8cb..f66f26ef3ce0 100644 --- a/arch/powerpc/include/asm/asm-prototypes.h +++ b/arch/powerpc/include/asm/asm-prototypes.h @@ -72,6 +72,7 @@ void machine_check_exception(struct pt_regs *regs); void emulation_assist_interrupt(struct pt_regs *regs); long do_slb_fault(struct pt_regs *regs, unsigned long ea); void do_bad_slb_fault(struct pt_regs *regs, unsigned long ea, long err); +void machine_check_notify(struct pt_regs *regs); /* signals, syscalls and interrupts */ long sys_swapcontext(struct ucontext __user *old_ctx, diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h index 94888a7025b3..948bef579086 100644 --- a/arch/powerpc/include/asm/mce.h +++ b/arch/powerpc/include/asm/mce.h @@ -214,4 +214,8 @@ unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr, #ifdef CONFIG_PPC_BOOK3S_64 void flush_and_reload_slb(void); #endif /* CONFIG_PPC_BOOK3S_64 */ + +int mce_register_notifier(struct notifier_block *nb); +int mce_unregister_notifier(struct notifier_block *nb); + #endif /* __ASM_PPC64_MCE_H__ */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6b86055e5251..2e56014fca21 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -457,6 +457,10 @@ EXC_COMMON_BEGIN(machine_check_handle_early) addi r3,r1,STACK_FRAME_OVERHEAD bl machine_check_early std r3,RESULT(r1) /* Save result */ + + addi r3,r1,STACK_FRAME_OVERHEAD + bl machine_check_notify + ld r12,_MSR(r1) BEGIN_FTR_SECTION b 4f diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index e78c4f18ea0a..24d350a934e4 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -42,6 +42,18 @@ static struct irq_work mce_event_process_work = { DECLARE_WORK(mce_ue_event_work, machine_process_ue_event); +static BLOCKING_NOTIFIER_HEAD(mce_notifier_list); + +int mce_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&mce_notifier_list, nb); +} + +int mce_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&mce_notifier_list, nb); +} + static void mce_set_error_info(struct machine_check_event *mce, struct mce_error_info *mce_err) { @@ -635,3 +647,13 @@ long hmi_exception_realmode(struct pt_regs *regs) return 1; } + +void machine_check_notify(struct pt_regs *regs) +{ + struct machine_check_event evt; + + if (!get_mce_event(&evt, MCE_EVENT_DONTRELEASE)) + return; + + blocking_notifier_call_chain(&mce_notifier_list, 0, &evt); +} -- 2.20.1