[RFC] OpenSBI: Lazy floating-point and vector context switching

Samuel Holland samuel.holland at sifive.com
Thu Mar 12 16:23:55 PDT 2026


Hi Vivian,

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.

Regards,
Samuel

[1]:
https://github.com/chipsalliance/rocket-chip/blob/v1.6/src/main/scala/rocket/CSR.scala#L1184-L1192




More information about the opensbi mailing list