git: 95dd6974b591 - main - Always read the VFP regs in the arm64 fill_fpregs
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 18 Jan 2023 09:39:48 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=95dd6974b591ce76bf8d29adcc0dd01b4b281ffd commit 95dd6974b591ce76bf8d29adcc0dd01b4b281ffd Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2023-01-18 09:30:20 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2023-01-18 09:31:35 +0000 Always read the VFP regs in the arm64 fill_fpregs The PCB_FP_STARTED is used to indicate that the current VFP context has been used since either 1. the start of the thread, or 2. exiting a kernel FP context. When case 2 was added to the kernel this could cause incorrect results to be returned when a thread exits the kernel FP context and fill_fpregs is called before it has restored the VFP state, e.g. by trappin on a userspace VFP instruction. In both of the cases the base save area is still valid so reduce the use of the PCB_FP_STARTED flag check to help decide if we need to store the current threads VFP state. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D37994 --- sys/arm64/arm64/exec_machdep.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c index 6109a866a2d0..12c23149ec7f 100644 --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -153,16 +153,17 @@ fill_fpregs(struct thread *td, struct fpreg *regs) */ if (td == curthread) vfp_save_state(td, pcb); + } - KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, - ("Called fill_fpregs while the kernel is using the VFP")); - memcpy(regs->fp_q, pcb->pcb_fpustate.vfp_regs, - sizeof(regs->fp_q)); - regs->fp_cr = pcb->pcb_fpustate.vfp_fpcr; - regs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; - } else + KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, + ("Called fill_fpregs while the kernel is using the VFP")); + memcpy(regs->fp_q, pcb->pcb_fpustate.vfp_regs, + sizeof(regs->fp_q)); + regs->fp_cr = pcb->pcb_fpustate.vfp_fpcr; + regs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; +#else + memset(regs, 0, sizeof(*regs)); #endif - memset(regs, 0, sizeof(*regs)); return (0); }