svn commit: r234115 - in head: lib/libc/powerpc/gen lib/libc/powerpc64/gen sys/powerpc/powerpc

Nathan Whitehorn nwhitehorn at FreeBSD.org
Wed Apr 11 00:00:41 UTC 2012


Author: nwhitehorn
Date: Wed Apr 11 00:00:40 2012
New Revision: 234115
URL: http://svn.freebsd.org/changeset/base/234115

Log:
  Do not restore the register holding the TLS pointer when doing various
  usermode context switches (long jumps and ucontext operations). If these
  are used across threads, multiple threads can end up with the same TLS base.
  Madness will then result.
  
  This makes behavior on PPC match that on x86 systems and on Linux.
  
  MFC after:	10 days

Modified:
  head/lib/libc/powerpc/gen/_setjmp.S
  head/lib/libc/powerpc/gen/setjmp.S
  head/lib/libc/powerpc/gen/sigsetjmp.S
  head/lib/libc/powerpc64/gen/_setjmp.S
  head/lib/libc/powerpc64/gen/setjmp.S
  head/lib/libc/powerpc64/gen/sigsetjmp.S
  head/sys/powerpc/powerpc/exec_machdep.c

Modified: head/lib/libc/powerpc/gen/_setjmp.S
==============================================================================
--- head/lib/libc/powerpc/gen/_setjmp.S	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/lib/libc/powerpc/gen/_setjmp.S	Wed Apr 11 00:00:40 2012	(r234115)
@@ -63,7 +63,6 @@ ENTRY(_longjmp)
 	lmw	%r9,20(%r3)
 	mtlr	%r11
 	mtcr	%r12
-	mr	%r2,%r9
 	mr	%r1,%r10
 	or.	%r3,%r4,%r4
 	bnelr

Modified: head/lib/libc/powerpc/gen/setjmp.S
==============================================================================
--- head/lib/libc/powerpc/gen/setjmp.S	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/lib/libc/powerpc/gen/setjmp.S	Wed Apr 11 00:00:40 2012	(r234115)
@@ -75,7 +75,6 @@ ENTRY(__longjmp)
 	mr	%r6,%r4			/* save val param */
 	mtlr	%r11			/* r11 -> link reg */
 	mtcr	%r12			/* r12 -> condition reg */
-	mr	%r2,%r9			/* r9  -> global ptr */
 	mr	%r1,%r10		/* r10 -> stackptr */
 	mr	%r4,%r3
 	li	%r3,3			/* SIG_SETMASK */

Modified: head/lib/libc/powerpc/gen/sigsetjmp.S
==============================================================================
--- head/lib/libc/powerpc/gen/sigsetjmp.S	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/lib/libc/powerpc/gen/sigsetjmp.S	Wed Apr 11 00:00:40 2012	(r234115)
@@ -80,7 +80,6 @@ ENTRY(siglongjmp)
 	mr	%r6,%r4
 	mtlr	%r11
 	mtcr	%r12
-	mr	%r2,%r9
 	mr	%r1,%r10
 	or.	%r7,%r7,%r7
 	beq	1f

Modified: head/lib/libc/powerpc64/gen/_setjmp.S
==============================================================================
--- head/lib/libc/powerpc64/gen/_setjmp.S	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/lib/libc/powerpc64/gen/_setjmp.S	Wed Apr 11 00:00:40 2012	(r234115)
@@ -86,7 +86,6 @@ ENTRY(_longjmp)
 	ld	%r10,40 + 1*8(%r3)
 	ld	%r11,40 + 2*8(%r3)
 	ld	%r12,40 + 3*8(%r3)
-	ld	%r13,40 + 4*8(%r3)
 	ld	%r14,40 + 5*8(%r3)
 	ld	%r15,40 + 6*8(%r3)
 	ld	%r16,40 + 7*8(%r3)

Modified: head/lib/libc/powerpc64/gen/setjmp.S
==============================================================================
--- head/lib/libc/powerpc64/gen/setjmp.S	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/lib/libc/powerpc64/gen/setjmp.S	Wed Apr 11 00:00:40 2012	(r234115)
@@ -99,7 +99,6 @@ ENTRY(__longjmp)
 	ld	%r10,40 + 1*8(%r3)
 	ld	%r11,40 + 2*8(%r3)
 	ld	%r12,40 + 3*8(%r3)
-	ld	%r13,40 + 4*8(%r3)
 	ld	%r14,40 + 5*8(%r3)
 	ld	%r15,40 + 6*8(%r3)
 	ld	%r16,40 + 7*8(%r3)

Modified: head/lib/libc/powerpc64/gen/sigsetjmp.S
==============================================================================
--- head/lib/libc/powerpc64/gen/sigsetjmp.S	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/lib/libc/powerpc64/gen/sigsetjmp.S	Wed Apr 11 00:00:40 2012	(r234115)
@@ -103,7 +103,6 @@ ENTRY(siglongjmp)
 	ld	%r10,40 + 1*8(%r3)
 	ld	%r11,40 + 2*8(%r3)
 	ld	%r12,40 + 3*8(%r3)
-	ld	%r13,40 + 4*8(%r3)
 	ld	%r14,40 + 5*8(%r3)
 	ld	%r15,40 + 6*8(%r3)
 	ld	%r16,40 + 7*8(%r3)

Modified: head/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/exec_machdep.c	Tue Apr 10 22:46:40 2012	(r234114)
+++ head/sys/powerpc/powerpc/exec_machdep.c	Wed Apr 11 00:00:40 2012	(r234115)
@@ -441,6 +441,7 @@ set_mcontext(struct thread *td, const mc
 {
 	struct pcb *pcb;
 	struct trapframe *tf;
+	register_t tls;
 
 	pcb = td->td_pcb;
 	tf = td->td_frame;
@@ -448,16 +449,25 @@ set_mcontext(struct thread *td, const mc
 	if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp))
 		return (EINVAL);
 
-	#ifdef AIM
+#ifdef AIM
 	/*
 	 * Don't let the user set privileged MSR bits
 	 */
 	if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) {
 		return (EINVAL);
 	}
-	#endif
+#endif
 
+	/* Copy trapframe, preserving TLS pointer across context change */
+	if (SV_PROC_FLAG(td->td_proc, SV_LP64))
+		tls = tf->fixreg[13];
+	else
+		tls = tf->fixreg[2];
 	memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
+	if (SV_PROC_FLAG(td->td_proc, SV_LP64))
+		tf->fixreg[13] = tls;
+	else
+		tf->fixreg[2] = tls;
 
 #ifdef AIM
 	if (mcp->mc_flags & _MC_FP_VALID) {


More information about the svn-src-all mailing list