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
This commit is contained in:
John Baldwin 2022-03-23 13:33:06 -07:00
parent b1cd03dd29
commit a47fd6929f

View File

@ -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));
if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) {
memset(mcp, 0, sizeof(*mcp));
pcb = td->td_pcb;
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