svn commit: r286225 - in head/sys/arm64: arm64 include
Andrew Turner
andrew at FreeBSD.org
Mon Aug 3 11:05:05 UTC 2015
Author: andrew
Date: Mon Aug 3 11:05:02 2015
New Revision: 286225
URL: https://svnweb.freebsd.org/changeset/base/286225
Log:
Pass the pcb to store the vfp state in to vfp_save_state. This fixes a bug
in savectx where it will be used to store the current state however will
pass in a pcb when vfp_save_state expected a thread pointer.
Obtained from: ABT Systems Ltd
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/arm64/arm64/machdep.c
head/sys/arm64/arm64/swtch.S
head/sys/arm64/arm64/vfp.c
head/sys/arm64/arm64/vm_machdep.c
head/sys/arm64/include/vfp.h
Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c Mon Aug 3 10:10:49 2015 (r286224)
+++ head/sys/arm64/arm64/machdep.c Mon Aug 3 11:05:02 2015 (r286225)
@@ -180,7 +180,7 @@ fill_fpregs(struct thread *td, struct fp
* If we have just been running VFP instructions we will
* need to save the state to memcpy it below.
*/
- vfp_save_state(td);
+ vfp_save_state(td, pcb);
memcpy(regs->fp_q, pcb->pcb_vfp, sizeof(regs->fp_q));
regs->fp_cr = pcb->pcb_fpcr;
@@ -314,7 +314,7 @@ get_fpcontext(struct thread *td, mcontex
* If we have just been running VFP instructions we will
* need to save the state to memcpy it below.
*/
- vfp_save_state(td);
+ vfp_save_state(td, curpcb);
memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_vfp,
sizeof(mcp->mc_fpregs));
Modified: head/sys/arm64/arm64/swtch.S
==============================================================================
--- head/sys/arm64/arm64/swtch.S Mon Aug 3 10:10:49 2015 (r286224)
+++ head/sys/arm64/arm64/swtch.S Mon Aug 3 11:05:02 2015 (r286225)
@@ -131,6 +131,8 @@ ENTRY(cpu_switch)
mov x19, x0
mov x20, x1
mov x21, x2
+ /* Load the pcb address */
+ mov x1, x4
bl vfp_save_state
mov x2, x21
mov x1, x20
@@ -268,9 +270,11 @@ ENTRY(savectx)
/* Store the VFP registers */
#ifdef VFP
- mov x29, lr
+ mov x28, lr
+ mov x1, x0 /* move pcb to the correct register */
+ mov x0, xzr /* td = NULL */
bl vfp_save_state
- mov lr, x29
+ mov lr, x28
#endif
ret
Modified: head/sys/arm64/arm64/vfp.c
==============================================================================
--- head/sys/arm64/arm64/vfp.c Mon Aug 3 10:10:49 2015 (r286224)
+++ head/sys/arm64/arm64/vfp.c Mon Aug 3 11:05:02 2015 (r286225)
@@ -82,12 +82,18 @@ vfp_discard(struct thread *td)
}
void
-vfp_save_state(struct thread *td)
+vfp_save_state(struct thread *td, struct pcb *pcb)
{
__int128_t *vfp_state;
uint64_t fpcr, fpsr;
uint32_t cpacr;
+ KASSERT(pcb != NULL, ("NULL vfp pcb"));
+ KASSERT(td == NULL || td->td_pcb == pcb, ("Invalid vfp pcb"));
+
+ if (td == NULL)
+ td = curthread;
+
critical_enter();
/*
* Only store the registers if the VFP is enabled,
@@ -98,7 +104,7 @@ vfp_save_state(struct thread *td)
KASSERT(PCPU_GET(fpcurthread) == td,
("Storing an invalid VFP state"));
- vfp_state = td->td_pcb->pcb_vfp;
+ vfp_state = pcb->pcb_vfp;
__asm __volatile(
"mrs %0, fpcr \n"
"mrs %1, fpsr \n"
@@ -120,8 +126,8 @@ vfp_save_state(struct thread *td)
"stp q30, q31, [%2, #16 * 30]\n"
: "=&r"(fpcr), "=&r"(fpsr) : "r"(vfp_state));
- td->td_pcb->pcb_fpcr = fpcr;
- td->td_pcb->pcb_fpsr = fpsr;
+ pcb->pcb_fpcr = fpcr;
+ pcb->pcb_fpsr = fpsr;
dsb(ish);
vfp_disable();
Modified: head/sys/arm64/arm64/vm_machdep.c
==============================================================================
--- head/sys/arm64/arm64/vm_machdep.c Mon Aug 3 10:10:49 2015 (r286224)
+++ head/sys/arm64/arm64/vm_machdep.c Mon Aug 3 11:05:02 2015 (r286225)
@@ -74,7 +74,7 @@ cpu_fork(struct thread *td1, struct proc
td1->td_pcb->pcb_tpidr_el0 = READ_SPECIALREG(tpidr_el0);
#ifdef VFP
if ((td1->td_pcb->pcb_fpflags & PCB_FP_STARTED) != 0)
- vfp_save_state(td1);
+ vfp_save_state(td1, td1->td_pcb);
#endif
}
Modified: head/sys/arm64/include/vfp.h
==============================================================================
--- head/sys/arm64/include/vfp.h Mon Aug 3 10:10:49 2015 (r286224)
+++ head/sys/arm64/include/vfp.h Mon Aug 3 11:05:02 2015 (r286225)
@@ -38,7 +38,7 @@
void vfp_init(void);
void vfp_discard(struct thread *);
void vfp_restore_state(void);
-void vfp_save_state(struct thread *);
+void vfp_save_state(struct thread *, struct pcb *);
#endif
#endif
More information about the svn-src-all
mailing list