diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2021-03-23 18:23:47 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2021-04-08 07:51:26 +0000 |
commit | d6a53211a716c987de76294cff32b652fe38bb09 (patch) | |
tree | 3f7452673ab909b0f3cff66e6ec516c5a1a6b914 | |
parent | 15dc713ceb57d0d61c1dc54b1d550da42d250730 (diff) | |
download | src-d6a53211a716c987de76294cff32b652fe38bb09.tar.gz src-d6a53211a716c987de76294cff32b652fe38bb09.zip |
Discard the arm64 VFP state before resetting it
When resetting the VFP state we need to discard any old state so we don't
try to save it on a context switch. Move this first so resetting the pcb
is safe to perform outside a critical section.
Reviewed by: arichardson
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D29401
-rw-r--r-- | sys/arm64/arm64/vfp.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c index 4935946d2430..9de27349fb8d 100644 --- a/sys/arm64/arm64/vfp.c +++ b/sys/arm64/arm64/vfp.c @@ -208,7 +208,15 @@ vfp_save_state(struct thread *td, struct pcb *pcb) void vfp_reset_state(struct thread *td, struct pcb *pcb) { + /* Discard the threads VFP state before resetting it */ critical_enter(); + vfp_discard(td); + critical_exit(); + + /* + * Clear the thread state. The VFP is disabled and is not the current + * VFP thread so we won't change any of these on context switch. + */ bzero(&pcb->pcb_fpustate.vfp_regs, sizeof(pcb->pcb_fpustate.vfp_regs)); KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, ("pcb_fpusaved should point to pcb_fpustate.")); @@ -216,8 +224,6 @@ vfp_reset_state(struct thread *td, struct pcb *pcb) pcb->pcb_fpustate.vfp_fpsr = 0; pcb->pcb_vfpcpu = UINT_MAX; pcb->pcb_fpflags = 0; - vfp_discard(td); - critical_exit(); } void |