[PATCH v5 4/4] lib: sbi: Conditionalize FP and Vector save/restore based on extensions

Anup Patel anup at brainfault.org
Fri May 15 00:44:50 PDT 2026


On Fri, May 15, 2026 at 11:12 AM <dave.patel at riscstar.com> wrote:
>
> From: Dave Patel <dave.patel at riscstar.com>
>
> Unconditional save and restore of floating-point (FP) and Vector
> registers fails on generic platform firmware. This firmware must run
> on multiple platforms that may lack these extensions.
>
> Address this by conditionally executing FP save/restore only if the
> underlying hart supports the F or D extensions. Similarly, perform
> Vector save/restore only if the hart supports the Vector extension.
>
> Depend on a separate patch that introduces SBI_HART_EXT_F,
> SBI_HART_EXT_D, and SBI_HART_EXT_V to enum sbi_hart_extensions and
> the sbi_hart_ext[] array. Use sbi_hart_has_extension() to check for
> these capabilities before performing the context switches.
>
> Signed-off-by: Dave Patel <dave.patel at riscstar.com>
> ---
>  include/sbi/sbi_hart.h       |  6 ++++++
>  lib/sbi/sbi_domain_context.c | 31 ++++++++++++++++++++++---------
>  lib/sbi/sbi_hart.c           |  4 ++++

This patch should be before PATCH3 and the sbi_domain_context.c
changes in this patch must be part of PATCH3.

>  3 files changed, 32 insertions(+), 9 deletions(-)
>
> diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
> index a788b34c..68a01b97 100644
> --- a/include/sbi/sbi_hart.h
> +++ b/include/sbi/sbi_hart.h
> @@ -87,6 +87,12 @@ enum sbi_hart_extensions {
>         SBI_HART_EXT_XSIFIVE_CFLUSH_D_L1,
>         /** Hart has Xsfcease extension */
>         SBI_HART_EXT_XSIFIVE_CEASE,
> +       /** Hart has V extension */
> +       SBI_HART_EXT_V,
> +       /** Hart has F extension */
> +       SBI_HART_EXT_F,
> +       /** Hart has D extension */
> +       SBI_HART_EXT_D,
>
>         /** Maximum index of Hart extension */
>         SBI_HART_EXT_MAX,
> diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
> index 5e180698..1e3ca46d 100644
> --- a/lib/sbi/sbi_domain_context.c
> +++ b/lib/sbi/sbi_domain_context.c
> @@ -155,10 +155,20 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
>         csr_set(CSR_MSTATUS, MSTATUS_FS | MSTATUS_VS);
>
>         /* Eager context switch F and V */
> -       sbi_fp_save(&ctx->fp_ctx);
> -       sbi_fp_restore(&dom_ctx->fp_ctx);
> -       sbi_vector_save(ctx->vec_ctx);
> -       sbi_vector_restore(dom_ctx->vec_ctx);
> +
> +       if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
> +                                  SBI_HART_EXT_F) ||
> +           sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
> +                                  SBI_HART_EXT_D)) {
> +               sbi_fp_save(&ctx->fp_ctx);
> +               sbi_fp_restore(&dom_ctx->fp_ctx);
> +       }
> +
> +       if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
> +                                  SBI_HART_EXT_V)) {
> +               sbi_vector_save(ctx->vec_ctx);
> +               sbi_vector_restore(dom_ctx->vec_ctx);
> +       }
>
>         /* Save current trap state and restore target domain's trap state */
>         trap_ctx = sbi_trap_get_context(scratch);
> @@ -201,11 +211,14 @@ static int hart_context_init(u32 hartindex)
>                 if (!ctx)
>                         return SBI_ENOMEM;
>
> -               /* Allocate the vector context pointer */
> -               ctx->vec_ctx = sbi_zalloc(vec_size);
> -               if (!ctx->vec_ctx) {
> -                       sbi_free(ctx);
> -                       return SBI_ENOMEM;
> +               if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
> +                                          SBI_HART_EXT_V )) {
> +                       /* Allocate the vector context pointer */
> +                       ctx->vec_ctx = sbi_zalloc(vec_size);
> +                       if (!ctx->vec_ctx) {
> +                               sbi_free(ctx);
> +                               return SBI_ENOMEM;
> +                       }
>                 }
>
>                 /* Bind context and domain */
> diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
> index 60e95bca..e7581368 100644
> --- a/lib/sbi/sbi_hart.c
> +++ b/lib/sbi/sbi_hart.c
> @@ -396,6 +396,10 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
>         __SBI_HART_EXT_DATA(ssstateen, SBI_HART_EXT_SSSTATEEN),
>         __SBI_HART_EXT_DATA(xsfcflushdlone, SBI_HART_EXT_XSIFIVE_CFLUSH_D_L1),
>         __SBI_HART_EXT_DATA(xsfcease, SBI_HART_EXT_XSIFIVE_CEASE),
> +       __SBI_HART_EXT_DATA(v, SBI_HART_EXT_V),
> +       __SBI_HART_EXT_DATA(f, SBI_HART_EXT_F),
> +       __SBI_HART_EXT_DATA(d, SBI_HART_EXT_D),
> +
>  };
>
>  _Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
> --
> 2.43.0
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi

Regards,
Anup



More information about the opensbi mailing list