summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Holland <[email protected]>2023-12-08 13:22:58 -0800
committerAnup Patel <[email protected]>2023-12-18 19:26:33 +0530
commit446fa65eb57947481583df043bc613a164172131 (patch)
tree5c7df7dd16575fe1bf78e0d6c1d9a5f79494983b
parenta894187e28895ab8e1196dea838fdef4cc4d32b3 (diff)
lib: sbi_ipi: Process self-IPIs in sbi_ipi_send()
An IPI sent to the local hart can be processed directly instead of triggering the IPI device. This is more efficient, and it avoids a deadlock when the .sync callback is defined. Since interrupts are disabled while handling an ecall, the IPI would not get delivered until the next mret, but sbi_ipi_sync() is called before then. Signed-off-by: Samuel Holland <[email protected]> Reviewed-by: Anup Patel <[email protected]> Reviewed-by: Xiang W <[email protected]>
-rw-r--r--lib/sbi/sbi_ipi.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c
index 56ba743c..bbc97f7f 100644
--- a/lib/sbi/sbi_ipi.c
+++ b/lib/sbi/sbi_ipi.c
@@ -60,6 +60,14 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartindex,
remote_hartindex, data);
if (ret != SBI_IPI_UPDATE_SUCCESS)
return ret;
+ } else if (scratch == remote_scratch) {
+ /*
+ * IPI events with an update() callback are expected to return
+ * SBI_IPI_UPDATE_BREAK for self-IPIs. For other events, check
+ * for self-IPI and execute the callback directly here.
+ */
+ ipi_ops->process(scratch);
+ return 0;
}
/*