[PATCH] lib: sbi_ecall_hsm: Reject oversized hart IDs
Shibo Zhu
3499129952 at qq.com
Mon Aug 17 11:12:02 PDT 2026
The HSM SBI interface passes hart IDs in XLEN-wide registers, while
OpenSBI's internal HSM APIs use u32 hart IDs. On RV64, values with upper
32 bits set are truncated before validation and can alias a valid hart.
Reject oversized target hart IDs at the ecall boundary for HART_START and
HART_GET_STATUS. Add SBIUnit coverage to ensure an oversized RV64 hart ID
does not alias the current hart. RV32 behavior is unchanged.
Fixes: e3f69fc1e934 ("lib: Implement Hart State Management (HSM) SBI extension")
Signed-off-by: Shibo Zhu <3499129952 at qq.com>
---
lib/sbi/sbi_ecall_hsm.c | 9 +++++++++
lib/sbi/tests/objects.mk | 2 ++
lib/sbi/tests/sbi_ecall_hsm_test.c | 32 ++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
create mode 100644 lib/sbi/tests/sbi_ecall_hsm_test.c
diff --git a/lib/sbi/sbi_ecall_hsm.c b/lib/sbi/sbi_ecall_hsm.c
index a6e83b05..b4f2b1bd 100644
--- a/lib/sbi/sbi_ecall_hsm.c
+++ b/lib/sbi/sbi_ecall_hsm.c
@@ -25,6 +25,11 @@ static int sbi_ecall_hsm_handler(unsigned long extid, unsigned long funcid,
ulong smode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >>
MSTATUS_MPP_SHIFT;
+ if ((funcid == SBI_EXT_HSM_HART_START ||
+ funcid == SBI_EXT_HSM_HART_GET_STATUS) &&
+ (((u32)-1U) < ((u64)regs->a0)))
+ return SBI_EINVAL;
+
switch (funcid) {
case SBI_EXT_HSM_HART_START:
ret = sbi_hsm_hart_start(scratch, sbi_domain_thishart_ptr(),
@@ -67,3 +72,7 @@ struct sbi_ecall_extension ecall_hsm = {
.register_extensions = sbi_ecall_hsm_register_extensions,
.handle = sbi_ecall_hsm_handler,
};
+
+#ifdef CONFIG_SBIUNIT
+#include "tests/sbi_ecall_hsm_test.c"
+#endif
diff --git a/lib/sbi/tests/objects.mk b/lib/sbi/tests/objects.mk
index 40c441e1..67316efb 100644
--- a/lib/sbi/tests/objects.mk
+++ b/lib/sbi/tests/objects.mk
@@ -16,6 +16,8 @@ libsbi-objs-$(CONFIG_SBIUNIT) += tests/riscv_locks_test.o
carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += math_test_suite
libsbi-objs-$(CONFIG_SBIUNIT) += tests/sbi_math_test.o
+carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += hsm_test_suite
+
carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += ecall_test_suite
libsbi-objs-$(CONFIG_SBIUNIT) += tests/sbi_ecall_test.o
diff --git a/lib/sbi/tests/sbi_ecall_hsm_test.c b/lib/sbi/tests/sbi_ecall_hsm_test.c
new file mode 100644
index 00000000..6bbcb99c
--- /dev/null
+++ b/lib/sbi/tests/sbi_ecall_hsm_test.c
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+#include <sbi/sbi_unit_test.h>
+
+static void hsm_hartid_test(struct sbiunit_test_case *test)
+{
+ struct sbi_ecall_return out = { 0 };
+ struct sbi_trap_regs regs = { 0 };
+
+ regs.a0 = current_hartid();
+ SBIUNIT_ASSERT_EQ(test,
+ sbi_ecall_hsm_handler(SBI_EXT_HSM,
+ SBI_EXT_HSM_HART_GET_STATUS,
+ ®s, &out),
+ SBI_OK);
+
+#if __riscv_xlen == 64
+ regs.a0 |= 1UL << 32;
+ SBIUNIT_EXPECT_EQ(test,
+ sbi_ecall_hsm_handler(SBI_EXT_HSM,
+ SBI_EXT_HSM_HART_GET_STATUS,
+ ®s, &out),
+ SBI_EINVAL);
+#endif
+}
+
+static struct sbiunit_test_case hsm_tests[] = {
+ SBIUNIT_TEST_CASE(hsm_hartid_test),
+ SBIUNIT_END_CASE,
+};
+
+SBIUNIT_TEST_SUITE(hsm_test_suite, hsm_tests);
--
2.43.0
More information about the opensbi
mailing list