The branch main has been updated by jhb:

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

commit a47fd6929fe2008e28e3e697e449fb0904258d04
Author:     John Baldwin <[email protected]>
AuthorDate: 2022-03-23 20:33:06 +0000
Commit:     John Baldwin <[email protected]>
CommitDate: 2022-03-23 20:33:06 +0000

    aarch64: Fix get_fpcontext32() to work on non-curthread.
    
    Similar to fill_fpregs(), only invoke vfp_save_state() for curthread.
    
    While here, zero the buffer if FP hasn't been started to avoid leaking
    kernel stack memory.
    
    Reviewed by:    andrew, markj
    Sponsored by:   University of Cambridge, Google, Inc.
    Differential Revision:  https://reviews.freebsd.org/D34525
---
 sys/arm64/arm64/freebsd32_machdep.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/sys/arm64/arm64/freebsd32_machdep.c 
b/sys/arm64/arm64/freebsd32_machdep.c
index 98f0bf784326..c4bb515becf7 100644
--- a/sys/arm64/arm64/freebsd32_machdep.c
+++ b/sys/arm64/arm64/freebsd32_machdep.c
@@ -130,29 +130,33 @@ freebsd32_sysarch(struct thread *td, struct 
freebsd32_sysarch_args *uap)
 static void
 get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp)
 {
-       struct pcb *curpcb;
+       struct pcb *pcb;
        int i;
 
-       critical_enter();
-       curpcb = curthread->td_pcb;
+       KASSERT(td == curthread || TD_IS_SUSPENDED(td) ||
+           P_SHOULDSTOP(td->td_proc),
+           ("not suspended thread %p", td));
+
+       memset(mcp, 0, sizeof(*mcp));
+       pcb = td->td_pcb;
 
-       if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) {
+       if ((pcb->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);
+               if (td == curthread)
+                       vfp_save_state(td, pcb);
 
-               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"));
+               KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate,
+                   ("Called get_fpcontext32 while the kernel is using the 
VFP"));
+               KASSERT((pcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0,
+                   ("Non-userspace FPU flags set in get_fpcontext32"));
                for (i = 0; i < 32; i++)
-                       mcp->mcv_reg[i] = 
(uint64_t)curpcb->pcb_fpustate.vfp_regs[i];
-               mcp->mcv_fpscr = 
VFP_FPSCR_FROM_SRCR(curpcb->pcb_fpustate.vfp_fpcr,
-                               curpcb->pcb_fpustate.vfp_fpsr);
+                       mcp->mcv_reg[i] = 
(uint64_t)pcb->pcb_fpustate.vfp_regs[i];
+               mcp->mcv_fpscr = VFP_FPSCR_FROM_SRCR(pcb->pcb_fpustate.vfp_fpcr,
+                   pcb->pcb_fpustate.vfp_fpsr);
        }
- critical_exit();
 }
 
 static void

Reply via email to