The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=95dd6974b591ce76bf8d29adcc0dd01b4b281ffd

commit 95dd6974b591ce76bf8d29adcc0dd01b4b281ffd
Author:     Andrew Turner <and...@freebsd.org>
AuthorDate: 2023-01-18 09:30:20 +0000
Commit:     Andrew Turner <and...@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);
 }
 

Reply via email to