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