linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] arm64: abort SDEI handlers during crash
@ 2023-02-04  0:08 D Scott Phillips
  2023-02-10 18:19 ` James Morse
  0 siblings, 1 reply; 4+ messages in thread
From: D Scott Phillips @ 2023-02-04  0:08 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Catalin Marinas, Will Deacon, James Morse

Interrupts are blocked in SDEI context, per the SDEI spec: "The client
interrupts cannot preempt the event handler." If we crashed in the SDEI
handler-running context (as with ACPI's AGDI) then we need to clean up the
SDEI state before proceeding to the crash kernel so that the crash kernel
can have working interrupts.  Try two COMPLETE_AND_RESUMEs in case both a
normal and critical event were being handled.

Fixes: f5df26961853 ("arm64: kernel: Add arch-specific SDEI entry code and CPU masking")
Signed-off-by: D Scott Phillips <scott@os.amperecomputing.com>
---
 arch/arm64/include/asm/sdei.h |  3 +++
 arch/arm64/kernel/entry.S     | 24 +++++++++++++++++++++---
 arch/arm64/kernel/smp.c       | 14 ++++++++++----
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/sdei.h b/arch/arm64/include/asm/sdei.h
index 4292d9bafb9d..1030568db7d3 100644
--- a/arch/arm64/include/asm/sdei.h
+++ b/arch/arm64/include/asm/sdei.h
@@ -29,6 +29,9 @@ asmlinkage void __sdei_asm_entry_trampoline(unsigned long event_num,
 						   unsigned long pc,
 						   unsigned long pstate);
 
+/* End a possibly still running handler. Context is discarded. */
+void sdei_handler_abort(void);
+
 /*
  * The above entry point does the minimum to call C code. This function does
  * anything else, before calling the driver.
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 11cb99c4d298..03dc233bdaa1 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -909,13 +909,18 @@ NOKPROBE(call_on_irq_stack)
 #include <asm/sdei.h>
 #include <uapi/linux/arm_sdei.h>
 
-.macro sdei_handler_exit exit_mode
-	/* On success, this call never returns... */
+.macro sdei_handler_exit_fallthrough exit_mode
 	cmp	\exit_mode, #SDEI_EXIT_SMC
 	b.ne	99f
 	smc	#0
-	b	.
+	b	100f
 99:	hvc	#0
+100:
+.endm
+
+.macro sdei_handler_exit exit_mode
+	sdei_handler_exit_fallthrough exit_mode=\exit_mode
+	/* On success, this call never returns... */
 	b	.
 .endm
 
@@ -1077,4 +1082,17 @@ alternative_else_nop_endif
 #endif
 SYM_CODE_END(__sdei_asm_handler)
 NOKPROBE(__sdei_asm_handler)
+
+SYM_CODE_START(sdei_handler_abort)
+	mov_q	x0, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME
+	adr	x1, 1f
+	ldr_l	x2, sdei_exit_mode
+	sdei_handler_exit_fallthrough exit_mode=x2
+	// either fallthrough if not in handler context, or exit the handler
+	// and jump to the next instruction. Exit will stomp x0-x17, PSTATE,
+	// ELR_ELx, and SPSR_ELx.
+1:	ret
+SYM_CODE_END(sdei_handler_abort)
+NOKPROBE(sdei_handler_abort)
+
 #endif /* CONFIG_ARM_SDE_INTERFACE */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index ffc5d76cf695..bc1b3000197e 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -1047,10 +1047,8 @@ void crash_smp_send_stop(void)
 	 * If this cpu is the only one alive at this point in time, online or
 	 * not, there are no stop messages to be sent around, so just back out.
 	 */
-	if (num_other_online_cpus() == 0) {
-		sdei_mask_local_cpu();
-		return;
-	}
+	if (num_other_online_cpus() == 0)
+		goto skip_ipi;
 
 	cpumask_copy(&mask, cpu_online_mask);
 	cpumask_clear_cpu(smp_processor_id(), &mask);
@@ -1069,7 +1067,15 @@ void crash_smp_send_stop(void)
 		pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
 			cpumask_pr_args(&mask));
 
+skip_ipi:
 	sdei_mask_local_cpu();
+	/*
+	 * The crash may have happened in a critical event handler which
+	 * preempted a normal handler. So at most we might have two
+	 * levels of SDEI context to exit.
+	 */
+	sdei_handler_abort();
+	sdei_handler_abort();
 }
 
 bool smp_crash_stop_failed(void)
-- 
2.39.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-04-20 11:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-04  0:08 [PATCH] arm64: abort SDEI handlers during crash D Scott Phillips
2023-02-10 18:19 ` James Morse
2023-02-10 22:16   ` D Scott Phillips
2023-04-20 11:50     ` Mihai Carabas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).