Re: [PATCH v6 3/3] lib: sbi: domain FP/Vector context support for context switch
Anup Patel <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <CAAhSdy17KdFiJKT3d83+HCQodYpxaZnedUW4q=7ExdB+oyVg5Q@mail.gmail.com> |
On Sun, May 17, 2026 at 3:51 AM <[email protected]> wrote: > > From: Dave Patel <[email protected]> > > 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. > > Conditionalize FP and Vector save/restore based on extensions, 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. > > 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. > - Added SBI_HART_EXT_F, SBI_HART_EXT_D, 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 This changelog should be part of cover-letter with every series revision. > > 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 <[email protected]> > --- > include/sbi/sbi_hart.h | 6 ++++++ > lib/sbi/sbi_domain_context.c | 37 ++++++++++++++++++++++++++++++++++++ > lib/sbi/sbi_hart.c | 3 +++ > 3 files changed, 46 insertions(+) > > 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 158f4990..a3f69e7f 100644 > --- a/lib/sbi/sbi_domain_context.c > +++ b/lib/sbi/sbi_domain_context.c > @@ -18,6 +18,8 @@ > #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 +57,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 +150,22 @@ 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); > > + /* Eager context switch F */ > + 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); > + } > + > + /* Eager context switch V */ > + 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); > sbi_memcpy(&ctx->trap_ctx, trap_ctx, sizeof(*trap_ctx)); > @@ -180,6 +203,20 @@ static int hart_context_init(u32 hartindex) > if (!ctx) > return SBI_ENOMEM; > > + if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), > + SBI_HART_EXT_V)) { > + 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); Use sbi_vector_context_size() over here as suggested in PATCH1 > + > + /* 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); > diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c > index 60e95bca..b5e0ee10 100644 > --- a/lib/sbi/sbi_hart.c > +++ b/lib/sbi/sbi_hart.c > @@ -396,6 +396,9 @@ 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 > [email protected] > http://lists.infradead.org/mailman/listinfo/opensbi Regards, Anup -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi