[RFC] OpenSBI: Lazy floating-point and vector context switching
Anup Patel
anup at brainfault.org
Thu Mar 12 23:59:04 PDT 2026
On Fri, Mar 13, 2026 at 6:43 AM Samuel Holland
<samuel.holland at sifive.com> wrote:
>
> Hi Dave,
>
> On 2026-03-12 6:23 PM, Samuel Holland wrote:
> > On 2026-03-12 12:33 PM, Vivian Wang wrote:
> >> On 3/12/26 22:13, Samuel Holland wrote:
> >>> On 2026-03-12 4:14 AM, Vivian Wang wrote:
> >>>> On 3/12/26 01:11, dave.patel at riscstar.com wrote:
> >>>>> Hi OpenSBI maintainers and community,
> >>>>>
> >>>>> I am working on an implementation to support floating-point (FP) and
> >>>>> vector register context management during domain and application
> >>>>> context switches in OpenSBI.
> >>>>>
> >>>>> Currently, OpenSBI saves and restores only the integer register
> >>>>> context when handling traps or domain transitions. The FP registers
> >>>>> (f0–f31) and vector registers (v0–v31) are not currently managed by
> >>>>> OpenSBI.
> >>>>>
> >>>>> With increasing adoption of the RISC-V vector extension and
> >>>>> floating-point workloads, it becomes important to ensure correct
> >>>>> behavior when S-mode software or trusted applications use these
> >>>>> execution units.
> >>>>>
> >>>>> This email proposes an approach to support lazy FP and vector
> >>>>> context switching, aligned with the mechanism described in the
> >>>>> RISC-V privileged specification.
> >>>>>
> >>>>> ---
> >>>>>
> >>>>> ## Background
> >>>>>
> >>>>> In RISC-V, the `FS` (Floating-point State) and `VS` (Vector State)
> >>>>> fields in `mstatus` / `sstatus` control access to the floating-point
> >>>>> and vector units.
> >>>>>
> >>>>> When these fields are set to `Off`, any attempt to execute FP or
> >>>>> vector instructions results in an illegal instruction trap.
> >>>>>
> >>>>> This mechanism allows operating systems and firmware to implement
> >>>>> lazy context switching where FP/vector registers are saved or
> >>>>> restored only when they are actually used.
> >>>> This does not work in Machine mode, where OpenSBI resides.
> >>>>
> >>>> See privileged spec, section "Extension Context Status in mstatus
> >>>> Register": "Machine and Supervisor modes share a single copy of the FS,
> >>>> VS, and XS bits."
> >>>>
> >>>> This means that a Supervisor mode program can set sstatus.FS to Dirty,
> >>>> access floating point state, and set sstatus.FS back to Off without
> >>>> Machine mode software noticing ever.
> >>>>
> >>>> See also https://github.com/riscv/riscv-isa-manual/issues/832
> >>>> "Impossible to implement HS-level sstatus.{FS,VS} = Off with
> >>>> software-emulated hypervisor extension?" where I ran into the same
> >>>> problem in a different context.
> >>>>
> >>>> So basically, lazy saving/restoring F and V in Machine mode with
> >>>> multiple Supervisor mode programs is not a designed feature, and is not
> >>>> possible as the privileged architecture is currently designed. For these
> >>>> use cases non-lazy switching is required.
> >>> As you mentioned in in that Github issue, it is also possible to force
> >>> floating-point instructions to trap by clearing misa.F. However, note this
> >>> clause in the misa specification:
> >>>
> >>> "When software enables an extension that was previously disabled, then all state
> >>> uniquely associated with that extension is UNSPECIFIED, unless otherwise
> >>> specified by that extension."
> >>>
> >>> So floating-point state must always be saved on a misa.F 1->0 transition and
> >>> restored on a misa.F 0->1 transition. This does somewhat reduce the
> >>> effectiveness of the lazy context saving, but still provides some benefit. And
> >>> this scheme gracefully degrades on systems where misa.F is not writable. So
> >>> unless I am missing something, hiding FP state using misa bits should work for
> >>> the current use case.
> >>
> >> I'm a bit confused about the 0->1 and 1->0 transition terminology but I
> >> get the idea. It *would* work, yes.
> >
> > Sorry for the confusion. To reword: the FP context must be saved every time the
> > misa.F bit is cleared (F/D/V extension disabled), because it must be restored
> > every time the misa.F bit is later set (F extension enabled), because the
> > register state is otherwise unspecified immediately after the misa.F bit is set.
> >
> > This is in contrast to mstatus.FS, where you can set the field to Off while the
> > FP registers hold domain A's context, switch to domain B and back to A, then set
> > mstatus.FS back to Dirty, all without losing any register state. So misa.F is
> > not as lazy as mstatus.FS.
> >
> >> It's just that I am not aware of any existing hardware implementation
> >> having writable misa.F and/or misa.V (as opposed to xstatus.{FS,VS}
> >> which are mandatory if F and V are implemented, respectively), so I did
> >> not consider it.
> >>
> >> To me, writable misa is one of those funny features that the spec
> >> technically permits but nobody actually implements in HW. I'm happy to
> >> change my mind about that if some real hardware has writable misa.F and
> >> misa.V.
> >
> > That's fair. I know at least one real-ish implementation, Rocket[1], has this
> > capability, but I'm also unaware of a public commercial SoC with this feature.
> > That being said, since this is the existing architectural way to track FP usage
> > from M-mode (admittedly with the above limitation), I would expect pushback to
> > adding any duplicate or overlapping mechanism. So we might see implementations
> > add this capability as they start to add Supervisor Domains features.
>
> I raised this at https://github.com/riscv/riscv-smmtt/issues/264 and the
> response from Ved was "Enhancing support for lazy save/restore has been
> discussed previously and is not likely to be accepted".
>
> So it seems that the options are:
> 1) eager context switching,
> 2) optionally with opportunistic use of misa.{D,F,V} if those bits are writable.
Currently, I am leaning towards option #1 because:
=> misa.{D,F,V} are not writable on all RISC-V platforms
=> domain context switching is less frequent and on-demand
compared to Linux task switching
In the long run, option #1 can be the default and we can do
option #2 selectively on platforms with writable misa{D,F,V} bits.
Regards,
Anup
More information about the opensbi
mailing list