[PATCH] lib: sbi_ecall_hsm: Reject oversized hart IDs
Anup Patel
anup at brainfault.org
Mon Sep 28 05:31:37 PDT 2026
On Mon, Aug 17, 2026 at 11:42 PM Shibo Zhu <3499129952 at qq.com> wrote:
>
> 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
Don't include SBIUnit tests over here. Compile sbi_ecall_hsm_tests
using lib/sbi/tests/objects.mk
Also, PLEASE STOP PIGGY-BACKING UNIT TEST IN FIX PATCH
instead create as separate patch for SBIUnit tests.
I will not take this patch until above is addressed.
Regards,
Anup
> 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
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
More information about the opensbi
mailing list