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

dave.patel at riscstar.com dave.patel at riscstar.com
Thu May 14 22:42:08 PDT 2026


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 ++++
 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




More information about the opensbi mailing list