svn commit: r198724 - head/sys/powerpc/aim

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat Oct 31 17:59:25 UTC 2009


Author: nwhitehorn
Date: Sat Oct 31 17:59:24 2009
New Revision: 198724
URL: http://svn.freebsd.org/changeset/base/198724

Log:
  Fix a race in casuword() exposed by csup. casuword() non-atomically read
  the current value of its argument before atomically replacing it, which
  could occasionally return the wrong value on an SMP system. This resulted
  in user mutex operations hanging when using threaded applications.

Modified:
  head/sys/powerpc/aim/copyinout.c

Modified: head/sys/powerpc/aim/copyinout.c
==============================================================================
--- head/sys/powerpc/aim/copyinout.c	Sat Oct 31 17:55:48 2009	(r198723)
+++ head/sys/powerpc/aim/copyinout.c	Sat Oct 31 17:59:24 2009	(r198724)
@@ -347,8 +347,19 @@ casuword(volatile u_long *addr, u_long o
 		return (-1);
 	}
 
-	val = *p;
-	(void) atomic_cmpset_32((volatile uint32_t *)p, old, new);
+	__asm __volatile (
+		"1:\tlwarx %0, 0, %2\n\t"	/* load old value */
+		"cmplw %3, %0\n\t"		/* compare */
+		"bne 2f\n\t"			/* exit if not equal */
+		"stwcx. %4, 0, %2\n\t"      	/* attempt to store */
+		"bne- 1b\n\t"			/* spin if failed */
+		"b 3f\n\t"			/* we've succeeded */
+		"2:\n\t"
+		"stwcx. %0, 0, %2\n\t"       	/* clear reservation (74xx) */
+		"3:\n\t"
+		: "=&r" (val), "=m" (*p)
+		: "r" (p), "r" (old), "r" (new), "m" (*p)
+		: "cc", "memory");
 
 	td->td_pcb->pcb_onfault = NULL;
 


More information about the svn-src-head mailing list