Skip site navigation (1)Skip section navigation (2)
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>