git: 12257233e8fd - main - arm64: Split out a savectx version of vfp_save_state

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Thu, 21 Mar 2024 10:13:46 UTC
The branch main has been updated by andrew:

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

commit 12257233e8fd94ab24e1a84ad87126af2a7be33b
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-01-03 17:41:42 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-03-21 10:13:24 +0000

    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
---
 sys/arm64/arm64/swtch.S |  4 +---
 sys/arm64/arm64/vfp.c   | 42 ++++++++++++++++++++++++++----------------
 sys/arm64/include/vfp.h |  1 +
 3 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/sys/arm64/arm64/swtch.S b/sys/arm64/arm64/swtch.S
index 4c9851da3dc6..9c43de3a9eae 100644
--- a/sys/arm64/arm64/swtch.S
+++ b/sys/arm64/arm64/swtch.S
@@ -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
 
diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c
index ced1a446f0a8..749d5b81bfc8 100644
--- a/sys/arm64/arm64/vfp.c
+++ b/sys/arm64/arm64/vfp.c
@@ -166,25 +166,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,
@@ -202,6 +188,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.
diff --git a/sys/arm64/include/vfp.h b/sys/arm64/include/vfp.h
index 8c3d56918822..7f4c86e7737d 100644
--- a/sys/arm64/include/vfp.h
+++ b/sys/arm64/include/vfp.h
@@ -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;