git: e005eea2c977 - stable/14 - arm64: Split out a savectx version of vfp_save_state

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Mon, 21 Oct 2024 15:05:07 UTC
The branch stable/14 has been updated by andrew:

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

commit e005eea2c977f8637071ee2b97501e21ce8f0de5
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-01-03 17:41:42 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-10-21 15:03:26 +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
    
    (cherry picked from commit 12257233e8fd94ab24e1a84ad87126af2a7be33b)
---
 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 be98af945b0a..f35cd960702b 100644
--- a/sys/arm64/arm64/vfp.c
+++ b/sys/arm64/arm64/vfp.c
@@ -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.
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;