tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[RFC][PATCH] _UC_TLSBASE for all ports



Hi all

Summary of the previous episode: NetBSD's swapcontext restores the
thread_self pointer. When using swapcontext() on a context obtained 
from getcontext() in another thread, this makes two threads with the
same pthread_self, leading to chaos

Some ports have a workaround for this: unset _UC_TLSBASE from
ucontext_t's uc_flags. On alpha it is called _UC_UNIQUE. sh3
and poweropc have no such feature. sh3 always behave like if 
_UC_TLSBASE was set. powerpc always behave like if _UC_TLSBASE was not
set.

Attached is a patch that attempts to bring _UC_TLSBASE to all ports,
so that this useful feature gets machine independant.

I need help for powerpc. By default it does not restore the thread
context, which avoids the bug. Should we change its default to 
match the other ports? And anyone can help on the machine dependant
bit? How does it stores the pthread_self pointer?

-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: arch/alpha/alpha/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.340
diff -U 4 -r1.340 machdep.c
--- arch/alpha/alpha/machdep.c  13 Jun 2012 17:13:41 -0000      1.340
+++ arch/alpha/alpha/machdep.c  10 Aug 2012 16:23:59 -0000
@@ -1793,9 +1793,9 @@
        if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
            (void *) gr[_REG_PC])) != -1)
                gr[_REG_PC] = ras_pc;
 
-       *flags |= _UC_CPU | _UC_UNIQUE;
+       *flags |= _UC_CPU | _UC_TLSBASE;
 
        /* Save floating point register context, if any, and copy it. */
        if (fpu_used_p(l)) {
                fpu_save();
@@ -1840,9 +1840,9 @@
                        pcb->pcb_hw.apcb_usp = gr[_REG_SP];
                frame->tf_regs[FRAME_PC] = gr[_REG_PC];
                frame->tf_regs[FRAME_PS] = gr[_REG_PS];
        }
-       if (flags & _UC_UNIQUE)
+       if (flags & _UC_TLSBASE)
                lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_UNIQUE]);
        /* Restore floating point register context, if any. */
        if (flags & _UC_FPU) {
                /* If we have an FP register context, get rid of it. */
Index: arch/alpha/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/include/mcontext.h,v
retrieving revision 1.7
diff -U 4 -r1.7 mcontext.h
--- arch/alpha/include/mcontext.h       25 Feb 2011 14:07:12 -0000      1.7
+++ arch/alpha/include/mcontext.h       10 Aug 2012 16:23:59 -0000
@@ -93,8 +93,9 @@
 } mcontext_t;
 
 /* Machine-dependent uc_flags */
 #define _UC_UNIQUE     0x20    /* valid process-unique value in _REG_UNIQUE */
+#define _UC_TLSBASE    0x20    /* synonym of _UC_UNIQUE */
 
 #define _UC_MACHINE_SP(uc)     ((uc)->uc_mcontext.__gregs[_REG_SP])
 #define _UC_MACHINE_PC(uc)     ((uc)->uc_mcontext.__gregs[_REG_PC])
 #define _UC_MACHINE_INTRV(uc)  ((uc)->uc_mcontext.__gregs[_REG_V0])
Index: arch/powerpc/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/mcontext.h,v
retrieving revision 1.13
diff -U 4 -r1.13 mcontext.h
--- arch/powerpc/include/mcontext.h     12 Mar 2011 07:38:16 -0000      1.13
+++ arch/powerpc/include/mcontext.h     10 Aug 2012 16:24:01 -0000
@@ -114,8 +114,9 @@
 
 /* Machine-dependent uc_flags */
 #define        _UC_POWERPC_VEC 0x00010000      /* Vector Register File valid */
 #define        _UC_POWERPC_SPE 0x00020000      /* Vector Register File valid */
+#define        _UC_TLSBASE     0x00080000      /* thread context valid */
 
 #define _UC_MACHINE_SP(uc)     ((uc)->uc_mcontext.__gregs[_REG_R1])
 #define _UC_MACHINE_PC(uc)     ((uc)->uc_mcontext.__gregs[_REG_PC])
 #define _UC_MACHINE_INTRV(uc)  ((uc)->uc_mcontext.__gregs[_REG_R3])
Index: arch/sh3/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/include/mcontext.h,v
retrieving revision 1.9
diff -U 4 -r1.9 mcontext.h
--- arch/sh3/include/mcontext.h 25 Feb 2011 14:07:13 -0000      1.9
+++ arch/sh3/include/mcontext.h 10 Aug 2012 16:24:02 -0000
@@ -91,8 +91,9 @@
  * Machine dependent uc_flags
  */
 #define        _UC_SETSTACK            0x10000
 #define        _UC_CLRSTACK            0x20000
+#define _UC_TLSBASE            0x80000
 
 static __inline void *
 __lwp_getprivate_fast(void)
 {
Index: arch/sh3/sh3/sh3_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/sh3_machdep.c,v
retrieving revision 1.100
diff -U 4 -r1.100 sh3_machdep.c
--- arch/sh3/sh3/sh3_machdep.c  8 Jul 2012 20:14:12 -0000       1.100
+++ arch/sh3/sh3/sh3_machdep.c  10 Aug 2012 16:24:02 -0000
@@ -431,9 +431,9 @@
        if ((ras_pc = (__greg_t)ras_lookup(l->l_proc,
            (void *) gr[_REG_PC])) != -1)
                gr[_REG_PC] = ras_pc;
 
-       *flags |= _UC_CPU;
+       *flags |= (_UC_CPU|_UC_TLSBASE);
 
        /* FPU context is currently not handled by the kernel. */
        memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
 }
@@ -487,9 +487,10 @@
                tf->tf_r1     = gr[_REG_R1];
                tf->tf_r0     = gr[_REG_R0];
                tf->tf_r15    = gr[_REG_R15];
 
-               lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_GBR]);
+               if (flags & _UC_TLSBASE)
+                       lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_GBR]);
        }
 
 #if 0
        /* XXX: FPU context is currently not handled by the kernel. */
Index: arch/sparc/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/include/mcontext.h,v
retrieving revision 1.12
diff -U 4 -r1.12 mcontext.h
--- arch/sparc/include/mcontext.h       25 Feb 2011 14:07:13 -0000      1.12
+++ arch/sparc/include/mcontext.h       10 Aug 2012 16:24:02 -0000
@@ -33,8 +33,9 @@
 #define _SPARC_MCONTEXT_H_
 
 #define _UC_SETSTACK   0x00010000
 #define _UC_CLRSTACK   0x00020000
+#define _UC_TLSBASE    0x00080000
 
 /*
  * Layout of mcontext_t according the System V Application Binary Interface,
  * Edition 4.1, SPARC Processor ABI Supplement and updated for SPARC v9.
Index: arch/sparc64/include/mcontext.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/include/mcontext.h,v
retrieving revision 1.8
diff -U 4 -r1.8 mcontext.h
--- arch/sparc64/include/mcontext.h     16 Mar 2006 16:05:53 -0000      1.8
+++ arch/sparc64/include/mcontext.h     10 Aug 2012 16:24:02 -0000
@@ -73,6 +73,7 @@
 } mcontext32_t;
 
 #define        _UC_SETSTACK    0x00010000
 #define        _UC_CLRSTACK    0x00020000
+#define        _UC_TLSBASE     0x00080000
 
 #endif /* _SPARC64_MCONTEXT_H_ */
Index: sys/ucontext.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ucontext.h,v
retrieving revision 1.16
diff -U 4 -r1.16 ucontext.h
--- sys/ucontext.h      21 May 2012 14:15:19 -0000      1.16
+++ sys/ucontext.h      10 Aug 2012 16:24:02 -0000
@@ -56,15 +56,20 @@
 #define _UC_SIGMASK    0x01            /* valid uc_sigmask */
 #define _UC_STACK      0x02            /* valid uc_stack */
 #define _UC_CPU                0x04            /* valid GPR context in 
uc_mcontext */
 #define _UC_FPU                0x08            /* valid FPU context in 
uc_mcontext */
-#define        _UC_MD          0x40070020      /* MD bits.  see below */
+#define        _UC_MD          0x400f0020      /* MD bits.  see below */
 
 /*
  * _UC_MD includes:
+ *     _UC_TLSBASE     0x00080000 (all ports except hppa, mips, alpha)
+ *                     0x00040000 (hppa, mips)
+ *                     0x00000020 (alpha)
+ *     _UC_UNIQUE      0x00000020 synonym of _UC_TLSBASE on alpha
  *     _UC_SETSTACK    0x00010000 (many ports) and 0x00020000 (arm)
  *     _UC_CLRSTACK    0x00020000 (many ports) and 0x00040000 (arm)
  *     _UC_POWERPC_VEC 0x00010000 (powerpc)
+ *     _UC_POWERPC_SPE 0x00020000 (powerpc)
  *     _UC_M68K_UC_USER 0x40000000 (m68k)
  *     _UC_UNIQUE      0x00000020 (alpha)
  *     _UC_ARM_VFP     0x00010000 (arm)
  *     _UC_VM          0x00040000 (i386)


Home | Main Index | Thread Index | Old Index