summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBen Dooks <[email protected]>2022-07-11 08:18:03 +0100
committerAnup Patel <[email protected]>2022-07-11 15:46:59 +0530
commitcaa5eeacacbc935090968e601716f66a6195ceef (patch)
tree8485b24961388fc16885ae81c409b828d854c70e /lib
parent994c8cfb29d0b53bbcc774a728cad778aeece6ac (diff)
lib: sbi: add check for ipi device for hsm start
If the ecall SBI_EXT_HSM_HART_START is called it might try to wake the secondary hart using sbi_ipi_raw_send() to send an IPI to the hart. This can fail if there is no IPI device but no error is returned from sbi_ipi_raw_send() so the ecall returns as if the action completed and the caller continues without noticing (in the case of Linux it just hangs waiting for the secondary hart to become active) Fix this by changing sbi_ipi_raw_send() to return and error, and if an error is returned, then return it via SBI_EXT_HSM_HART_START call. Signed-off-by: Ben Dooks <[email protected]> Reviewed-by: Anup Patel <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/sbi/sbi_hsm.c4
-rw-r--r--lib/sbi/sbi_ipi.c9
2 files changed, 9 insertions, 4 deletions
diff --git a/lib/sbi/sbi_hsm.c b/lib/sbi/sbi_hsm.c
index 1165acc0..836008fc 100644
--- a/lib/sbi/sbi_hsm.c
+++ b/lib/sbi/sbi_hsm.c
@@ -289,7 +289,9 @@ int sbi_hsm_hart_start(struct sbi_scratch *scratch,
(hsm_device_has_hart_secondary_boot() && !init_count)) {
return hsm_device_hart_start(hartid, scratch->warmboot_addr);
} else {
- sbi_ipi_raw_send(hartid);
+ int rc = sbi_ipi_raw_send(hartid);
+ if (rc)
+ return rc;
}
return 0;
diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c
index 1014909b..7aafbbde 100644
--- a/lib/sbi/sbi_ipi.c
+++ b/lib/sbi/sbi_ipi.c
@@ -208,10 +208,13 @@ skip:
};
}
-void sbi_ipi_raw_send(u32 target_hart)
+int sbi_ipi_raw_send(u32 target_hart)
{
- if (ipi_dev && ipi_dev->ipi_send)
- ipi_dev->ipi_send(target_hart);
+ if (!ipi_dev || !ipi_dev->ipi_send)
+ return SBI_EINVAL;
+
+ ipi_dev->ipi_send(target_hart);
+ return 0;
}
const struct sbi_ipi_device *sbi_ipi_get_device(void)