[RFC] OpenSBI: Lazy floating-point and vector context switching
Samuel Holland
samuel.holland at sifive.com
Thu Mar 12 18:13:31 PDT 2026
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.
Regards,
Samuel
More information about the opensbi
mailing list