RISC-V:the FPU case in ostest failed due to "lazy" FPU save/restore?
- Dominant language
- C
- Stars
- 4k
- Forks
- 1.7k
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 237
Description
We tried to port NuttX on a new SoC, and found an issue related to the FPU test.
In the source files:
https://github.com/apache/incubator-nuttx/blob/master/arch/risc-v/src/common/riscv_exception_common.S
https://github.com/apache/incubator-nuttx/blob/master/arch/risc-v/src/common/riscv_macros.S
We can see that when the FPU context needs to be saved, it checks the FS field, and stores the FPU regs ONLY when it is dirty, then mark it as clean and updates "mstatus" in the full context.
In the FPU test:
https://github.com/apache/incubator-nuttx-apps/blob/master/testing/ostest/fpu.c
1. when up_saveusercontext is called for the first time, the FS=3 after float OPs in this thread, so we got the FPU context stored in sp, and copied to "fpu->save1", when done, FS=2 in this thread
2. when up_saveusercontext is called for the second time, just after the first call, the "LAZY" FPU save logic will skip FPU context since FS = 2(CLEAN) != 3(DIRTY). But since the FPU context is still in the stack of the current thread, so we still get the right float regs in fpu->save2, and pass the first up_fpucmp
3. when up_saveusercontext is called for the third time, the FS is still 2 since we did not touch the FPU during sched_unlock and usleep. However, these two did mess up the stack --- the original FPU context is gone. But due to the "LAZY" FPU save logic, it still skip the FPU context since FS=2. So we will get the un-expected data in fpu->save2 this time, and leads to fail in the second up_fpucmp.
Did we missed something in our port?
Thanks in advance.
Contributor guide
Assessment
This issue has not been assessed yet.