[PATCH v4 3/3] lib: sbi: domain FP/Vector context support for context switch
Anup Patel
anup at brainfault.org
Wed May 13 00:54:15 PDT 2026
On Wed, May 13, 2026 at 12:44 PM <dave.patel at riscstar.com> wrote:
>
> From: Dave Patel <dave.patel at riscstar.com>
>
> This patch adds proper support for per-domain floating-point (FP) and
> vector (V) contexts in the domain context switch logic. Each domain
> now maintains its own FP and vector state, which is saved and restored
> during domain switches.
>
> Changes include:
>
> - Added `fp_ctx` and `vec_ctx` members to `struct hart_context`.
> - Introduced dynamic vector struct allocation for vlenb in 'struct hart_context'
> to allocate and free per-domain FP and vector context.
> - Modified `sbi_domain_register()` to initialize FP/Vector context per domain.
> - Updated `switch_to_next_domain_context()` to save/restore FP and vector
> contexts safely:
> - Ensures FS/VS fields in `mstatus` are enabled (set to Initial) only if Off.
> - Added runtime checks for FP and vector extensions where needed.
>
> This improves support for multi-domain systems with FP and Vector
> extensions, and prevents corruption of FP/Vector state during domain
> switches.
>
> Signed-off-by: Dave Patel <dave.patel at riscstar.com>
> ---
> include/sbi/sbi_domain.h | 2 ++
> lib/sbi/sbi_domain_context.c | 28 ++++++++++++++++++++++++++++
> 2 files changed, 30 insertions(+)
>
> diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> index 882b62c2..05a5d86c 100644
> --- a/include/sbi/sbi_domain.h
> +++ b/include/sbi/sbi_domain.h
> @@ -16,6 +16,8 @@
> #include <sbi/sbi_hartmask.h>
> #include <sbi/sbi_domain_context.h>
> #include <sbi/sbi_domain_data.h>
> +#include <sbi/sbi_vector.h>
> +#include <sbi/sbi_fp.h>
>
> struct sbi_scratch;
>
> diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
> index 158f4990..5e180698 100644
> --- a/lib/sbi/sbi_domain_context.c
> +++ b/lib/sbi/sbi_domain_context.c
> @@ -18,6 +18,9 @@
> #include <sbi/sbi_domain_context.h>
> #include <sbi/sbi_platform.h>
> #include <sbi/sbi_trap.h>
> +#include <sbi/sbi_vector.h>
> +#include <sbi/sbi_fp.h>
> +
>
> /** Context representation for a hart within a domain */
> struct hart_context {
> @@ -55,6 +58,11 @@ struct hart_context {
> struct hart_context *prev_ctx;
> /** Is context initialized and runnable */
> bool initialized;
> +
> + /** float context state */
> + struct sbi_fp_context fp_ctx;
> + /** vector context state */
> + struct sbi_vector_context *vec_ctx;
> };
>
> static struct sbi_domain_data dcpriv;
> @@ -143,6 +151,15 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
> if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSQOSID))
> ctx->srmcfg = csr_swap(CSR_SRMCFG, dom_ctx->srmcfg);
>
> + /* Make sure FS and VS is on before context switch */
> + 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);
Unconditional save/restore of FP and Vector is not going to fly
because the generic platform firmwares are expected to work
on multiple platforms (both with or without vector).
To address this, do FP save/restore only if underlying hart
has F/D hart extension. Similarly, do Vector save/restore
only if underlying hart has Vector extension.
As a separate patch, introduce SBI_HART_EXT_F,
SBI_HART_EXT_D, and SBI_HART_EXT_V in
enum sbi_hart_extensions and sbi_hart_ext[]. Once,
this is done you can check for SBI_HART_EXT_F,
SBI_HART_EXT_D, and SBI_HART_EXT_V using
sbi_hart_has_extension().
> +
> /* Save current trap state and restore target domain's trap state */
> trap_ctx = sbi_trap_get_context(scratch);
> sbi_memcpy(&ctx->trap_ctx, trap_ctx, sizeof(*trap_ctx));
> @@ -170,6 +187,10 @@ static int hart_context_init(u32 hartindex)
> {
> struct hart_context *ctx;
> struct sbi_domain *dom;
> + unsigned long vlenb = vector_vlenb();
> +
> + /* Calculate size: base struct + 32 registers of vlenb size */
> + size_t vec_size = sizeof(struct sbi_vector_context) + (32 * vlenb);
>
> sbi_domain_for_each(dom) {
> if (!sbi_hartmask_test_hartindex(hartindex,
> @@ -180,6 +201,13 @@ 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;
> + }
> +
> /* Bind context and domain */
> ctx->dom = dom;
> hart_context_set(dom, hartindex, ctx);
> --
> 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