diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h index a2b8c7b35fbaf040243e3d4678e7a8264a9f038d..8e99edf6d966d8129a7c1e3feef84334fba2b250 100644 --- a/arch/powerpc/include/asm/mce.h +++ b/arch/powerpc/include/asm/mce.h @@ -191,7 +191,6 @@ extern void save_mce_event(struct pt_regs *regs, long handled, extern int get_mce_event(struct machine_check_event *mce, bool release); extern void release_mce_event(void); extern void machine_check_queue_event(void); -extern void machine_check_process_queued_event(void); extern void machine_check_print_event_info(struct machine_check_event *evt); extern uint64_t get_mce_fault_addr(struct machine_check_event *evt); diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 770d6d65c47b62b1d101021ec0e4b063226606dc..bbfb0294b3544072ac22b2fcfee486620ae1479e 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -183,11 +183,6 @@ syscall_exit: #ifdef SHOW_SYSCALLS bl .do_show_syscall_exit ld r3,RESULT(r1) -#endif -#ifdef CONFIG_PPC_BOOK3S_64 -BEGIN_FTR_SECTION - bl .machine_check_process_queued_event -END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) #endif CURRENT_THREAD_INFO(r12, r1) diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index c0c52ec1fca7002b996e5b9e60f036a6f55e5f90..cadef7e64e4245e816f0878c63ebab43855c15c2 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -26,6 +26,7 @@ #include #include #include +#include #include static DEFINE_PER_CPU(int, mce_nest_count); @@ -35,6 +36,11 @@ static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT], mce_event); static DEFINE_PER_CPU(int, mce_queue_count); static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT], mce_event_queue); +static void machine_check_process_queued_event(struct irq_work *work); +struct irq_work mce_event_process_work = { + .func = machine_check_process_queued_event, +}; + static void mce_set_error_info(struct machine_check_event *mce, struct mce_error_info *mce_err) { @@ -185,17 +191,19 @@ void machine_check_queue_event(void) return; } __get_cpu_var(mce_event_queue[index]) = evt; + + /* Queue irq work to process this event later. */ + irq_work_queue(&mce_event_process_work); } /* * process pending MCE event from the mce event queue. This function will be * called during syscall exit. */ -void machine_check_process_queued_event(void) +static void machine_check_process_queued_event(struct irq_work *work) { int index; - preempt_disable(); /* * For now just print it to console. * TODO: log this error event to FSP or nvram. @@ -206,7 +214,6 @@ void machine_check_process_queued_event(void) &__get_cpu_var(mce_event_queue[index])); __get_cpu_var(mce_queue_count)--; } - preempt_enable(); } void machine_check_print_event_info(struct machine_check_event *evt)