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 _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"