Module Name: src Committed By: manu Date: Wed Sep 12 02:00:55 UTC 2012
Modified Files: src/distrib/sets/lists/tests: mi src/lib/libc/arch/hppa/gen: swapcontext.S src/lib/libc/arch/mips/gen: _resumecontext.S swapcontext.S src/lib/libc/arch/powerpc64/gen: swapcontext.S src/lib/libc/arch/sparc/gen: swapcontext.S src/lib/libc/arch/sparc64/gen: swapcontext.S src/lib/libc/include: extern.h src/lib/libc/sys: Makefile.inc src/lib/libpthread: pthread_specific.c src/sys/arch/alpha/alpha: machdep.c src/sys/arch/alpha/include: mcontext.h src/sys/arch/sh3/include: mcontext.h src/sys/arch/sparc/include: mcontext.h src/sys/arch/sparc64/include: mcontext.h src/sys/sys: ucontext.h src/tests/lib/libc/sys: Makefile src/tests/lib/libpthread: Makefile Added Files: src/tests/lib/libc/sys: t_swapcontext.c src/tests/lib/libpthread: t_swapcontext.c Log Message: setcontext() used to be incompatible with -lpthread since it affected the TLS pointer, therefore wrecking the pthread environement. Some ports had _UC_TLSBASE flag or equivalent (_UC_UNIQUE on alpha) that controlled whether setcontext() would change the TLS pointer. This change let libpthread override setcontext() with its own version that unsets _UC_TLSBASE, enabling safe usage of setcontext() with -lpthread. We also have the following required changes here: - rename alpha's _UC_UNIQUE into _UC_TLSBASE - add _UC_TLSBASE definition in header file for all ports (powerpc, sh3, sparc and sparc64 lack the implementation for now) - introduce a libc stub that can be overriden for setcontext() - modify MD libcs swapcontext() implementations so that they use the setcontext() libc stub instead of doing a plain system call. While we are there: - document various MD _UC_* flags in header file - add libc and libpthread tests for swapcontext() behavior (hopefully helpful to spot MD problems introduced with this change) Future work: - Deciding whether kernel support or _UC_TLSBASE should be added for powerpc, sh3, sparc and sparc64 is left to portmasters sparc64 Approved by core@ To generate a diff of this commit: cvs rdiff -u -r1.490 -r1.491 src/distrib/sets/lists/tests/mi cvs rdiff -u -r1.4 -r1.5 src/lib/libc/arch/hppa/gen/swapcontext.S cvs rdiff -u -r1.6 -r1.7 src/lib/libc/arch/mips/gen/_resumecontext.S cvs rdiff -u -r1.4 -r1.5 src/lib/libc/arch/mips/gen/swapcontext.S cvs rdiff -u -r1.3 -r1.4 src/lib/libc/arch/powerpc64/gen/swapcontext.S cvs rdiff -u -r1.3 -r1.4 src/lib/libc/arch/sparc/gen/swapcontext.S cvs rdiff -u -r1.5 -r1.6 src/lib/libc/arch/sparc64/gen/swapcontext.S cvs rdiff -u -r1.19 -r1.20 src/lib/libc/include/extern.h cvs rdiff -u -r1.215 -r1.216 src/lib/libc/sys/Makefile.inc cvs rdiff -u -r1.21 -r1.22 src/lib/libpthread/pthread_specific.c cvs rdiff -u -r1.341 -r1.342 src/sys/arch/alpha/alpha/machdep.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/alpha/include/mcontext.h cvs rdiff -u -r1.9 -r1.10 src/sys/arch/sh3/include/mcontext.h cvs rdiff -u -r1.12 -r1.13 src/sys/arch/sparc/include/mcontext.h cvs rdiff -u -r1.8 -r1.9 src/sys/arch/sparc64/include/mcontext.h cvs rdiff -u -r1.16 -r1.17 src/sys/sys/ucontext.h cvs rdiff -u -r1.27 -r1.28 src/tests/lib/libc/sys/Makefile cvs rdiff -u -r0 -r1.1 src/tests/lib/libc/sys/t_swapcontext.c cvs rdiff -u -r1.7 -r1.8 src/tests/lib/libpthread/Makefile cvs rdiff -u -r0 -r1.1 src/tests/lib/libpthread/t_swapcontext.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.490 src/distrib/sets/lists/tests/mi:1.491 --- src/distrib/sets/lists/tests/mi:1.490 Sun Aug 26 23:03:21 2012 +++ src/distrib/sets/lists/tests/mi Wed Sep 12 02:00:51 2012 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.490 2012/08/26 23:03:21 jmmv Exp $ +# $NetBSD: mi,v 1.491 2012/09/12 02:00:51 manu Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -573,6 +573,7 @@ ./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 @@ -674,6 +675,7 @@ ./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 @@ -2486,6 +2488,7 @@ ./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 @@ -2714,6 +2717,7 @@ ./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 Index: src/lib/libc/arch/hppa/gen/swapcontext.S diff -u src/lib/libc/arch/hppa/gen/swapcontext.S:1.4 src/lib/libc/arch/hppa/gen/swapcontext.S:1.5 --- src/lib/libc/arch/hppa/gen/swapcontext.S:1.4 Mon Apr 28 20:22:56 2008 +++ src/lib/libc/arch/hppa/gen/swapcontext.S Wed Sep 12 02:00:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: swapcontext.S,v 1.4 2008/04/28 20:22:56 martin Exp $ */ +/* $NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #include <machine/mcontext.h> #if defined(SYSLIBC_SCCS) && !defined(lint) - RCSID("$NetBSD: swapcontext.S,v 1.4 2008/04/28 20:22:56 martin Exp $") + RCSID("$NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $") #endif /* SYSLIBC_SCCS && !lint */ LEAF_ENTRY(swapcontext) @@ -44,10 +44,15 @@ LEAF_ENTRY(swapcontext) 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: src/lib/libc/arch/mips/gen/_resumecontext.S diff -u src/lib/libc/arch/mips/gen/_resumecontext.S:1.6 src/lib/libc/arch/mips/gen/_resumecontext.S:1.7 --- src/lib/libc/arch/mips/gen/_resumecontext.S:1.6 Mon Dec 14 01:07:42 2009 +++ src/lib/libc/arch/mips/gen/_resumecontext.S Wed Sep 12 02:00:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: _resumecontext.S,v 1.6 2009/12/14 01:07:42 matt Exp $ */ +/* $NetBSD: _resumecontext.S,v 1.7 2012/09/12 02:00:52 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include "assym.h" #if defined(SYSLIBC_SCCS) && !defined(lint) - RCSID("$NetBSD: _resumecontext.S,v 1.6 2009/12/14 01:07:42 matt Exp $") + RCSID("$NetBSD: _resumecontext.S,v 1.7 2012/09/12 02:00:52 manu Exp $") #endif /* SYSLIBC_SCCS && !lint */ .set reorder @@ -53,7 +53,7 @@ LEAF_NOPROFILE(__resumecontext) 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: Index: src/lib/libc/arch/mips/gen/swapcontext.S diff -u src/lib/libc/arch/mips/gen/swapcontext.S:1.4 src/lib/libc/arch/mips/gen/swapcontext.S:1.5 --- src/lib/libc/arch/mips/gen/swapcontext.S:1.4 Mon Dec 14 01:07:42 2009 +++ src/lib/libc/arch/mips/gen/swapcontext.S Wed Sep 12 02:00:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: swapcontext.S,v 1.4 2009/12/14 01:07:42 matt Exp $ */ +/* $NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #include "assym.h" #if defined(SYSLIBC_SCCS) && !defined(lint) - RCSID("$NetBSD: swapcontext.S,v 1.4 2009/12/14 01:07:42 matt Exp $") + RCSID("$NetBSD: swapcontext.S,v 1.5 2012/09/12 02:00:52 manu Exp $") #endif /* SYSLIBC_SCCS && !lint */ .set reorder @@ -57,7 +57,7 @@ NESTED(swapcontext, CALLFRAME_SIZ, ra) REG_S v0, _OFFSETOF_UC_GREGS_SP(v1) REG_EPILOGUE - SYSTRAP(setcontext) + PIC_TAILCALL(setcontext) /* NOTREACHED */ 1: PTR_ADDU sp, sp, CALLFRAME_SIZ Index: src/lib/libc/arch/powerpc64/gen/swapcontext.S diff -u src/lib/libc/arch/powerpc64/gen/swapcontext.S:1.3 src/lib/libc/arch/powerpc64/gen/swapcontext.S:1.4 --- src/lib/libc/arch/powerpc64/gen/swapcontext.S:1.3 Mon Apr 28 20:22:57 2008 +++ src/lib/libc/arch/powerpc64/gen/swapcontext.S Wed Sep 12 02:00:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $ */ +/* $NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:52 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #if defined(LIBC_SCCS) && !defined(lint) .text - .asciz "$NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $" + .asciz "$NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:52 manu Exp $" #endif /* LIBC_SCCS && !lint */ ENTRY(swapcontext) @@ -52,8 +52,8 @@ ENTRY(swapcontext) 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) Index: src/lib/libc/arch/sparc/gen/swapcontext.S diff -u src/lib/libc/arch/sparc/gen/swapcontext.S:1.3 src/lib/libc/arch/sparc/gen/swapcontext.S:1.4 --- src/lib/libc/arch/sparc/gen/swapcontext.S:1.3 Mon Apr 28 20:22:57 2008 +++ src/lib/libc/arch/sparc/gen/swapcontext.S Wed Sep 12 02:00:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $ */ +/* $NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:53 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include "SYS.h" #if defined(LIBC_SCCS) && !defined(lint) - RCSID("$NetBSD: swapcontext.S,v 1.3 2008/04/28 20:22:57 martin Exp $") + RCSID("$NetBSD: swapcontext.S,v 1.4 2012/09/12 02:00:53 manu Exp $") #endif /* LIBC_SCCS && !lint */ ENTRY(swapcontext) @@ -49,8 +49,13 @@ ENTRY(swapcontext) 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: src/lib/libc/arch/sparc64/gen/swapcontext.S diff -u src/lib/libc/arch/sparc64/gen/swapcontext.S:1.5 src/lib/libc/arch/sparc64/gen/swapcontext.S:1.6 --- src/lib/libc/arch/sparc64/gen/swapcontext.S:1.5 Mon Mar 28 11:19:13 2011 +++ src/lib/libc/arch/sparc64/gen/swapcontext.S Wed Sep 12 02:00:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: swapcontext.S,v 1.5 2011/03/28 11:19:13 martin Exp $ */ +/* $NetBSD: swapcontext.S,v 1.6 2012/09/12 02:00:53 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include "SYS.h" #if defined(LIBC_SCCS) && !defined(lint) - RCSID("$NetBSD: swapcontext.S,v 1.5 2011/03/28 11:19:13 martin Exp $") + RCSID("$NetBSD: swapcontext.S,v 1.6 2012/09/12 02:00:53 manu Exp $") #endif /* LIBC_SCCS && !lint */ @@ -50,8 +50,17 @@ ENTRY(swapcontext) 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: src/lib/libc/include/extern.h diff -u src/lib/libc/include/extern.h:1.19 src/lib/libc/include/extern.h:1.20 --- src/lib/libc/include/extern.h:1.19 Mon Sep 19 21:24:58 2011 +++ src/lib/libc/include/extern.h Wed Sep 12 02:00:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.19 2011/09/19 21:24:58 joerg Exp $ */ +/* $NetBSD: extern.h,v 1.20 2012/09/12 02:00:53 manu Exp $ */ /* * Copyright (c) 1997 Christos Zoulas. All rights reserved. @@ -25,6 +25,7 @@ */ #include <stdarg.h> +#include <ucontext.h> __BEGIN_DECLS extern char *__minbrk; @@ -67,4 +68,6 @@ int vsnprintf_ss(char * __restrict, size void _malloc_prefork(void); void _malloc_postfork(void); +int _sys_setcontext(const ucontext_t *); + __END_DECLS Index: src/lib/libc/sys/Makefile.inc diff -u src/lib/libc/sys/Makefile.inc:1.215 src/lib/libc/sys/Makefile.inc:1.216 --- src/lib/libc/sys/Makefile.inc:1.215 Fri Jun 22 18:28:38 2012 +++ src/lib/libc/sys/Makefile.inc Wed Sep 12 02:00:53 2012 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.inc,v 1.215 2012/06/22 18:28:38 christos Exp $ +# $NetBSD: Makefile.inc,v 1.216 2012/09/12 02:00:53 manu Exp $ # @(#)Makefile.inc 8.3 (Berkeley) 10/24/94 # sys sources @@ -120,7 +120,7 @@ ASM= access.S acct.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 \ @@ -156,7 +156,7 @@ WEAKASM= accept.S __aio_suspend50.S clos __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 \ Index: src/lib/libpthread/pthread_specific.c diff -u src/lib/libpthread/pthread_specific.c:1.21 src/lib/libpthread/pthread_specific.c:1.22 --- src/lib/libpthread/pthread_specific.c:1.21 Mon Jun 23 10:38:39 2008 +++ src/lib/libpthread/pthread_specific.c Wed Sep 12 02:00:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_specific.c,v 1.21 2008/06/23 10:38:39 ad Exp $ */ +/* $NetBSD: pthread_specific.c,v 1.22 2012/09/12 02:00:53 manu Exp $ */ /*- * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc. @@ -30,19 +30,26 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_specific.c,v 1.21 2008/06/23 10:38:39 ad Exp $"); +__RCSID("$NetBSD: pthread_specific.c,v 1.22 2012/09/12 02:00:53 manu Exp $"); /* Functions and structures dealing with thread-specific data */ #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) { @@ -75,3 +82,16 @@ pthread_curcpu_np(void) 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: src/sys/arch/alpha/alpha/machdep.c diff -u src/sys/arch/alpha/alpha/machdep.c:1.341 src/sys/arch/alpha/alpha/machdep.c:1.342 --- src/sys/arch/alpha/alpha/machdep.c:1.341 Sat Jul 28 00:57:04 2012 +++ src/sys/arch/alpha/alpha/machdep.c Wed Sep 12 02:00:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.341 2012/07/28 00:57:04 matt Exp $ */ +/* $NetBSD: machdep.c,v 1.342 2012/09/12 02:00:53 manu Exp $ */ /*- * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.341 2012/07/28 00:57:04 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.342 2012/09/12 02:00:53 manu Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1793,7 +1793,7 @@ cpu_getmcontext(struct lwp *l, mcontext_ (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)) { @@ -1840,7 +1840,7 @@ cpu_setmcontext(struct lwp *l, const mco 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) { Index: src/sys/arch/alpha/include/mcontext.h diff -u src/sys/arch/alpha/include/mcontext.h:1.7 src/sys/arch/alpha/include/mcontext.h:1.8 --- src/sys/arch/alpha/include/mcontext.h:1.7 Fri Feb 25 14:07:12 2011 +++ src/sys/arch/alpha/include/mcontext.h Wed Sep 12 02:00:54 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mcontext.h,v 1.7 2011/02/25 14:07:12 joerg Exp $ */ +/* $NetBSD: mcontext.h,v 1.8 2012/09/12 02:00:54 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -93,7 +93,7 @@ typedef struct { } 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]) Index: src/sys/arch/sh3/include/mcontext.h diff -u src/sys/arch/sh3/include/mcontext.h:1.9 src/sys/arch/sh3/include/mcontext.h:1.10 --- src/sys/arch/sh3/include/mcontext.h:1.9 Fri Feb 25 14:07:13 2011 +++ src/sys/arch/sh3/include/mcontext.h Wed Sep 12 02:00:54 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mcontext.h,v 1.9 2011/02/25 14:07:13 joerg Exp $ */ +/* $NetBSD: mcontext.h,v 1.10 2012/09/12 02:00:54 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -92,6 +92,7 @@ typedef struct { */ #define _UC_SETSTACK 0x10000 #define _UC_CLRSTACK 0x20000 +#define _UC_TLSBASE 0x80000 static __inline void * __lwp_getprivate_fast(void) Index: src/sys/arch/sparc/include/mcontext.h diff -u src/sys/arch/sparc/include/mcontext.h:1.12 src/sys/arch/sparc/include/mcontext.h:1.13 --- src/sys/arch/sparc/include/mcontext.h:1.12 Fri Feb 25 14:07:13 2011 +++ src/sys/arch/sparc/include/mcontext.h Wed Sep 12 02:00:54 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mcontext.h,v 1.12 2011/02/25 14:07:13 joerg Exp $ */ +/* $NetBSD: mcontext.h,v 1.13 2012/09/12 02:00:54 manu Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -34,6 +34,7 @@ #define _UC_SETSTACK 0x00010000 #define _UC_CLRSTACK 0x00020000 +#define _UC_TLSBASE 0x00080000 /* * Layout of mcontext_t according the System V Application Binary Interface, Index: src/sys/arch/sparc64/include/mcontext.h diff -u src/sys/arch/sparc64/include/mcontext.h:1.8 src/sys/arch/sparc64/include/mcontext.h:1.9 --- src/sys/arch/sparc64/include/mcontext.h:1.8 Thu Mar 16 16:05:53 2006 +++ src/sys/arch/sparc64/include/mcontext.h Wed Sep 12 02:00:54 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mcontext.h,v 1.8 2006/03/16 16:05:53 cube Exp $ */ +/* $NetBSD: mcontext.h,v 1.9 2012/09/12 02:00:54 manu Exp $ */ #ifndef _SPARC64_MCONTEXT_H_ #define _SPARC64_MCONTEXT_H_ @@ -74,5 +74,6 @@ typedef struct { #define _UC_SETSTACK 0x00010000 #define _UC_CLRSTACK 0x00020000 +#define _UC_TLSBASE 0x00080000 #endif /* _SPARC64_MCONTEXT_H_ */ Index: src/sys/sys/ucontext.h diff -u src/sys/sys/ucontext.h:1.16 src/sys/sys/ucontext.h:1.17 --- src/sys/sys/ucontext.h:1.16 Mon May 21 14:15:19 2012 +++ src/sys/sys/ucontext.h Wed Sep 12 02:00:54 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ucontext.h,v 1.16 2012/05/21 14:15:19 martin Exp $ */ +/* $NetBSD: ucontext.h,v 1.17 2012/09/12 02:00:54 manu Exp $ */ /*- * Copyright (c) 1999, 2003 The NetBSD Foundation, Inc. @@ -57,21 +57,48 @@ struct __ucontext { #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 Index: src/tests/lib/libc/sys/Makefile diff -u src/tests/lib/libc/sys/Makefile:1.27 src/tests/lib/libc/sys/Makefile:1.28 --- src/tests/lib/libc/sys/Makefile:1.27 Wed Aug 8 13:57:06 2012 +++ src/tests/lib/libc/sys/Makefile Wed Sep 12 02:00:55 2012 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.27 2012/08/08 13:57:06 christos Exp $ +# $NetBSD: Makefile,v 1.28 2012/09/12 02:00:55 manu Exp $ MKMAN= no @@ -54,6 +54,7 @@ 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 Index: src/tests/lib/libpthread/Makefile diff -u src/tests/lib/libpthread/Makefile:1.7 src/tests/lib/libpthread/Makefile:1.8 --- src/tests/lib/libpthread/Makefile:1.7 Wed Apr 6 16:04:16 2011 +++ src/tests/lib/libpthread/Makefile Wed Sep 12 02:00:55 2012 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.7 2011/04/06 16:04:16 jruoho Exp $ +# $NetBSD: Makefile,v 1.8 2012/09/12 02:00:55 manu Exp $ NOMAN= # defined @@ -35,6 +35,7 @@ TESTS_C+= t_sigmask TESTS_C+= t_sigsuspend TESTS_C+= t_siglongjmp TESTS_C+= t_sleep +TESTS_C+= t_swapcontext LDADD.t_sem+= -lrt Added files: Index: src/tests/lib/libc/sys/t_swapcontext.c diff -u /dev/null src/tests/lib/libc/sys/t_swapcontext.c:1.1 --- /dev/null Wed Sep 12 02:00:56 2012 +++ src/tests/lib/libc/sys/t_swapcontext.c Wed Sep 12 02:00:55 2012 @@ -0,0 +1,133 @@ +/* $NetBSD: t_swapcontext.c,v 1.1 2012/09/12 02:00:55 manu Exp $ */ + +/* + * 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(); +} Index: src/tests/lib/libpthread/t_swapcontext.c diff -u /dev/null src/tests/lib/libpthread/t_swapcontext.c:1.1 --- /dev/null Wed Sep 12 02:00:56 2012 +++ src/tests/lib/libpthread/t_swapcontext.c Wed Sep 12 02:00:55 2012 @@ -0,0 +1,111 @@ +/* $NetBSD: t_swapcontext.c,v 1.1 2012/09/12 02:00:55 manu Exp $ */ + +/* + * 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(); +}