From: dave.patel@riscstar.com
To: Samuel Holland <samuel.holland@sifive.com>
Cc: Scott Bambrough <scott@riscstar.com>,
Robin Randhawa <robin.randhawa@sifive.com>,
Anup Patel <anup.patel@qti.qualcomm.com>,
Dave Patel <dave.patel@riscstar.com>,
Ray Mao <raymond.mao@riscstar.com>,
Anup Patel <anuppate@qti.qualcomm.com>,
Dhaval <dhaval@rivosinc.com>, Peter Lin <peter.lin@sifive.com>,
opensbi@lists.infradead.org
Subject: [PATCH v3 3/3] lib: sbi: domain FP/Vector context support for context switch
Date: Tue, 31 Mar 2026 06:58:57 +0100 [thread overview]
Message-ID: <20260331055858.305207-4-dave.patel@riscstar.com> (raw)
In-Reply-To: <20260331055858.305207-1-dave.patel@riscstar.com>
From: Dave Patel <dave.patel@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 sbi_domain`.
- Introduced `sbi_vector_domain_init` for vlen check
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.
- Restores original FS/VS bits after context switch.
- Adds NULL checks to handle domains without FP or Vector extensions.
- Updated domain context deinit to free FP and vector contexts per domain.
- Added runtime checks for FP and vector extensions where needed.
- Corrected handling of MSTATUS FS/VS bits to avoid unsafe full-bit writes.
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@riscstar.com>
---
include/sbi/sbi_domain.h | 6 +++++
include/sbi/sbi_fp.h | 13 +----------
include/sbi/sbi_vector.h | 4 ++++
lib/sbi/sbi_domain.c | 6 +++++
lib/sbi/sbi_domain_context.c | 12 ++++++++++
lib/sbi/sbi_fp.c | 6 +++++
lib/sbi/sbi_vector.c | 43 ++++++++++++++++++++++++++----------
7 files changed, 66 insertions(+), 24 deletions(-)
diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 882b62c2..318d3a9a 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;
@@ -217,6 +219,10 @@ struct sbi_domain {
bool fw_region_inited;
/** per-domain wired-IRQ courier state */
void *virq_priv;
+ /** per-domain float context state */
+ struct sbi_fp_context fp_ctx;
+ /** per-domain vector context state */
+ struct sbi_vector_context vec_ctx;
};
/** The root domain instance */
diff --git a/include/sbi/sbi_fp.h b/include/sbi/sbi_fp.h
index 8079bb3b..962150a3 100644
--- a/include/sbi/sbi_fp.h
+++ b/include/sbi/sbi_fp.h
@@ -8,13 +8,8 @@
#ifndef __SBI_FP_H__
#define __SBI_FP_H__
-#include <sbi/riscv_encoding.h>
#include <sbi/sbi_types.h>
-#if defined(__riscv_f) || defined(__riscv_d)
-
-#include <stdint.h>
-
struct sbi_fp_context {
#if __riscv_d
uint64_t f[32];
@@ -22,13 +17,7 @@ struct sbi_fp_context {
uint32_t f[32];
#endif
uint32_t fcsr;
-} __aligned(16);
-
-#else /* No FP (e.g., Zve32x) */
-
-struct sbi_fp_context { };
-
-#endif //defined(__riscv_f) || defined(__riscv_d)
+};
void sbi_fp_save(struct sbi_fp_context *dst);
void sbi_fp_restore(const struct sbi_fp_context *src);
diff --git a/include/sbi/sbi_vector.h b/include/sbi/sbi_vector.h
index 4ecfaa0b..9ae76b00 100644
--- a/include/sbi/sbi_vector.h
+++ b/include/sbi/sbi_vector.h
@@ -10,6 +10,9 @@
#define __SBI_VECTOR_H__
#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_console.h>
#define SBI_MAX_VLENB CONFIG_SBI_MAX_VLENB
@@ -25,6 +28,7 @@ struct sbi_vector_context {
void sbi_vector_save(struct sbi_vector_context *dst);
void sbi_vector_restore(const struct sbi_vector_context *src);
+int sbi_vector_domain_init(void);
#endif //__SBI_VECTOR_H__
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 498a1d56..424204eb 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -19,6 +19,8 @@
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_string.h>
#include <sbi/sbi_virq.h>
+#include <sbi/sbi_vector.h>
+#include <sbi/sbi_fp.h>
SBI_LIST_HEAD(domain_list);
@@ -1007,6 +1009,10 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
if (rc)
goto fail_free_root_hmask;
+ rc = sbi_vector_domain_init();
+ if (rc)
+ goto fail_free_root_hmask;
+
return 0;
fail_free_root_hmask:
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index 158f4990..f646c7d4 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 {
@@ -143,6 +146,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(¤t_dom->fp_ctx);
+ sbi_fp_restore(&target_dom->fp_ctx);
+ sbi_vector_save(¤t_dom->vec_ctx);
+ sbi_vector_restore(&target_dom->vec_ctx);
+
/* 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));
diff --git a/lib/sbi/sbi_fp.c b/lib/sbi/sbi_fp.c
index 5d72b72e..9772d359 100644
--- a/lib/sbi/sbi_fp.c
+++ b/lib/sbi/sbi_fp.c
@@ -7,8 +7,11 @@
*/
#include <sbi/riscv_asm.h>
+#include <sbi/sbi_heap.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_fp.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_console.h>
#if defined(__riscv_f) || defined(__riscv_d)
@@ -185,7 +188,10 @@ void sbi_fp_restore(const struct sbi_fp_context *src)
csr_write(CSR_FCSR, src->fcsr);
}
+
#else
+
void sbi_fp_save(struct sbi_fp_context *dst) {}
void sbi_fp_restore(const struct sbi_fp_context *src) {}
+
#endif // FP present
diff --git a/lib/sbi/sbi_vector.c b/lib/sbi/sbi_vector.c
index 5a3f34d7..5877c373 100644
--- a/lib/sbi/sbi_vector.c
+++ b/lib/sbi/sbi_vector.c
@@ -12,21 +12,23 @@
#include <sbi/sbi_vector.h>
#include <sbi/sbi_types.h>
#include <sbi/sbi_hart.h>
+#include <sbi/sbi_heap.h>
#ifdef OPENSBI_CC_SUPPORT_VECTOR
+#define VLEN_MAX 65536
static inline void vsetvl(ulong vl, ulong vtype)
{
- ulong tmp;
-
- asm volatile(
- ".option push\n\t"
- ".option arch, +v\n\t"
- "vsetvl %0, %1, %2\n\t"
- ".option pop\n\t"
- : "=r"(tmp)
- : "r"(vl), "r"(vtype)
- : "memory");
+ ulong tmp;
+
+ asm volatile(
+ ".option push\n\t"
+ ".option arch, +v\n\t"
+ "vsetvl %0, %1, %2\n\t"
+ ".option pop\n\t"
+ : "=r"(tmp)
+ : "r"(vl), "r"(vtype)
+ : "memory");
}
static inline unsigned long vector_vlenb(void)
@@ -64,7 +66,7 @@ void sbi_vector_save(struct sbi_vector_context *dst)
/* Step 1: Save CSRs */
READ_CSR(dst->vtype, vtype);
- READ_CSR(dst->vl, vl);
+ READ_CSR(dst->vl, vl);
READ_CSR(dst->vcsr, vcsr);
READ_CSR(dst->vstart, vstart);
@@ -194,12 +196,24 @@ void sbi_vector_restore(const struct sbi_vector_context *src)
/* Restore CSRs first */
WRITE_CSR(vtype, src->vtype);
- WRITE_CSR(vl, src->vl);
+ WRITE_CSR(vl, src->vl);
WRITE_CSR(vcsr, src->vcsr);
WRITE_CSR(vstart, src->vstart);
#undef WRITE_CSR
}
+int sbi_vector_domain_init(void)
+{
+ ulong vlenb = vector_vlenb();
+
+ if (vlenb > SBI_MAX_VLENB) {
+ sbi_printf("[Vector ERR:] vlenb range error\n");
+ return SBI_ERR_BAD_RANGE;
+ }
+
+ return SBI_OK;
+}
+
#else
void sbi_vector_save(struct sbi_vector_context *dst)
@@ -212,4 +226,9 @@ void sbi_vector_restore(const struct sbi_vector_context *src)
return;
}
+int sbi_vector_domain_init(void)
+{
+ return SBI_OK;
+
#endif /* OPENSBI_CC_SUPPORT_VECTOR */
+
--
2.43.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
next prev parent reply other threads:[~2026-03-31 5:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-31 5:58 [PATCH v3 0/3] Add eager FP and RISC-V vector context switching support dave.patel
2026-03-31 5:58 ` [PATCH v3 1/3] lib: sbi: Add RISC-V vector context save/restore support dave.patel
2026-04-02 13:35 ` Radim Krčmář
2026-03-31 5:58 ` [PATCH v3 2/3] lib: sbi: Add floating-point " dave.patel
2026-04-02 13:40 ` Radim Krčmář
2026-03-31 5:58 ` dave.patel [this message]
2026-04-02 13:54 ` [PATCH v3 3/3] lib: sbi: domain FP/Vector context support for context switch Radim Krčmář
-- strict thread matches above, loose matches on Subject: below --
2026-03-27 17:15 [PATCH v3 0/3] Add eager FP and RISC-V vector context switching support dave.patel
2026-03-27 17:16 ` [PATCH v3 3/3] lib: sbi: domain FP/Vector context support for context switch dave.patel
2026-03-30 12:53 ` Radim Krcmar
2026-03-31 5:49 ` Dave Patel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260331055858.305207-4-dave.patel@riscstar.com \
--to=dave.patel@riscstar.com \
--cc=anup.patel@qti.qualcomm.com \
--cc=anuppate@qti.qualcomm.com \
--cc=dhaval@rivosinc.com \
--cc=opensbi@lists.infradead.org \
--cc=peter.lin@sifive.com \
--cc=raymond.mao@riscstar.com \
--cc=robin.randhawa@sifive.com \
--cc=samuel.holland@sifive.com \
--cc=scott@riscstar.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox