History

firmware: arm_sdei: add SDEI_EVENT_SIGNAL support

Add sdei_event_signal(), a thin wrapper over the SDEI_EVENT_SIGNAL call (DEN0054) that makes the software-signalled event (event 0) pending on a target PE -- delivered NMI-like even when that PE has interrupts masked. It takes no locks, so it is safe to call from NMI / crash context.

Kiryl Shutsemau (Meta) committed 4 months ago

Commit 9141eda1 parent 5686f2b3 files · +19 −0Browse files

Unified · Split

3 files
  1. drivers/firmware/arm_sdei.c +12 −0
  2. include/linux/arm_sdei.h +6 −0
  3. include/uapi/linux/arm_sdei.h +1 −0
drivers/firmware/arm_sdei.c+12−0
@@ -339,6 +339,18 @@ static void _ipi_unmask_cpu(void *ignored) · 338 unmodified lines
339339 sdei_unmask_local_cpu();
340340 }
341341
342+/*
343+ * Signal the software-signalled event (event 0) to @mpidr. Does nothing
344+ * but the SMC -- no locks, no event lookup -- so it is safe from NMI /
345+ * crash context (e.g. the cross-CPU NMI service).
346+ */
347+int sdei_event_signal(u32 event_num, u64 mpidr)
348+{
349+ return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_SIGNAL, event_num,
350+ mpidr, 0, 0, 0, NULL);
351+}
352+NOKPROBE_SYMBOL(sdei_event_signal);
353+
342354 /*
343355 * Was SDEI firmware probed and is it usable? Lets optional consumers skip
344356 * registering an event -- and the warning a failed registration emits -- on
include/linux/arm_sdei.h+6−0
@@ -37,6 +37,12 @@ int sdei_event_unregister(u32 event_num); · 36 unmodified lines
3737 int sdei_event_enable(u32 event_num);
3838 int sdei_event_disable(u32 event_num);
3939
40+/*
41+ * Signal the software-signalled event (event 0) to another PE, NMI-like.
42+ * @mpidr is the target's MPIDR affinity.
43+ */
44+int sdei_event_signal(u32 event_num, u64 mpidr);
45+
4046 /* Was SDEI firmware probed and usable? */
4147 bool sdei_is_present(void);
4248
include/uapi/linux/arm_sdei.h+1−0
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 #define SDEI_1_0_FN_SDEI_PE_UNMASK SDEI_1_0_FN(0x0C)
2323 #define SDEI_1_0_FN_SDEI_INTERRUPT_BIND SDEI_1_0_FN(0x0D)
2424 #define SDEI_1_0_FN_SDEI_INTERRUPT_RELEASE SDEI_1_0_FN(0x0E)
25+#define SDEI_1_0_FN_SDEI_EVENT_SIGNAL SDEI_1_0_FN(0x0F)
2526 #define SDEI_1_0_FN_SDEI_PRIVATE_RESET SDEI_1_0_FN(0x11)
2627 #define SDEI_1_0_FN_SDEI_SHARED_RESET SDEI_1_0_FN(0x12)
2728