Here is the patch so far, with previous suggestions integrated -- Emmanuel Dreyfus m...@netbsd.org
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 26 Aug 2012 01:37:22 -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 26 Aug 2012 01:38:07 -0000 @@ -47,7 +47,15 @@ stw %r0, (_OFFSETOF_UC_GREGS + _REG_RET0 * SZREG)(%arg1) ldo 4(%rp), %r1 stw %r1, (_OFFSETOF_UC_GREGS + _REG_PCOQT * SZREG)(%arg1) stw %rp, (_OFFSETOF_UC_GREGS + _REG_PCOQH * SZREG)(%arg1) - SYSCALL(setcontext) +#ifdef PIC + ldw HPPA_FRAME_EDP(%sp), %r19 + addil LT%_C_LABEL(setcontext), %r19 + ldw RT%_C_LABEL(setcontext)(%r1), %r1 +#else + ldil L%_C_LABEL(setcontext), %r1 + ldo R%_C_LABEL(setcontext)(%r1), %r1 +#endif + bv,n %r0(%r1) 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 26 Aug 2012 01:38:08 -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 26 Aug 2012 01:38:08 -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 26 Aug 2012 01:38:08 -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 26 Aug 2012 01:38:08 -0000 @@ -48,9 +48,15 @@ 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 +#ifdef PIC + PIC_PROLOGUE(%g1, %g2) ! %g1 = _GLOBAL_OFFSET_TABLE + set _C_LABEL(_setjmp), %g2 + ld [%g1 + %g2], %g1 + jmp %g1 mov %o3, %o0 - mov %o1, %g2 ! optimize `return' - mov SYS_setcontext|SYSCALL_G2RFLAG, %g1 - t ST_SYSCALL +#else + jmp _C_LABEL(setcontext) + mov %o3, %o0 +#endif ERROR() 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 26 Aug 2012 01:38:08 -0000 @@ -49,9 +49,19 @@ 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 +#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 ERROR() 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 26 Aug 2012 01:38:08 -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: 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 26 Aug 2012 01:38:12 -0000 @@ -46,15 +46,21 @@ 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. Portable code should not +use it. +.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 26 Aug 2012 01:38:13 -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 26 Aug 2012 01:38:13 -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: 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 26 Aug 2012 01:38:17 -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 26 Aug 2012 01:38:17 -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 26 Aug 2012 01:38:18 -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 26 Aug 2012 01:38:18 -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,11 @@ error = cpu_mcontext_validate(l, mcp); if (error) return error; +#if notanymore /* done in lwp_setprivate */ tf->tf_gbr = gr[_REG_GBR]; +#endif 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 +489,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 26 Aug 2012 01:38:18 -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 26 Aug 2012 01:38:18 -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,11 @@ 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]; +#if notanymore /* done in lwp_setprivate */ tf->tf_global[7] = r[_REG_G7]; +#endif tf->tf_out[0] = r[_REG_O0]; tf->tf_out[1] = r[_REG_O1]; tf->tf_out[2] = r[_REG_O2]; @@ -757,9 +759,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 26 Aug 2012 01:38:18 -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 26 Aug 2012 01:38:18 -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,11 @@ 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]; +#if notanymore /* done in cpu_lwp_setprivate */ tf->tf_global[7] = (uint64_t)gr[_REG_G7]; +#endif 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 +2602,11 @@ tf->tf_out[7] = (uint64_t)gr[_REG_O7]; /* %asi restored above; %fprs not yet supported. */ /* XXX mcp->__gwins */ + + if (flags & _UC_TLSBASE) + cpu_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 26 Aug 2012 01:38:18 -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,11 @@ 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]; +#if notanymore /* done in cpu_lwp_setprivate */ tf->tf_global[7] = (uint64_t)gr[_REG32_G7]; +#endif 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 +1198,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) + cpu_lwp_setprivate(l, (void *)(uintptr_t)gr[_REG32_G7]); /* XXX mcp->__gwins */ } @@ -1280,13 +1283,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 26 Aug 2012 01:38:23 -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) 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 26 Aug 2012 01:38:24 -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 26 Aug 2012 01:38:24 -0000 @@ -34,8 +35,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-22 10:46:13.000000000 +0200 @@ -0,0 +1,110 @@ +/* $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"); + + 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(); +}