Date: Wed, 15 Apr 2015 14:30:08 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281557 - head/sys/arm64/arm64 Message-ID: <201504151430.t3FEU8Xk001183@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andrew Date: Wed Apr 15 14:30:07 2015 New Revision: 281557 URL: https://svnweb.freebsd.org/changeset/base/281557 Log: Enter a critical section when storing the vfp registers, we don't want to be preempted here as this will enter back into this function, but the hardware could be in an inconsistant state, and the vfp unit will be off when switced back to this function. Sponsored by: The FreeBSD Foundation Modified: head/sys/arm64/arm64/vfp.c Modified: head/sys/arm64/arm64/vfp.c ============================================================================== --- head/sys/arm64/arm64/vfp.c Wed Apr 15 14:20:12 2015 (r281556) +++ head/sys/arm64/arm64/vfp.c Wed Apr 15 14:30:07 2015 (r281557) @@ -88,41 +88,42 @@ vfp_save_state(struct thread *td) uint64_t fpcr, fpsr; uint32_t cpacr; + critical_enter(); /* * Only store the registers if the VFP is enabled, * i.e. return if we are trapping on FP access. */ cpacr = READ_SPECIALREG(cpacr_el1); - if ((cpacr & CPACR_FPEN_MASK) != CPACR_FPEN_TRAP_NONE) - return; - - vfp_state = td->td_pcb->pcb_vfp; - __asm __volatile( - "mrs %0, fpcr \n" - "mrs %1, fpsr \n" - "stp q0, q1, [%2, #16 * 0]\n" - "stp q2, q3, [%2, #16 * 2]\n" - "stp q4, q5, [%2, #16 * 4]\n" - "stp q6, q7, [%2, #16 * 6]\n" - "stp q8, q9, [%2, #16 * 8]\n" - "stp q10, q11, [%2, #16 * 10]\n" - "stp q12, q13, [%2, #16 * 12]\n" - "stp q14, q15, [%2, #16 * 14]\n" - "stp q16, q17, [%2, #16 * 16]\n" - "stp q18, q19, [%2, #16 * 18]\n" - "stp q20, q21, [%2, #16 * 20]\n" - "stp q22, q23, [%2, #16 * 22]\n" - "stp q24, q25, [%2, #16 * 24]\n" - "stp q26, q27, [%2, #16 * 26]\n" - "stp q28, q29, [%2, #16 * 28]\n" - "stp q30, q31, [%2, #16 * 30]\n" - : "=&r"(fpcr), "=&r"(fpsr) : "r"(vfp_state)); + if ((cpacr & CPACR_FPEN_MASK) == CPACR_FPEN_TRAP_NONE) { + vfp_state = td->td_pcb->pcb_vfp; + __asm __volatile( + "mrs %0, fpcr \n" + "mrs %1, fpsr \n" + "stp q0, q1, [%2, #16 * 0]\n" + "stp q2, q3, [%2, #16 * 2]\n" + "stp q4, q5, [%2, #16 * 4]\n" + "stp q6, q7, [%2, #16 * 6]\n" + "stp q8, q9, [%2, #16 * 8]\n" + "stp q10, q11, [%2, #16 * 10]\n" + "stp q12, q13, [%2, #16 * 12]\n" + "stp q14, q15, [%2, #16 * 14]\n" + "stp q16, q17, [%2, #16 * 16]\n" + "stp q18, q19, [%2, #16 * 18]\n" + "stp q20, q21, [%2, #16 * 20]\n" + "stp q22, q23, [%2, #16 * 22]\n" + "stp q24, q25, [%2, #16 * 24]\n" + "stp q26, q27, [%2, #16 * 26]\n" + "stp q28, q29, [%2, #16 * 28]\n" + "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; + td->td_pcb->pcb_fpcr = fpcr; + td->td_pcb->pcb_fpsr = fpsr; - dsb(); - vfp_disable(); + dsb(); + vfp_disable(); + } + critical_exit(); } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504151430.t3FEU8Xk001183>