--- v6
+++ v4
@@ -1,99 +1,121 @@
-As explained by commit daf00ae71dad ("powerpc/traps: restore
-recoverability of machine_check interrupts"), die() can't be called from
-within nmi_enter to nicely kill a process context that was interrupted.
-nmi_exit must be called first.
-
-This adds a function die_mce which takes care of this for machine check
-handlers.
+There is no need for this to be in asm, use the new intrrupt entry wrapper.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
- arch/powerpc/include/asm/bug.h | 1 +
- arch/powerpc/kernel/traps.c | 21 +++++++++++++++------
- arch/powerpc/platforms/powernv/opal.c | 2 +-
- arch/powerpc/platforms/pseries/ras.c | 2 +-
- 4 files changed, 18 insertions(+), 8 deletions(-)
+ arch/powerpc/include/asm/interrupt.h | 7 +++++++
+ arch/powerpc/kernel/exceptions-64s.S | 18 ------------------
+ 2 files changed, 7 insertions(+), 18 deletions(-)
-diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
-index 8f09ddae9305..c10ae0a9bbaf 100644
---- a/arch/powerpc/include/asm/bug.h
-+++ b/arch/powerpc/include/asm/bug.h
-@@ -118,6 +118,7 @@ void do_bad_page_fault_segv(struct pt_regs *regs);
- extern void _exception(int, struct pt_regs *, int, unsigned long);
- extern void _exception_pkey(struct pt_regs *, unsigned long, int);
- extern void die(const char *, struct pt_regs *, long);
-+void die_mce(const char *str, struct pt_regs *regs, long err);
- extern bool die_will_crash(void);
- extern void panic_flush_kmsg_start(void);
- extern void panic_flush_kmsg_end(void);
-diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
-index 6691774fe1fb..f9ef183a5454 100644
---- a/arch/powerpc/kernel/traps.c
-+++ b/arch/powerpc/kernel/traps.c
-@@ -789,6 +789,19 @@ int machine_check_generic(struct pt_regs *regs)
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
+index db89ecfef762..9c16e9a48df6 100644
+--- a/arch/powerpc/include/asm/interrupt.h
++++ b/arch/powerpc/include/asm/interrupt.h
+@@ -6,6 +6,7 @@
+ #include <linux/hardirq.h>
+ #include <asm/cputime.h>
+ #include <asm/ftrace.h>
++#include <asm/runlatch.h>
+
+ struct interrupt_state {
+ #ifdef CONFIG_PPC_BOOK3E_64
+@@ -84,6 +85,12 @@ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt
+
+ static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
+ {
++#ifdef CONFIG_PPC_BOOK3S_64
++ if (cpu_has_feature(CPU_FTR_CTRL) &&
++ !test_thread_local_flags(_TLF_RUNLATCH))
++ __ppc64_runlatch_on();
++#endif
++
+ interrupt_enter_prepare(regs, state);
+ irq_enter();
}
- #endif /* everything else */
+diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
+index f9a2751570ef..05a358559274 100644
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -692,14 +692,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
+ ld r1,GPR1(r1)
+ .endm
-+void die_mce(const char *str, struct pt_regs *regs, long err)
-+{
-+ /*
-+ * The machine check wants to kill the interrupted context, but
-+ * do_exit() checks for in_interrupt() and panics in that case, so
-+ * exit the irq/nmi before calling die.
-+ */
-+ if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64))
-+ nmi_exit();
-+ die(str, regs, err);
-+}
-+NOKPROBE_SYMBOL(die_mce);
-+
- void machine_check_exception(struct pt_regs *regs)
- {
- int recover = 0;
-@@ -831,15 +844,11 @@ void machine_check_exception(struct pt_regs *regs)
- if (check_io_access(regs))
- goto bail;
+-#define RUNLATCH_ON \
+-BEGIN_FTR_SECTION \
+- ld r3, PACA_THREAD_INFO(r13); \
+- ld r4,TI_LOCAL_FLAGS(r3); \
+- andi. r0,r4,_TLF_RUNLATCH; \
+- beql ppc64_runlatch_on_trampoline; \
+-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+-
+ /*
+ * When the idle code in power4_idle puts the CPU into NAP mode,
+ * it has to do so in a loop, and relies on the external interrupt
+@@ -1582,7 +1574,6 @@ EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
+ EXC_COMMON_BEGIN(hardware_interrupt_common)
+ GEN_COMMON hardware_interrupt
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_IRQ
+ b interrupt_return
+@@ -1768,7 +1759,6 @@ EXC_VIRT_END(decrementer, 0x4900, 0x80)
+ EXC_COMMON_BEGIN(decrementer_common)
+ GEN_COMMON decrementer
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl timer_interrupt
+ b interrupt_return
+@@ -1854,7 +1844,6 @@ EXC_VIRT_END(doorbell_super, 0x4a00, 0x100)
+ EXC_COMMON_BEGIN(doorbell_super_common)
+ GEN_COMMON doorbell_super
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ #ifdef CONFIG_PPC_DOORBELL
+ bl doorbell_exception
+@@ -2209,7 +2198,6 @@ EXC_COMMON_BEGIN(hmi_exception_early_common)
+ EXC_COMMON_BEGIN(hmi_exception_common)
+ GEN_COMMON hmi_exception
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl handle_hmi_exception
+ b interrupt_return
+@@ -2239,7 +2227,6 @@ EXC_VIRT_END(h_doorbell, 0x4e80, 0x20)
+ EXC_COMMON_BEGIN(h_doorbell_common)
+ GEN_COMMON h_doorbell
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ #ifdef CONFIG_PPC_DOORBELL
+ bl doorbell_exception
+@@ -2273,7 +2260,6 @@ EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20)
+ EXC_COMMON_BEGIN(h_virt_irq_common)
+ GEN_COMMON h_virt_irq
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl do_IRQ
+ b interrupt_return
+@@ -2320,7 +2306,6 @@ EXC_VIRT_END(performance_monitor, 0x4f00, 0x20)
+ EXC_COMMON_BEGIN(performance_monitor_common)
+ GEN_COMMON performance_monitor
+ FINISH_NAP
+- RUNLATCH_ON
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl performance_monitor_exception
+ b interrupt_return
+@@ -3035,9 +3020,6 @@ kvmppc_skip_Hinterrupt:
+ * come here.
+ */
-- if (nmi) nmi_exit();
+-EXC_COMMON_BEGIN(ppc64_runlatch_on_trampoline)
+- b __ppc64_runlatch_on
-
-- die("Machine check", regs, SIGBUS);
-+ die_mce("Machine check", regs, SIGBUS);
-
- /* Must die if the interrupt is not recoverable */
- if (!(regs->msr & MSR_RI))
-- die("Unrecoverable Machine check", regs, SIGBUS);
--
-- return;
-+ die_mce("Unrecoverable Machine check", regs, SIGBUS);
-
- bail:
- if (nmi) nmi_exit();
-diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
-index c61c3b62c8c6..303d7c775740 100644
---- a/arch/powerpc/platforms/powernv/opal.c
-+++ b/arch/powerpc/platforms/powernv/opal.c
-@@ -624,7 +624,7 @@ static int opal_recover_mce(struct pt_regs *regs,
- */
- recovered = 0;
- } else {
-- die("Machine check", regs, SIGBUS);
-+ die_mce("Machine check", regs, SIGBUS);
- recovered = 1;
- }
- }
-diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
-index 149cec2212e6..2d9f985fd13a 100644
---- a/arch/powerpc/platforms/pseries/ras.c
-+++ b/arch/powerpc/platforms/pseries/ras.c
-@@ -813,7 +813,7 @@ static int recover_mce(struct pt_regs *regs, struct machine_check_event *evt)
- */
- recovered = 0;
- } else {
-- die("Machine check", regs, SIGBUS);
-+ die_mce("Machine check", regs, SIGBUS);
- recovered = 1;
- }
- }
+ USE_FIXED_SECTION(virt_trampolines)
+ /*
+ * All code below __end_interrupts is treated as soft-masked. If
--
2.23.0