git: bd011976c6cf - stable/13 - Always read the VFP regs in the arm64 fill_fpregs
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 15 May 2023 15:45:59 UTC
The branch stable/13 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=bd011976c6cf769baa04c55e48d9cda8a2ba60be commit bd011976c6cf769baa04c55e48d9cda8a2ba60be Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2023-01-18 09:30:20 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2023-05-15 10:54:21 +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 (cherry picked from commit 95dd6974b591ce76bf8d29adcc0dd01b4b281ffd) --- 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 cc589731ae6a..a55048461682 100644 --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -147,16 +147,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); }