Module Name:    src
Committed By:   snj
Date:           Wed May 13 00:35:16 UTC 2009

Modified Files:
        src/sys/arch/amd64/amd64 [netbsd-5]: lock_stubs.S
        src/sys/arch/i386/i386 [netbsd-5]: lock_stubs.S
        src/sys/arch/x86/x86 [netbsd-5]: patch.c

Log Message:
Pull up following revision(s) (requested by ad in ticket #725):
        sys/arch/amd64/amd64/lock_stubs.S: revision 1.22
        sys/arch/i386/i386/lock_stubs.S: revision 1.23
        sys/arch/x86/x86/patch.c: revision 1.18
A workaround for a bug with some Opteron revisions where locked operations
sometimes do not serve as memory barriers, allowing memory references to
bleed outside of critical sections.  It is possible that this is the
reason for pkgbuild's longstanding crashiness.
This is not complete (atomic ops need some work too).


To generate a diff of this commit:
cvs rdiff -u -r1.20.6.1 -r1.20.6.2 src/sys/arch/amd64/amd64/lock_stubs.S
cvs rdiff -u -r1.21.6.1 -r1.21.6.2 src/sys/arch/i386/i386/lock_stubs.S
cvs rdiff -u -r1.14.4.3 -r1.14.4.4 src/sys/arch/x86/x86/patch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/lock_stubs.S
diff -u src/sys/arch/amd64/amd64/lock_stubs.S:1.20.6.1 src/sys/arch/amd64/amd64/lock_stubs.S:1.20.6.2
--- src/sys/arch/amd64/amd64/lock_stubs.S:1.20.6.1	Mon Feb  2 03:01:12 2009
+++ src/sys/arch/amd64/amd64/lock_stubs.S	Wed May 13 00:35:16 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: lock_stubs.S,v 1.20.6.1 2009/02/02 03:01:12 snj Exp $	*/
+/*	$NetBSD: lock_stubs.S,v 1.20.6.2 2009/05/13 00:35:16 snj Exp $	*/
 
 /*-
- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -48,6 +48,7 @@
 
 #define	ENDLABEL(name,a) .align	a; LABEL(name)
 #define	LOCK(num)	.Lpatch/**/num: lock
+#define	RET(num)	.Lret/**/num: ret; nop; nop; ret
 
 #ifndef LOCKDEBUG
 
@@ -64,7 +65,7 @@
 	LOCK(1)
 	cmpxchgq %rcx, (%rdi)
 	jnz	1f
-	ret
+	RET(1)
 1:
 	jmp	_C_LABEL(mutex_vector_enter)
 
@@ -106,7 +107,7 @@
 	testb	%al, %al
 	jnz	1f
 #endif
-	ret
+	RET(2)
 1:
 	jmp	_C_LABEL(mutex_spin_retry)	/* failed; hard case */
 
@@ -186,7 +187,7 @@
 	LOCK(2)
 	cmpxchgq %rdx, (%rdi)
 	jnz	1f
-	ret
+	RET(3)
 1:
 	jmp	0b
 
@@ -199,7 +200,7 @@
 	LOCK(3)
 	cmpxchgq %rcx, (%rdi)
 	jnz	3f
-	ret
+	RET(4)
 3:
 	jmp	_C_LABEL(rw_vector_enter)
 
@@ -256,13 +257,13 @@
 	movq	(%rdi), %rax
 0:
 	testb	$(RW_WRITE_LOCKED|RW_WRITE_WANTED), %al
-	jnz	3f
+	jnz	4f
 	leaq	RW_READ_INCR(%rax), %rdx 
 	LOCK(8)
 	cmpxchgq %rdx, (%rdi)
 	jnz	1f
 	movl	%edx, %eax			/* nonzero */
-	ret
+	RET(5)
 1:
 	jmp	0b
 
@@ -276,10 +277,12 @@
 	cmpxchgq %rcx, (%rdi)
 	movl	$0, %eax
 	setz	%al
+3:
+	RET(6)
 	ret
-
-3:	xorl	%eax, %eax
-	ret
+4:
+	xorl	%eax, %eax
+	jmp	3b
 
 #endif	/* LOCKDEBUG */
 
@@ -296,7 +299,7 @@
 	LOCK(6)
 	cmpxchgb %ah, (%rdi)
 	jnz	2f
-	ret
+	RET(7)
 2:
 	movl	$0x0100, %eax
 	pause
@@ -315,8 +318,8 @@
 	LOCK(7)
 	cmpxchgb %ah, (%rdi)
 	movl	$0, %eax
-	setz	%al	
-	ret
+	setz	%al
+	RET(8)
 
 /*
  * Patchpoints to replace with NOP when ncpu == 1.
@@ -328,3 +331,10 @@
 	.quad	.Lpatch9
 	.quad	0
 #endif
+
+LABEL(x86_retpatch)
+#ifndef LOCKDEBUG
+	.long	.Lret1, .Lret2, .Lret3, .Lret4, .Lret5, .Lret6
+#endif
+	.long	.Lret7, .Lret8
+	.long	0

Index: src/sys/arch/i386/i386/lock_stubs.S
diff -u src/sys/arch/i386/i386/lock_stubs.S:1.21.6.1 src/sys/arch/i386/i386/lock_stubs.S:1.21.6.2
--- src/sys/arch/i386/i386/lock_stubs.S:1.21.6.1	Mon Feb  2 03:01:12 2009
+++ src/sys/arch/i386/i386/lock_stubs.S	Wed May 13 00:35:16 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: lock_stubs.S,v 1.21.6.1 2009/02/02 03:01:12 snj Exp $	*/
+/*	$NetBSD: lock_stubs.S,v 1.21.6.2 2009/05/13 00:35:16 snj Exp $	*/
 
 /*-
- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -35,7 +35,7 @@
  */
 
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: lock_stubs.S,v 1.21.6.1 2009/02/02 03:01:12 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lock_stubs.S,v 1.21.6.2 2009/05/13 00:35:16 snj Exp $");
 
 #include "opt_lockdebug.h"
 
@@ -46,6 +46,7 @@
 #define	ALIGN64		.align	64
 #define	ALIGN32		.align	32
 #define	LOCK(num)	.Lpatch/**/num:	lock
+#define	RET(num)	.Lret/**/num: ret; nop; nop; ret
 #define	ENDLABEL(name,a) .align	a; LABEL(name)
 
 #if !defined(LOCKDEBUG)
@@ -59,12 +60,12 @@
 
 ENTRY(mutex_enter)
 	movl	4(%esp), %edx
-	movl	CPUVAR(CURLWP), %ecx
 	xorl	%eax, %eax
+	movl	%fs:CPU_INFO_CURLWP(%eax), %ecx
 	LOCK(1)
 	cmpxchgl %ecx, (%edx)
 	jnz	1f
-	ret
+	RET(1)
 1:
 	jmp	_C_LABEL(mutex_vector_enter)
 END(mutex_enter)
@@ -80,8 +81,8 @@
  */
 ENTRY(mutex_exit)
 	movl	4(%esp), %edx
-	movl	CPUVAR(CURLWP), %eax
 	xorl	%ecx, %ecx
+	movl	%fs:CPU_INFO_CURLWP(%ecx), %eax
 	cmpxchgl %ecx, (%edx)
 	jnz	1f
 	ret
@@ -110,20 +111,20 @@
 	LOCK(2)
 	cmpxchgl %ecx, (%edx)
 	jnz	1f
-	ret
+	RET(2)
 1:
 	jmp	0b
 
 	/*
 	 * Writer
 	 */
-2:	movl	CPUVAR(CURLWP), %ecx
-	xorl	%eax, %eax
+2:	xorl	%eax, %eax
+	movl	%fs:CPU_INFO_CURLWP(%eax), %ecx
 	orl	$RW_WRITE_LOCKED, %ecx
 	LOCK(3)
 	cmpxchgl %ecx, (%edx)
 	jnz	3f
-	ret
+	RET(3)
 3:
 	jmp	_C_LABEL(rw_vector_enter)
 END(rw_enter)
@@ -187,13 +188,13 @@
 	movl	(%edx), %eax
 0:
 	testb	$(RW_WRITE_LOCKED|RW_WRITE_WANTED), %al
-	jnz	3f
+	jnz	4f
 	leal	RW_READ_INCR(%eax), %ecx
 	LOCK(12)
 	cmpxchgl %ecx, (%edx)
 	jnz	1f
 	movl	%edx, %eax			/* nonzero */
-	ret
+	RET(4)
 1:
 	jmp	0b
 
@@ -201,17 +202,18 @@
 	 * Writer
 	 */
 2:
-	movl	CPUVAR(CURLWP), %ecx
-	orl	$RW_WRITE_LOCKED, %ecx
 	xorl	%eax, %eax
+	movl	%fs:CPU_INFO_CURLWP(%eax), %ecx
+	orl	$RW_WRITE_LOCKED, %ecx
 	LOCK(13)
 	cmpxchgl %ecx, (%edx)
 	movl	$0, %eax
 	setz	%al
-	ret
 3:
+	RET(5)
+4:
 	xorl	%eax, %eax
-	ret
+	jmp	3b
 END(rw_tryenter)
 
 #ifndef __XEN__
@@ -237,7 +239,7 @@
 	xchgb	%al, MTX_LOCK(%edx)		/* lock it */
 	testb	%al, %al
 	jnz	3f
-	ret
+	RET(6)
 3:
 	jmp	_C_LABEL(mutex_spin_retry)
 
@@ -326,7 +328,7 @@
 	LOCK(6)
 	cmpxchgb %ah, (%edx)
 	jnz	2f
-	ret
+	RET(7)
 2:
 	movl	$0x0100, %eax
 	pause
@@ -350,7 +352,7 @@
 	cmpxchgb %ah, (%edx)
 	movl	$0, %eax
 	setz	%al	
-	ret
+	RET(8)
 END(__cpu_simple_lock_try)
 
 /*
@@ -365,3 +367,13 @@
 	.long	.Lpatch13
 	.long	0
 #endif
+
+LABEL(x86_retpatch)
+#ifndef LOCKDEBUG
+	.long	.Lret1, .Lret2, .Lret3, .Lret4, .Lret5
+#ifndef __XEN__
+	.long	.Lret6
+#endif
+#endif
+	.long	.Lret7, .Lret8
+	.long	0

Index: src/sys/arch/x86/x86/patch.c
diff -u src/sys/arch/x86/x86/patch.c:1.14.4.3 src/sys/arch/x86/x86/patch.c:1.14.4.4
--- src/sys/arch/x86/x86/patch.c:1.14.4.3	Fri Apr  3 17:42:36 2009
+++ src/sys/arch/x86/x86/patch.c	Wed May 13 00:35:16 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: patch.c,v 1.14.4.3 2009/04/03 17:42:36 snj Exp $	*/
+/*	$NetBSD: patch.c,v 1.14.4.4 2009/05/13 00:35:16 snj Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.14.4.3 2009/04/03 17:42:36 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.14.4.4 2009/05/13 00:35:16 snj Exp $");
 
 #include "opt_lockdebug.h"
 
@@ -74,6 +74,7 @@
 void	_atomic_cas_cx8_end(void);
 
 extern void	*x86_lockpatch[];
+extern void	*x86_retpatch[];
 extern void	*atomic_lockpatch[];
 
 #define	X86_NOP		0x90
@@ -124,12 +125,14 @@
 }
 
 static inline void __unused
-patchbytes(void *addr, const int byte1, const int byte2)
+patchbytes(void *addr, const int byte1, const int byte2, const int byte3)
 {
 
 	((uint8_t *)addr)[0] = (uint8_t)byte1;
 	if (byte2 != -1)
 		((uint8_t *)addr)[1] = (uint8_t)byte2;
+	if (byte3 != -1)
+		((uint8_t *)addr)[2] = (uint8_t)byte3;
 }
 
 void
@@ -138,6 +141,7 @@
 	static bool first, second;
 	u_long psl;
 	u_long cr0;
+	int i;
 
 	if (early) {
 		if (first)
@@ -160,13 +164,11 @@
 #if !defined(GPROF)
 	if (!early && ncpu == 1) {
 #ifndef LOCKDEBUG
-		int i;
-
 		/* Uniprocessor: kill LOCK prefixes. */
 		for (i = 0; x86_lockpatch[i] != 0; i++)
-			patchbytes(x86_lockpatch[i], X86_NOP, -1);	
+			patchbytes(x86_lockpatch[i], X86_NOP, -1, -1);
 		for (i = 0; atomic_lockpatch[i] != 0; i++)
-			patchbytes(atomic_lockpatch[i], X86_NOP, -1);
+			patchbytes(atomic_lockpatch[i], X86_NOP, -1, -1);
 #endif	/* !LOCKDEBUG */
 	}
 	if (!early && (cpu_feature & CPUID_SSE2) != 0) {
@@ -214,6 +216,21 @@
 #endif	/* !LOCKDEBUG */
 	}
 
+	/*
+	 * On some Opteron revisions, locked operations erroneously
+	 * allow memory references to be `bled' outside of critical
+	 * sections.  Apply workaround.
+	 */
+	if (cpu_vendor == CPUVENDOR_AMD &&
+	    (CPUID2FAMILY(cpu_info_primary.ci_signature) == 0xe ||
+	    (CPUID2FAMILY(cpu_info_primary.ci_signature) == 0xf &&
+	    CPUID2EXTMODEL(cpu_info_primary.ci_signature) < 0x4))) {
+		for (i = 0; x86_retpatch[i] != 0; i++) {
+			/* ret,nop,nop,ret -> lfence,ret */
+			patchbytes(x86_retpatch[i], 0x0f, 0xae, 0xe8);
+		}
+	}
+
 	/* Write back and invalidate cache, flush pipelines. */
 	wbinvd();
 	x86_flush();

Reply via email to