[v2 03/12] powerpc/mce: Add MCE notification chain
From: Santosh Sivaraj <hidden>
Date: 2019-07-02 06:39:12
Subsystem:
linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Linus Torvalds
From: Reza Arbab <redacted> Signed-off-by: Reza Arbab <redacted> --- 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