Inter-revision diff: patch 20

Comparing v6 (message) to v4 (message)

--- 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
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help