Katsuhiro Suzuki wrote:
> Newer switching sets NEW thread handle into _current_cpu.current
> BEFORE calling arch_switch(). This implementation will face a
> problem in RISC-V environment if thread calls do_swap() explicitly
> and switch to thread B (use FPU) from thread A (not use FPU)
So... this is the very middle of a context switch. The expectation of the kernel is that no exception/interrupt handlers are going to fire, because (by definition) if they do they will see corrupt/inconsistent thread state. Or rather, if an architecture wants to allow that, it needs to be prepared to do the work.
I mean, the information is available to you: you know what the new thread is, because you're handed its switch handle which you created yourself. You likewise know the old thread, because you're passed the address of its switch_handle field from which you can extract a pointer to the enclosing thread struct. You know you're in the middle of a context switch, because arch_switch() was called. You COULD write an FPU exception handler to detect this state and do the right thing. I don't necessarily think this would be a good design, but it's possible.
Can you explain why you need to take an FPU exception in the middle of a context switch? That seems a little questionable to me. Why are you hitting lazy-saved FPU registers in a situation where it would be faster to just check the mask state to see if they are populated or not? (Forgive me: I don't know the RISC-V FPU architecture, but I assume that's the situation you're in: the FPU registers may or may not be in use and using them if they aren't will trap.)