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
_______________________________________________
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"

Reply via email to