tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
swapcontext vs libpthread, round 10
Here is the latest patch with various comments adressed. Some points
raised I did not change:
- Documenting uc_flags while it is not public API. I just say that it
is implementation specific and should not be used. IMO documentation cannot
hurt, especially since the field name suggests it is public API while it
is not (it should have been _uc_flags).
- tests/lib/libc/sys/t_swapcontext tests a non public API. Yes, but since
the change touch a lot of MD bits without the possibility of testing
first, having the test case to diagnose a problem could be of great help.
- Joerg think the whole approach is wrong and suggests a purely userland
implementation. IMO my changes does not prevent such a work in the future
and even makes it easier. We need a core decision here.
--
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: distrib/sets/lists/tests/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/tests/mi,v
retrieving revision 1.480
diff -U 4 -r1.480 mi
--- distrib/sets/lists/tests/mi 23 Jul 2012 04:21:39 -0000 1.480
+++ distrib/sets/lists/tests/mi 3 Sep 2012 16:03:59 -0000
@@ -571,8 +571,9 @@
./usr/libdata/debug/usr/tests/lib/libc/sys/t_sigaction.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_sigqueue.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_socketpair.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_stat.debug
tests-lib-debug debug,atf
+./usr/libdata/debug/usr/tests/lib/libc/sys/t_swapcontext.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_timer_create.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_truncate.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_ucontext.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/libc/sys/t_umask.debug
tests-lib-debug debug,atf
@@ -672,8 +673,9 @@
./usr/libdata/debug/usr/tests/lib/libpthread/t_sigsuspend.debug
tests-lib-tests debug,atf
./usr/libdata/debug/usr/tests/lib/libpthread/t_siglongjmp.debug
tests-lib-tests debug,atf
./usr/libdata/debug/usr/tests/lib/libpthread/t_sleep.debug
tests-lib-tests debug,atf
./usr/libdata/debug/usr/tests/lib/libpthread/t_status.debug
tests-obsolete obsolete
+./usr/libdata/debug/usr/tests/lib/libpthread/t_swapcontext.debug
tests-lib-tests debug,atf
./usr/libdata/debug/usr/tests/lib/librt
tests-lib-debug
./usr/libdata/debug/usr/tests/lib/librt/t_sched.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/librt/t_sem.debug
tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/lib/librumpclient
tests-lib-debug
@@ -2478,8 +2480,9 @@
./usr/tests/lib/libc/sys/t_sigaction tests-lib-tests atf
./usr/tests/lib/libc/sys/t_sigqueue tests-lib-tests atf
./usr/tests/lib/libc/sys/t_socketpair tests-lib-tests atf
./usr/tests/lib/libc/sys/t_stat tests-lib-tests
atf
+./usr/tests/lib/libc/sys/t_swapcontext tests-lib-tests atf
./usr/tests/lib/libc/sys/t_timer_create tests-lib-tests
atf
./usr/tests/lib/libc/sys/t_truncate tests-lib-tests atf
./usr/tests/lib/libc/sys/t_ucontext tests-lib-tests atf
./usr/tests/lib/libc/sys/t_umask tests-lib-tests atf
@@ -2706,8 +2709,9 @@
./usr/tests/lib/libpthread/t_sigsuspend tests-lib-tests
atf
./usr/tests/lib/libpthread/t_siglongjmp tests-lib-tests
atf
./usr/tests/lib/libpthread/t_sleep tests-lib-tests atf
./usr/tests/lib/libpthread/t_status tests-obsolete obsolete
+./usr/tests/lib/libpthread/t_swapcontext tests-lib-tests atf
./usr/tests/lib/librt tests-lib-tests atf
./usr/tests/lib/librt/Atffile tests-lib-tests atf
./usr/tests/lib/librt/t_sched tests-lib-tests atf
./usr/tests/lib/librt/t_sem tests-lib-tests atf
Index: lib/libc/arch/hppa/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/hppa/gen/swapcontext.S,v
retrieving revision 1.4
diff -U 4 -r1.4 swapcontext.S
--- lib/libc/arch/hppa/gen/swapcontext.S 28 Apr 2008 20:22:56 -0000
1.4
+++ lib/libc/arch/hppa/gen/swapcontext.S 3 Sep 2012 16:04:20 -0000
@@ -43,11 +43,16 @@
SYSCALL(getcontext)
ldw HPPA_FRAME_ARG(0)(%sp), %arg1
ldw HPPA_FRAME_ARG(1)(%sp), %arg0
- stw %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
+
+ ldw HPPA_FRAME_CRP(%sp), %rp
ldo 4(%rp), %r1
stw %r1, (_OFFSETOF_UC_GREGS + _REG_PCOQT * SZREG)(%arg1)
stw %rp, (_OFFSETOF_UC_GREGS + _REG_PCOQH * SZREG)(%arg1)
- SYSCALL(setcontext)
+ bl setcontext, %rp
+ stw %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1)
+
+ ldw HPPA_FRAME_CRP(%sp), %rp
+ bv,n %r0(%rp)
EXIT(swapcontext)
.end
Index: lib/libc/arch/mips/gen/_resumecontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/mips/gen/_resumecontext.S,v
retrieving revision 1.6
diff -U 4 -r1.6 _resumecontext.S
--- lib/libc/arch/mips/gen/_resumecontext.S 14 Dec 2009 01:07:42 -0000
1.6
+++ lib/libc/arch/mips/gen/_resumecontext.S 3 Sep 2012 16:04:20 -0000
@@ -52,9 +52,9 @@
SYSTRAP(getcontext) # get context
PTR_L a0, _OFFSETOF_UC_LINK(a0) # linked context?
beq a0, zero, 1f # nope, exit process
nop
- SYSTRAP(setcontext) # yes, become it.
+ PIC_TAILCALL(setcontext) # yes, become it.
/* NOTREACHED (in theory) */
li a0, -1 # failure,
1:
SYSTRAP(exit) # all hope is lost.
Index: lib/libc/arch/mips/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/mips/gen/swapcontext.S,v
retrieving revision 1.4
diff -U 4 -r1.4 swapcontext.S
--- lib/libc/arch/mips/gen/swapcontext.S 14 Dec 2009 01:07:42 -0000
1.4
+++ lib/libc/arch/mips/gen/swapcontext.S 3 Sep 2012 16:04:20 -0000
@@ -56,9 +56,9 @@
REG_S ra, _OFFSETOF_UC_GREGS_EPC(v1)
REG_S v0, _OFFSETOF_UC_GREGS_SP(v1)
REG_EPILOGUE
- SYSTRAP(setcontext)
+ PIC_TAILCALL(setcontext)
/* NOTREACHED */
1:
PTR_ADDU sp, sp, CALLFRAME_SIZ
SETUP_GPX(t0);
Index: lib/libc/arch/powerpc64/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/powerpc64/gen/swapcontext.S,v
retrieving revision 1.3
diff -U 4 -r1.3 swapcontext.S
--- lib/libc/arch/powerpc64/gen/swapcontext.S 28 Apr 2008 20:22:57 -0000
1.3
+++ lib/libc/arch/powerpc64/gen/swapcontext.S 3 Sep 2012 16:04:20 -0000
@@ -51,10 +51,10 @@
ld %r0,SF_SZ+SF_LR(%r1) # get LR back
std %r0,mc_off+34*8(%r11) # pc <- lr
la %r0,16(%r1)
std %r0,mc_off+1*8(%r11) # adjust sp
- ld %r3,SF_PARAM+8(%r1) # load ucp
- bl .setcontext # setcontext(ucp)
+ ld %r3,SF_PARAM+8(%r1) # load ucp
+ bl PIC_PLT(_C_LABEL(setcontext)) # setcontext(ucp)
nop
1:
ld %r0,SF_SZ+SF_LR(%r1)
mtlr %r0
Index: lib/libc/arch/sparc/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/gen/swapcontext.S,v
retrieving revision 1.3
diff -U 4 -r1.3 swapcontext.S
--- lib/libc/arch/sparc/gen/swapcontext.S 28 Apr 2008 20:22:57 -0000
1.3
+++ lib/libc/arch/sparc/gen/swapcontext.S 3 Sep 2012 16:04:20 -0000
@@ -48,9 +48,14 @@
st %o1, [%o2 + 40 + 2 * 4] ! gr[_REG_nPC] = retaddr + 4
add %o7, 8, %o1
st %o1, [%o2 + 40 + 1 * 4] ! gr[_REG_PC] = retaddr
- mov %o3, %o0
- mov %o1, %g2 ! optimize `return'
- mov SYS_setcontext|SYSCALL_G2RFLAG, %g1
- t ST_SYSCALL
- ERROR()
+#ifdef PIC
+ PIC_PROLOGUE(%g1, %g2) ! %g1 = _GLOBAL_OFFSET_TABLE
+ set _C_LABEL(setcontext), %g2
+ ld [%g1 + %g2], %g1
+ jmp %g1
+ mov %o3, %o0
+#else
+ jmp _C_LABEL(setcontext)
+ mov %o3, %o0
+#endif
Index: lib/libc/arch/sparc64/gen/swapcontext.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc64/gen/swapcontext.S,v
retrieving revision 1.5
diff -U 4 -r1.5 swapcontext.S
--- lib/libc/arch/sparc64/gen/swapcontext.S 28 Mar 2011 11:19:13 -0000
1.5
+++ lib/libc/arch/sparc64/gen/swapcontext.S 3 Sep 2012 16:04:20 -0000
@@ -49,9 +49,18 @@
stx %o1, [%o2 + 64 + 2 * 8] /* gr[_REG_nPC] = retaddr + 4 */
add %o7, 8, %o1
stx %o1, [%o2 + 64 + 1 * 8] /* gr[_REG_PC] = retaddr */
- mov %o3, %o0
- mov %o1, %g5 /* optimize `return' */
- mov SYS_setcontext|SYSCALL_G5RFLAG, %g1
- t ST_SYSCALL
- ERROR()
+#ifdef PIC
+ PIC_PROLOGUE(%g5,%o4) /* %g5 = _GLOBAL_OFFSET_TABLE */
+#ifdef BIGPIC
+ set _C_LABEL(setcontext), %o6
+ ldx [%g5+%o6], %o5
+#else
+ ldx [%g5+_C_LABEL(setcontext)], %o5
+#endif
+ jmp %o5
+ mov %o3, %o0
+#else
+ ba,a _C_LABEL(setcontext)
+ mov %o3, %o0
+#endif
Index: lib/libc/include/extern.h
===================================================================
RCS file: /cvsroot/src/lib/libc/include/extern.h,v
retrieving revision 1.19
diff -U 4 -r1.19 extern.h
--- lib/libc/include/extern.h 19 Sep 2011 21:24:58 -0000 1.19
+++ lib/libc/include/extern.h 3 Sep 2012 16:04:20 -0000
@@ -24,8 +24,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdarg.h>
+#include <ucontext.h>
__BEGIN_DECLS
extern char *__minbrk;
int __getcwd(char *, size_t);
@@ -66,5 +67,7 @@
void _malloc_prefork(void);
void _malloc_postfork(void);
+int _sys_setcontext(const ucontext_t *);
+
__END_DECLS
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.215
diff -U 4 -r1.215 Makefile.inc
--- lib/libc/sys/Makefile.inc 22 Jun 2012 18:28:38 -0000 1.215
+++ lib/libc/sys/Makefile.inc 3 Sep 2012 16:04:20 -0000
@@ -119,9 +119,9 @@
__quotactl.S \
rasctl.S readlinkat.S reboot.S recvfrom.S recvmmsg.S recvmsg.S rename.S
\
renameat.S revoke.S rmdir.S \
semconfig.S semget.S semop.S \
- sendmmsg.S sendmsg.S sendto.S setegid.S setcontext.S seteuid.S \
+ sendmmsg.S sendmsg.S sendto.S setegid.S seteuid.S \
setgid.S setgroups.S __setitimer50.S __setlogin.S setpgid.S \
setpriority.S \
setregid.S setreuid.S setrlimit.S setsid.S setsockopt.S \
setuid.S __shmctl50.S shmdt.S shmget.S shutdown.S \
@@ -155,9 +155,9 @@
msgrcv.S msgsnd.S __msync13.S __nanosleep50.S open.S poll.S \
__pollts50.S __pselect50.S read.S readlink.S \
readv.S _sched_setparam.S _sched_getparam.S _sched_setaffinity.S \
_sched_getaffinity.S sched_yield.S \
- __select50.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
+ __select50.S setcontext.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
__wait450.S write.S writev.S
NOERR= getegid.S geteuid.S getgid.S getpid.S getppid.S getuid.S \
issetugid.S posix_spawn.S sync.S __posix_fadvise50.S
Index: lib/libpthread/pthread_specific.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_specific.c,v
retrieving revision 1.21
diff -U 4 -r1.21 pthread_specific.c
--- lib/libpthread/pthread_specific.c 23 Jun 2008 10:38:39 -0000 1.21
+++ lib/libpthread/pthread_specific.c 3 Sep 2012 16:04:21 -0000
@@ -36,14 +36,21 @@
#include "pthread.h"
#include "pthread_int.h"
+#include <string.h>
#include <sys/lwpctl.h>
+#include "../libc/include/extern.h" /* for _sys_setcontext() */
+
+int pthread_setcontext(const ucontext_t *);
+
__strong_alias(__libc_thr_setspecific,pthread_setspecific)
__strong_alias(__libc_thr_getspecific,pthread_getspecific)
__strong_alias(__libc_thr_curcpu,pthread_curcpu_np)
+__strong_alias(setcontext,pthread_setcontext)
+
int
pthread_setspecific(pthread_key_t key, const void *value)
{
pthread_t self;
@@ -74,4 +81,17 @@
{
return pthread__self()->pt_lwpctl->lc_curcpu;
}
+
+/*
+ * Override setcontext so that pthread private pointer is preserved
+ */
+int
+pthread_setcontext(const ucontext_t *ucp)
+{
+ ucontext_t uc;
+
+ (void)memcpy(&uc, ucp, sizeof(uc));
+ uc.uc_flags &= ~_UC_TLSBASE;
+ return _sys_setcontext(&uc);
+}
Index: share/man/man2/ucontext.2
===================================================================
RCS file: /cvsroot/src/share/man/man2/ucontext.2,v
retrieving revision 1.6
diff -U 4 -r1.6 ucontext.2
--- share/man/man2/ucontext.2 29 Apr 2010 06:07:35 -0000 1.6
+++ share/man/man2/ucontext.2 3 Sep 2012 16:04:22 -0000
@@ -46,15 +46,22 @@
The
.Vt ucontext_t
structure includes the following members:
.Bd -literal -offset indent
-ucontext_t *uc_link
-sigset_t uc_sigmask
-stack_t uc_stack
-mcontext_t uc_mcontext
+unsigned int uc_flags
+ucontext_t *uc_link
+sigset_t uc_sigmask
+stack_t uc_stack
+mcontext_t uc_mcontext
.Ed
.Pp
The
+.Fa uc_flags
+member contains implementation-specific flags, it should not be used by
+portable code. List of supported flags and their description can be found in
+.In sys/ucontext.h .
+.Pp
+The
.Fa uc_link
member points to the context that will be resumed after the function
specified when modifying a context using
.Xr makecontext 3
Index: sys/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
--- sys/arch/alpha/alpha/machdep.c 13 Jun 2012 17:13:41 -0000 1.340
+++ sys/arch/alpha/alpha/machdep.c 3 Sep 2012 16:04:22 -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: sys/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
--- sys/arch/alpha/include/mcontext.h 25 Feb 2011 14:07:12 -0000 1.7
+++ sys/arch/alpha/include/mcontext.h 3 Sep 2012 16:04:22 -0000
@@ -92,9 +92,9 @@
__fpregset_t __fpregs;
} mcontext_t;
/* Machine-dependent uc_flags */
-#define _UC_UNIQUE 0x20 /* valid process-unique value in _REG_UNIQUE */
+#define _UC_TLSBASE 0x20 /* valid process-unique value in _REG_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: sys/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
--- sys/arch/powerpc/include/mcontext.h 12 Mar 2011 07:38:16 -0000 1.13
+++ sys/arch/powerpc/include/mcontext.h 3 Sep 2012 16:04:23 -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: sys/arch/powerpc/powerpc/sig_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/sig_machdep.c,v
retrieving revision 1.42
diff -U 4 -r1.42 sig_machdep.c
--- sys/arch/powerpc/powerpc/sig_machdep.c 21 May 2012 14:15:18 -0000
1.42
+++ sys/arch/powerpc/powerpc/sig_machdep.c 3 Sep 2012 16:04:23 -0000
@@ -170,9 +170,9 @@
#else
gr[_REG_MQ] = 0;
#endif
- *flagp |= _UC_CPU;
+ *flagp |= (_UC_CPU|_UC_TLSBASE);
#ifdef PPC_HAVE_FPU
/* Save FPU context, if any. */
if (!fpu_save_to_mcontext(l, mcp, flagp))
@@ -196,8 +196,9 @@
cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
{
struct trapframe * const tf = l->l_md.md_utf;
const __greg_t * const gr = mcp->__gregs;
+ __greg_t saved_r2;
int error;
/* Restore GPR context, if any. */
if (flags & _UC_CPU) {
@@ -213,8 +214,9 @@
pcb->pcb_flags &= ~(PCB_FE0|PCB_FE1);
pcb->pcb_flags |= gr[_REG_MSR] & (PCB_FE0|PCB_FE1);
#endif
+ saved_r2 = tf->tf_fixreg[_REG_R2];
(void)memcpy(&tf->tf_fixreg, gr, 32 * sizeof (gr[0]));
tf->tf_cr = gr[_REG_CR];
tf->tf_lr = gr[_REG_LR];
tf->tf_srr0 = gr[_REG_PC];
@@ -228,8 +230,11 @@
tf->tf_xer = gr[_REG_XER];
#ifdef PPC_OEA
tf->tf_mq = gr[_REG_MQ];
#endif
+
+ if (!(flags & _UC_TLSBASE))
+ tf->tf_fixreg[_REG_R2] = saved_r2;
}
#ifdef PPC_HAVE_FPU
/* Restore FPU context, if any. */
Index: sys/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
--- sys/arch/sh3/include/mcontext.h 25 Feb 2011 14:07:13 -0000 1.9
+++ sys/arch/sh3/include/mcontext.h 3 Sep 2012 16:04:23 -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: sys/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
--- sys/arch/sh3/sh3/sh3_machdep.c 8 Jul 2012 20:14:12 -0000 1.100
+++ sys/arch/sh3/sh3/sh3_machdep.c 3 Sep 2012 16:04:23 -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));
}
@@ -464,9 +464,10 @@
error = cpu_mcontext_validate(l, mcp);
if (error)
return error;
- tf->tf_gbr = gr[_REG_GBR];
+ /* done in lwp_setprivate */
+ /* tf->tf_gbr = gr[_REG_GBR]; */
tf->tf_spc = gr[_REG_PC];
tf->tf_ssr = gr[_REG_SR];
tf->tf_macl = gr[_REG_MACL];
tf->tf_mach = gr[_REG_MACH];
@@ -487,9 +488,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: sys/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
--- sys/arch/sparc/include/mcontext.h 25 Feb 2011 14:07:13 -0000 1.12
+++ sys/arch/sparc/include/mcontext.h 3 Sep 2012 16:04:23 -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: sys/arch/sparc/sparc/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/machdep.c,v
retrieving revision 1.319
diff -U 4 -r1.319 machdep.c
--- sys/arch/sparc/sparc/machdep.c 21 May 2012 14:15:18 -0000 1.319
+++ sys/arch/sparc/sparc/machdep.c 3 Sep 2012 16:04:24 -0000
@@ -640,9 +640,9 @@
r[_REG_O5] = tf->tf_out[5];
r[_REG_O6] = tf->tf_out[6];
r[_REG_O7] = tf->tf_out[7];
- *flags |= _UC_CPU;
+ *flags |= (_UC_CPU|_UC_TLSBASE);
#ifdef FPU_CONTEXT
/*
* Get the floating point registers
@@ -746,9 +746,10 @@
tf->tf_global[3] = r[_REG_G3];
tf->tf_global[4] = r[_REG_G4];
tf->tf_global[5] = r[_REG_G5];
tf->tf_global[6] = r[_REG_G6];
- tf->tf_global[7] = r[_REG_G7];
+ /* done in lwp_setprivate */
+ /* tf->tf_global[7] = r[_REG_G7]; */
tf->tf_out[0] = r[_REG_O0];
tf->tf_out[1] = r[_REG_O1];
tf->tf_out[2] = r[_REG_O2];
@@ -757,9 +758,10 @@
tf->tf_out[5] = r[_REG_O5];
tf->tf_out[6] = r[_REG_O6];
tf->tf_out[7] = r[_REG_O7];
- lwp_setprivate(l, (void *)(uintptr_t)r[_REG_G7]);
+ if (flags & _UC_TLSBASE)
+ lwp_setprivate(l, (void *)(uintptr_t)r[_REG_G7]);
}
#ifdef FPU_CONTEXT
if (flags & _UC_FPU) {
Index: sys/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
--- sys/arch/sparc64/include/mcontext.h 16 Mar 2006 16:05:53 -0000 1.8
+++ sys/arch/sparc64/include/mcontext.h 3 Sep 2012 16:04:24 -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/arch/sparc64/sparc64/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/machdep.c,v
retrieving revision 1.267
diff -U 4 -r1.267 machdep.c
--- sys/arch/sparc64/sparc64/machdep.c 21 May 2012 14:15:18 -0000 1.267
+++ sys/arch/sparc64/sparc64/machdep.c 3 Sep 2012 16:04:24 -0000
@@ -2499,9 +2499,9 @@
gr[_REG_PC] = ras_pc;
gr[_REG_nPC] = ras_pc + 4;
}
- *flags |= _UC_CPU;
+ *flags |= (_UC_CPU|_UC_TLSBASE);
mcp->__gwins = NULL;
@@ -2588,9 +2588,10 @@
tf->tf_global[3] = (uint64_t)gr[_REG_G3];
tf->tf_global[4] = (uint64_t)gr[_REG_G4];
tf->tf_global[5] = (uint64_t)gr[_REG_G5];
tf->tf_global[6] = (uint64_t)gr[_REG_G6];
- tf->tf_global[7] = (uint64_t)gr[_REG_G7];
+ /* done in lwp_setprivate */
+ /* tf->tf_global[7] = (uint64_t)gr[_REG_G7]; */
tf->tf_out[0] = (uint64_t)gr[_REG_O0];
tf->tf_out[1] = (uint64_t)gr[_REG_O1];
tf->tf_out[2] = (uint64_t)gr[_REG_O2];
tf->tf_out[3] = (uint64_t)gr[_REG_O3];
@@ -2600,8 +2601,11 @@
tf->tf_out[7] = (uint64_t)gr[_REG_O7];
/* %asi restored above; %fprs not yet supported. */
/* XXX mcp->__gwins */
+
+ if (flags & _UC_TLSBASE)
+ lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_G7]);
}
/* Restore FP register context, if any. */
if ((flags & _UC_FPU) != 0 && mcp->__fpregs.__fpu_en != 0) {
Index: sys/arch/sparc64/sparc64/netbsd32_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/netbsd32_machdep.c,v
retrieving revision 1.98
diff -U 4 -r1.98 netbsd32_machdep.c
--- sys/arch/sparc64/sparc64/netbsd32_machdep.c 21 May 2012 14:15:18 -0000
1.98
+++ sys/arch/sparc64/sparc64/netbsd32_machdep.c 3 Sep 2012 16:04:24 -0000
@@ -776,9 +776,9 @@
gr[_REG_O4] = tf->tf_out[4];
gr[_REG_O5] = tf->tf_out[5];
gr[_REG_O6] = tf->tf_out[6];
gr[_REG_O7] = tf->tf_out[7];
- *flags |= _UC_CPU;
+ *flags |= (_UC_CPU|_UC_TLSBASE);
mcp->__gwins = 0;
@@ -1185,9 +1185,10 @@
tf->tf_global[3] = (uint64_t)gr[_REG32_G3];
tf->tf_global[4] = (uint64_t)gr[_REG32_G4];
tf->tf_global[5] = (uint64_t)gr[_REG32_G5];
tf->tf_global[6] = (uint64_t)gr[_REG32_G6];
- tf->tf_global[7] = (uint64_t)gr[_REG32_G7];
+ /* done in lwp_setprivate */
+ /* tf->tf_global[7] = (uint64_t)gr[_REG32_G7]; */
tf->tf_out[0] = (uint64_t)gr[_REG32_O0];
tf->tf_out[1] = (uint64_t)gr[_REG32_O1];
tf->tf_out[2] = (uint64_t)gr[_REG32_O2];
tf->tf_out[3] = (uint64_t)gr[_REG32_O3];
@@ -1196,9 +1197,10 @@
tf->tf_out[6] = (uint64_t)gr[_REG32_O6];
tf->tf_out[7] = (uint64_t)gr[_REG32_O7];
/* %asi restored above; %fprs not yet supported. */
- lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_G7]);
+ if (flags & _UC_TLSBASE)
+ lwp_setprivate(l, (void *)(uintptr_t)gr[_REG32_G7]);
/* XXX mcp->__gwins */
}
@@ -1280,13 +1282,13 @@
gr[_REG32_O4] = tf->tf_out[4];
gr[_REG32_O5] = tf->tf_out[5];
gr[_REG32_O6] = tf->tf_out[6];
gr[_REG32_O7] = tf->tf_out[7];
- *flags |= _UC_CPU;
+ *flags |= (_UC_CPU|_UC_TLSBASE);
mcp->__gwins = 0;
mcp->__xrs.__xrs_id = 0; /* Solaris extension? */
- *flags |= _UC_CPU;
+ *flags |= (_UC_CPU|_UC_TLSBASE);
/* Save FP register context, if any. */
if (l->l_md.md_fpstate != NULL) {
#ifdef notyet
Index: sys/sys/ucontext.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ucontext.h,v
retrieving revision 1.16
diff -U 4 -r1.16 ucontext.h
--- sys/sys/ucontext.h 21 May 2012 14:15:19 -0000 1.16
+++ sys/sys/ucontext.h 3 Sep 2012 16:04:25 -0000
@@ -56,23 +56,50 @@
#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_SETSTACK 0x00010000 (many ports) and 0x00020000 (arm)
- * _UC_CLRSTACK 0x00020000 (many ports) and 0x00040000 (arm)
- * _UC_POWERPC_VEC 0x00010000 (powerpc)
- * _UC_M68K_UC_USER 0x40000000 (m68k)
- * _UC_UNIQUE 0x00000020 (alpha)
- * _UC_ARM_VFP 0x00010000 (arm)
- * _UC_VM 0x00040000 (i386)
- * _UC_FXSAVE 0x00000020 (i386)
- *
* if your port needs more MD bits, please try to choose bits from _UC_MD
* first, rather than picking random unused bits.
+ *
+ * _UC_MD details
+ *
+ * _UC_TLSBASE Context contains valid pthread private pointer
+ * All ports must define this MD flag
+ * 0x00040000 hppa, mips
+ * 0x00000020 alpha
+ * 0x00080000 all other ports
+ *
+ * _UC_SETSTACK Context uses signal stack
+ * 0x00020000 arm
+ * [undefined] alpha, powerpc and vax
+ * 0x00010000 other ports
+ *
+ * _UC_CLRSTACK Context does not use signal stack
+ * 0x00040000 arm
+ * [undefined] alpha, powerpc and vax
+ * 0x00020000 other ports
+ *
+ * _UC_POWERPC_VEC Context does not use signal stack
+ * 0x00010000 powerpc only
+ *
+ * _UC_POWERPC_SPE Context contains valid SPE context
+ * 0x00020000 powerpc only
+ *
+ * _UC_M68K_UC_USER Used by m68k machdep code, but undocumented
+ * 0x40000000 m68k only
+ *
+ * _UC_ARM_VFP Unused
+ * 0x00010000 arm only
+ *
+ * _UC_VM Context contains valid virtual 8086 context
+ * 0x00040000 i386, amd64 only
+ *
+ * _UC_FXSAVE Context contains FPU context in that
+ * is in FXSAVE format in XMM space
+ * 0x00000020 i386, amd64 only
*/
#ifdef _KERNEL
struct lwp;
Index: tests/lib/libc/sys/Makefile
===================================================================
RCS file: /cvsroot/src/tests/lib/libc/sys/Makefile,v
retrieving revision 1.26
diff -U 4 -r1.26 Makefile
--- tests/lib/libc/sys/Makefile 22 Jun 2012 18:45:23 -0000 1.26
+++ tests/lib/libc/sys/Makefile 3 Sep 2012 16:04:25 -0000
@@ -54,8 +54,9 @@
TESTS_C+= t_setuid
TESTS_C+= t_sigaction
TESTS_C+= t_sigqueue
TESTS_C+= t_socketpair
+TESTS_C+= t_swapcontext
TESTS_C+= t_stat
TESTS_C+= t_timer_create
TESTS_C+= t_truncate
TESTS_C+= t_ucontext
Index: tests/lib/libpthread/Makefile
===================================================================
RCS file: /cvsroot/src/tests/lib/libpthread/Makefile,v
retrieving revision 1.7
diff -U 4 -r1.7 Makefile
--- tests/lib/libpthread/Makefile 6 Apr 2011 16:04:16 -0000 1.7
+++ tests/lib/libpthread/Makefile 3 Sep 2012 16:04:25 -0000
@@ -34,8 +34,9 @@
TESTS_C+= t_sigmask
TESTS_C+= t_sigsuspend
TESTS_C+= t_siglongjmp
TESTS_C+= t_sleep
+TESTS_C+= t_swapcontext
LDADD.t_sem+= -lrt
BINDIR= ${TESTSDIR}
--- tests/lib/libc/sys/t_swapcontext.c.orig 1970-01-01 01:00:00.000000000
+0100
+++ tests/lib/libc/sys/t_swapcontext.c 2012-08-22 10:56:34.000000000 +0200
@@ -0,0 +1,133 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD");
+
+#include <ucontext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <lwp.h>
+
+#include <atf-c.h>
+
+#define STACKSIZE 65536
+
+char stack[STACKSIZE];
+ucontext_t nctx;
+ucontext_t octx;
+void *otls;
+void *ntls;
+int val1, val2;
+int alter_tlsbase;
+
+/* ARGSUSED0 */
+static void
+swapfunc(void *arg)
+{
+ ntls = _lwp_getprivate();
+ printf("after swapcontext TLS pointer = %p\n", ntls);
+
+ if (alter_tlsbase) {
+ ATF_REQUIRE_EQ(ntls, &val1);
+ printf("TLS pointer modified by swapcontext()\n");
+ } else {
+ ATF_REQUIRE_EQ(ntls, &val2);
+ printf("TLS pointer left untouched by swapcontext()\n");
+ }
+
+ /* Go back in main */
+ ATF_REQUIRE(swapcontext(&nctx, &octx));
+
+ /* NOTREACHED */
+ return;
+}
+
+static void
+mainfunc(void)
+{
+ printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE "
+ "is %s\n", (alter_tlsbase) ? "left set" : "cleared");
+
+ _lwp_setprivate(&val1);
+ printf("before swapcontext TLS pointer = %p\n", &val1);
+
+ ATF_REQUIRE(getcontext(&nctx) == 0);
+
+ nctx.uc_stack.ss_sp = stack;
+ nctx.uc_stack.ss_size = sizeof(stack);
+
+#ifndef _UC_TLSBASE
+ ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined");
+#else /* _UC_TLSBASE */
+ ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE);
+ if (!alter_tlsbase)
+ nctx.uc_flags &= ~_UC_TLSBASE;
+#endif /* _UC_TLSBASE */
+
+ makecontext(&nctx, (void *)*swapfunc, 0);
+
+ _lwp_setprivate(&val2);
+ otls = _lwp_getprivate();
+ printf("before swapcontext TLS pointer = %p\n", otls);
+ ATF_REQUIRE(swapcontext(&octx, &nctx) == 0);
+
+ printf("Test completed\n");
+}
+
+
+ATF_TC(swapcontext1);
+ATF_TC_HEAD(swapcontext1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let "
+ "TLS pointer untouched");
+}
+ATF_TC_BODY(swapcontext1, tc)
+{
+ alter_tlsbase = 0;
+ mainfunc();
+}
+
+ATF_TC(swapcontext2);
+ATF_TC_HEAD(swapcontext2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can "
+ "modify TLS pointer");
+}
+ATF_TC_BODY(swapcontext2, tc)
+{
+ alter_tlsbase = 1;
+ mainfunc();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, swapcontext1);
+ ATF_TP_ADD_TC(tp, swapcontext2);
+
+ return atf_no_error();
+}
--- tests/lib/libpthread/t_swapcontext.c.orig 1970-01-01 01:00:00.000000000
+0100
+++ tests/lib/libpthread/t_swapcontext.c 2012-08-29 17:51:25.000000000
+0200
@@ -0,0 +1,111 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD");
+
+#include <pthread.h>
+#include <ucontext.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define STACKSIZE 65536
+
+char stack[STACKSIZE];
+ucontext_t nctx;
+ucontext_t octx;
+void *oself;
+void *nself;
+int val1, val2;
+
+/* ARGSUSED0 */
+static void
+swapfunc(void *arg)
+{
+ /*
+ * If the test fails, we are very likely to crash
+ * without the opportunity to report
+ */
+ nself = (void *)pthread_self();
+ printf("after swapcontext self = %p\n", nself);
+
+ ATF_REQUIRE_EQ(oself, nself);
+ printf("Test succeeded\n");
+
+ /* NOTREACHED */
+ return;
+}
+
+/* ARGSUSED0 */
+static void *
+threadfunc(void *arg)
+{
+ nctx.uc_stack.ss_sp = stack;
+ nctx.uc_stack.ss_size = sizeof(stack);
+
+ makecontext(&nctx, (void *)*swapfunc, 0);
+
+ oself = (void *)pthread_self();
+ printf("before swapcontext self = %p\n", oself);
+ PTHREAD_REQUIRE(swapcontext(&octx, &nctx));
+
+ /* NOTREACHED */
+ return NULL;
+}
+
+
+ATF_TC(swapcontext1);
+ATF_TC_HEAD(swapcontext1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() "
+ "alters pthread_self()");
+}
+ATF_TC_BODY(swapcontext1, tc)
+{
+ pthread_t thread;
+
+ oself = (void *)&val1;
+ nself = (void *)&val2;
+
+ printf("Testing if swapcontext() alters pthread_self()\n");
+
+ PTHREAD_REQUIRE(getcontext(&nctx));
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL));
+
+ return;
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, swapcontext1);
+
+ return atf_no_error();
+}
Home |
Main Index |
Thread Index |
Old Index