git: 12257233e8fd - main - arm64: Split out a savectx version of vfp_save_state
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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;