Index: src/lib/libc/tls/tls.c
===================================================================
RCS file: /home/chs/netbsd/cvs/src/lib/libc/tls/tls.c,v
retrieving revision 1.7
diff -u -p -r1.7 tls.c
--- src/lib/libc/tls/tls.c      19 Aug 2013 22:14:37 -0000      1.7
+++ src/lib/libc/tls/tls.c      20 Nov 2014 21:29:30 -0000
@@ -155,15 +155,6 @@ __libc_static_tls_setup(void)
       struct tls_tcb *tcb;

       if (&rtld_DYNAMIC != NULL) {
-#ifdef __powerpc__
-               /*
-                * Old powerpc crt0's are going to overwrite r2 so we need to
-                * restore it but only do so if the saved value isn't NULL (if
-                * it is NULL, ld.elf_so doesn't have the matching change).
-                */
-               if ((tcb = _lwp_getprivate()) != NULL)
-                       __lwp_settcb(tcb);
-#endif
               return;
       }

Index: src/libexec/ld.elf_so/tls.c
===================================================================
RCS file: /home/chs/netbsd/cvs/src/libexec/ld.elf_so/tls.c,v
retrieving revision 1.9
diff -u -p -r1.9 tls.c
--- src/libexec/ld.elf_so/tls.c 21 Oct 2013 19:14:15 -0000      1.9
+++ src/libexec/ld.elf_so/tls.c 20 Nov 2014 21:29:18 -0000
@@ -106,13 +106,6 @@ _rtld_tls_initial_allocation(void)
       tcb = _rtld_tls_allocate_locked();
#ifdef __HAVE___LWP_SETTCB
       __lwp_settcb(tcb);
-#ifdef __powerpc__
-       /*
-        * Save the tcb pointer so that libc can retrieve it.  Older
-        * crt0 will obliterate r2 so there is code in libc to restore it.
-        */
-       _lwp_setprivate(tcb);
-#endif
#else
       _lwp_setprivate(tcb);
#endif
Index: src/sys/arch/powerpc/include/types.h
===================================================================
RCS file: /home/chs/netbsd/cvs/src/sys/arch/powerpc/include/types.h,v
retrieving revision 1.49
diff -u -p -r1.49 types.h
--- src/sys/arch/powerpc/include/types.h        18 Mar 2014 18:20:41 -0000      1.49
+++ src/sys/arch/powerpc/include/types.h        21 Nov 2014 05:30:10 -0000
@@ -81,6 +81,7 @@ typedef volatile int __cpu_simple_lock_t
#ifdef _LP64
#define        __HAVE_ATOMIC64_OPS
#endif
+#define        __HAVE_CPU_LWP_SETPRIVATE
#define        __HAVE_COMMON___TLS_GET_ADDR
#define        __HAVE___LWP_GETTCB_FAST
#define        __HAVE___LWP_SETTCB
Index: src/sys/arch/powerpc/powerpc/sig_machdep.c
===================================================================
RCS file: /home/chs/netbsd/cvs/src/sys/arch/powerpc/powerpc/sig_machdep.c,v
retrieving revision 1.43
diff -u -p -r1.43 sig_machdep.c
--- src/sys/arch/powerpc/powerpc/sig_machdep.c  11 Sep 2012 00:15:19 -0000      1.43
+++ src/sys/arch/powerpc/powerpc/sig_machdep.c  20 Nov 2014 21:36:37 -0000
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: sig_machdep.
#include <sys/syscallargs.h>
#include <sys/systm.h>
#include <sys/ucontext.h>
+#include <sys/cpu.h>

#include <uvm/uvm_extern.h>

@@ -172,8 +173,7 @@ cpu_getmcontext(struct lwp *l, mcontext_
#endif

       *flagp |= _UC_CPU;
-       if (gr[_REG_R2] == (uintptr_t)l->l_private)
-               *flagp |= _UC_TLSBASE;
+       *flagp |= _UC_TLSBASE;

#ifdef PPC_HAVE_FPU
       /* Save FPU context, if any. */
@@ -231,17 +231,6 @@ cpu_setmcontext(struct lwp *l, const mco
#ifdef PPC_OEA
               tf->tf_mq = gr[_REG_MQ];
#endif
-               /*
-                * If R2 contains the TLS base, make sure to update l->l_private.
-                * If not, restore R2 from l->l_private if not null.  Since setcontext
-                * existed before the TCB code, a static program could expect R2 to
-                * the small data pointer.
-                */
-               if (flags & _UC_TLSBASE) {
-                       l->l_private = (void *) tf->tf_fixreg[_REG_R2];
-               } else if (l->l_private) {
-                       tf->tf_fixreg[_REG_R2] = (uintptr_t)l->l_private;
-               }
       }

#ifdef PPC_HAVE_FPU
@@ -264,3 +253,12 @@ cpu_setmcontext(struct lwp *l, const mco

       return (0);
}
+
+int
+cpu_lwp_setprivate(lwp_t *l, void *addr)
+{
+       struct trapframe * const tf = l->l_md.md_utf;
+
+       tf->tf_fixreg[_REG_R2] = (register_t)addr;
+       return 0;
+}