git: a47fd6929fe2 - main - aarch64: Fix get_fpcontext32() to work on non-curthread.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 23 Mar 2022 20:33:18 UTC
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=a47fd6929fe2008e28e3e697e449fb0904258d04 commit a47fd6929fe2008e28e3e697e449fb0904258d04 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2022-03-23 20:33:06 +0000 Commit: John Baldwin <jhb@FreeBSD.org> 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