arm64: Split out a savectx version of vfp_save_state

Rather than try to detect when vfp_save_state is called by savectx use
a separate function that sets up the pcb as needed.

Reviewed by:	imp
Sponsored by:	Arm Ltd
Differential Revision:	https://reviews.freebsd.org/D43304

(cherry picked from commit 12257233e8fd94ab24e1a84ad87126af2a7be33b)
This commit is contained in:
Andrew Turner 2024-01-03 17:41:42 +00:00
parent 2db6ffac24
commit e005eea2c9
3 changed files with 28 additions and 19 deletions

View file

@ -270,9 +270,7 @@ ENTRY(savectx)
/* Store the VFP registers */
#ifdef VFP
mov x28, lr
mov x1, x0 /* move pcb to the correct register */
mov x0, xzr /* td = NULL */
bl vfp_save_state
bl vfp_save_state_savectx
mov lr, x28
#endif

View file

@ -170,25 +170,11 @@ vfp_restore(struct vfpstate *state)
: : "r"(fpcr), "r"(fpsr), "r"(vfp_state));
}
void
vfp_save_state(struct thread *td, struct pcb *pcb)
static void
vfp_save_state_common(struct thread *td, struct pcb *pcb)
{
uint32_t cpacr;
KASSERT(pcb != NULL, ("NULL vfp pcb"));
KASSERT(td == NULL || td->td_pcb == pcb, ("Invalid vfp pcb"));
/*
* savectx() will be called on panic with dumppcb as an argument,
* dumppcb doesn't have pcb_fpusaved set, so set it to save
* the VFP registers.
*/
if (pcb->pcb_fpusaved == NULL)
pcb->pcb_fpusaved = &pcb->pcb_fpustate;
if (td == NULL)
td = curthread;
critical_enter();
/*
* Only store the registers if the VFP is enabled,
@ -206,6 +192,30 @@ vfp_save_state(struct thread *td, struct pcb *pcb)
critical_exit();
}
void
vfp_save_state(struct thread *td, struct pcb *pcb)
{
KASSERT(td != NULL, ("NULL vfp thread"));
KASSERT(pcb != NULL, ("NULL vfp pcb"));
KASSERT(td->td_pcb == pcb, ("Invalid vfp pcb"));
vfp_save_state_common(td, pcb);
}
void
vfp_save_state_savectx(struct pcb *pcb)
{
/*
* savectx() will be called on panic with dumppcb as an argument,
* dumppcb doesn't have pcb_fpusaved set, so set it to save
* the VFP registers.
*/
MPASS(pcb->pcb_fpusaved == NULL);
pcb->pcb_fpusaved = &pcb->pcb_fpustate;
vfp_save_state_common(curthread, pcb);
}
/*
* Update the VFP state for a forked process or new thread. The PCB will
* have been copied from the old thread.

View file

@ -78,6 +78,7 @@ void vfp_new_thread(struct thread *, struct thread *, bool);
void vfp_reset_state(struct thread *, struct pcb *);
void vfp_restore_state(void);
void vfp_save_state(struct thread *, struct pcb *);
void vfp_save_state_savectx(struct pcb *);
struct fpu_kern_ctx;