diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2023-01-18 09:30:32 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2023-01-18 09:31:45 +0000 |
commit | 61f5462fde6c38c1f4f5c34a05fab506b6869375 (patch) | |
tree | 59b07882fcb70153a92277dab25b1cb7c6b75b1e | |
parent | 95dd6974b591ce76bf8d29adcc0dd01b4b281ffd (diff) | |
download | src-61f5462fde6c38c1f4f5c34a05fab506b6869375.tar.gz src-61f5462fde6c38c1f4f5c34a05fab506b6869375.zip |
Always store the arm64 VFP context
If a thread enters a kernel FP context the PCB_FP_STARTED may be
unset when calling get_fpcontext even if the VFP unit has been used
by the current thread.
Reduce the use of this flag to just decide when to store the VFP state.
While here add an assert to check the assumption that the passed in
thread is the current thread and remove the unneeded critical section.
The latter is unneeded as the only place we would need it is in
vfp_save_state and this already has a critical section when needed.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D37998
-rw-r--r-- | sys/arm64/arm64/exec_machdep.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c index 12c23149ec7f..258cb5d26b13 100644 --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -489,30 +489,27 @@ get_fpcontext(struct thread *td, mcontext_t *mcp) #ifdef VFP struct pcb *curpcb; - critical_enter(); + MPASS(td == curthread); curpcb = curthread->td_pcb; - if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) { /* * If we have just been running VFP instructions we will * need to save the state to memcpy it below. */ vfp_save_state(td, curpcb); - - KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, - ("Called get_fpcontext while the kernel is using the VFP")); - KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0, - ("Non-userspace FPU flags set in get_fpcontext")); - memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_fpustate.vfp_regs, - sizeof(mcp->mc_fpregs.fp_q)); - mcp->mc_fpregs.fp_cr = curpcb->pcb_fpustate.vfp_fpcr; - mcp->mc_fpregs.fp_sr = curpcb->pcb_fpustate.vfp_fpsr; - mcp->mc_fpregs.fp_flags = curpcb->pcb_fpflags; - mcp->mc_flags |= _MC_FP_VALID; } - critical_exit(); + KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, + ("Called get_fpcontext while the kernel is using the VFP")); + KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0, + ("Non-userspace FPU flags set in get_fpcontext")); + memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_fpustate.vfp_regs, + sizeof(mcp->mc_fpregs.fp_q)); + mcp->mc_fpregs.fp_cr = curpcb->pcb_fpustate.vfp_fpcr; + mcp->mc_fpregs.fp_sr = curpcb->pcb_fpustate.vfp_fpsr; + mcp->mc_fpregs.fp_flags = curpcb->pcb_fpflags; + mcp->mc_flags |= _MC_FP_VALID; #endif } |