Index: alpha/alpha/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/vm_machdep.c,v retrieving revision 1.109 diff -u -r1.109 vm_machdep.c --- alpha/alpha/vm_machdep.c 23 Apr 2005 02:32:30 -0000 1.109 +++ alpha/alpha/vm_machdep.c 2 Jul 2005 12:33:26 -0000 @@ -360,7 +360,7 @@ tf->tf_regs[FRAME_FLAGS] = 0; /* full restore */ } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { @@ -368,6 +368,7 @@ td->td_pcb->pcb_hw.apcb_unique = (unsigned long)tls_base; else alpha_pal_wrunique((uintptr_t)tls_base); + return (0); } /* Index: amd64/amd64/sys_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/sys_machdep.c,v retrieving revision 1.89 diff -u -r1.89 sys_machdep.c --- amd64/amd64/sys_machdep.c 14 Apr 2005 16:57:58 -0000 1.89 +++ amd64/amd64/sys_machdep.c 2 Jul 2005 12:33:27 -0000 @@ -42,6 +42,10 @@ #include #include +#include +#include +#include + #ifndef _SYS_SYSPROTO_H_ struct sysarch_args { int op; @@ -57,6 +61,7 @@ int error = 0; struct pcb *pcb = curthread->td_pcb; uint32_t i386base; + uint64_t a64base; switch(uap->op) { case I386_GET_FSBASE: @@ -65,9 +70,12 @@ break; case I386_SET_FSBASE: error = copyin(uap->parms, &i386base, sizeof(i386base)); - pcb->pcb_fsbase = i386base; - if (!error) - wrmsr(MSR_FSBASE, pcb->pcb_fsbase); + if (!error) { + critical_enter(); + wrmsr(MSR_FSBASE, i386base); + pcb->pcb_fsbase = i386base; + critical_exit(); + } break; case I386_GET_GSBASE: i386base = pcb->pcb_gsbase; @@ -75,18 +83,29 @@ break; case I386_SET_GSBASE: error = copyin(uap->parms, &i386base, sizeof(i386base)); - pcb->pcb_gsbase = i386base; - if (!error) - wrmsr(MSR_KGSBASE, pcb->pcb_gsbase); + if (!error) { + critical_enter(); + wrmsr(MSR_KGSBASE, i386base); + pcb->pcb_gsbase = i386base; + critical_exit(); + } break; case AMD64_GET_FSBASE: error = copyout(&pcb->pcb_fsbase, uap->parms, sizeof(pcb->pcb_fsbase)); break; case AMD64_SET_FSBASE: - error = copyin(uap->parms, &pcb->pcb_fsbase, sizeof(pcb->pcb_fsbase)); - if (!error) - wrmsr(MSR_FSBASE, pcb->pcb_fsbase); + error = copyin(uap->parms, &a64base, sizeof(a64base)); + if (!error) { + if (a64base < VM_MAXUSER_ADDRESS) { + critical_enter(); + wrmsr(MSR_FSBASE, a64base); + pcb->pcb_fsbase = a64base; + critical_exit(); + } else { + error = EINVAL; + } + } break; case AMD64_GET_GSBASE: @@ -94,9 +113,17 @@ break; case AMD64_SET_GSBASE: - error = copyin(uap->parms, &pcb->pcb_gsbase, sizeof(pcb->pcb_gsbase)); - if (!error) - wrmsr(MSR_KGSBASE, pcb->pcb_gsbase); + error = copyin(uap->parms, &a64base, sizeof(a64base)); + if (!error) { + if (a64base < VM_MAXUSER_ADDRESS) { + critical_enter(); + wrmsr(MSR_KGSBASE, a64base); + pcb->pcb_gsbase = a64base; + critical_exit(); + } else { + error = EINVAL; + } + } break; default: Index: amd64/amd64/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/vm_machdep.c,v retrieving revision 1.247 diff -u -r1.247 vm_machdep.c --- amd64/amd64/vm_machdep.c 24 Jun 2005 00:29:53 -0000 1.247 +++ amd64/amd64/vm_machdep.c 2 Jul 2005 12:33:27 -0000 @@ -341,10 +341,13 @@ td->td_frame->tf_rdi = (register_t)arg; } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { + if ((u_int64_t)tls_base >= VM_MAXUSER_ADDRESS) + return (EINVAL); + if (td == curthread) { critical_enter(); td->td_pcb->pcb_fsbase = (register_t)tls_base; @@ -353,6 +356,7 @@ } else { td->td_pcb->pcb_fsbase = (register_t)tls_base; } + return (0); } #ifdef SMP Index: arm/arm/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/arm/arm/vm_machdep.c,v retrieving revision 1.16 diff -u -r1.16 vm_machdep.c --- arm/arm/vm_machdep.c 23 Jun 2005 11:37:41 -0000 1.16 +++ arm/arm/vm_machdep.c 2 Jul 2005 12:33:27 -0000 @@ -297,7 +297,7 @@ tf->tf_spsr = PSR_USR32_MODE; } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { @@ -308,6 +308,7 @@ *(void **)ARM_TP_ADDRESS = tls_base; critical_exit(); } + return (0); } void Index: i386/i386/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/vm_machdep.c,v retrieving revision 1.258 diff -u -r1.258 vm_machdep.c --- i386/i386/vm_machdep.c 23 Jun 2005 21:56:45 -0000 1.258 +++ i386/i386/vm_machdep.c 2 Jul 2005 12:33:34 -0000 @@ -472,7 +472,7 @@ (int)arg); } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { struct segment_descriptor sd; @@ -503,6 +503,7 @@ load_gs(GSEL(GUGS_SEL, SEL_UPL)); } critical_exit(); + return (0); } /* Index: ia64/ia64/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/ia64/ia64/vm_machdep.c,v retrieving revision 1.89 diff -u -r1.89 vm_machdep.c --- ia64/ia64/vm_machdep.c 23 Apr 2005 02:32:31 -0000 1.89 +++ ia64/ia64/vm_machdep.c 2 Jul 2005 12:33:35 -0000 @@ -209,10 +209,11 @@ } } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { td->td_frame->tf_special.tp = (unsigned long)tls_base; + return (0); } /* Index: kern/kern_thr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thr.c,v retrieving revision 1.33 diff -u -r1.33 kern_thr.c --- kern/kern_thr.c 23 Apr 2005 02:36:07 -0000 1.33 +++ kern/kern_thr.c 2 Jul 2005 12:33:35 -0000 @@ -176,7 +176,12 @@ /* Set upcall address to user thread entry function. */ cpu_set_upcall_kse(newtd, start_func, arg, &stack); /* Setup user TLS address and TLS pointer register. */ - cpu_set_user_tls(newtd, tls_base); + error = cpu_set_user_tls(newtd, tls_base); + if (error != 0) { + thread_free(newtd); + crfree(td->td_ucred); + return (error); + } } if ((td->td_proc->p_flag & P_HADTHREADS) == 0) { Index: powerpc/powerpc/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/powerpc/powerpc/vm_machdep.c,v retrieving revision 1.109 diff -u -r1.109 vm_machdep.c --- powerpc/powerpc/vm_machdep.c 23 Apr 2005 02:32:31 -0000 1.109 +++ powerpc/powerpc/vm_machdep.c 2 Jul 2005 12:33:39 -0000 @@ -355,9 +355,10 @@ td->td_retval[1] = 0; } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { td->td_frame->fixreg[2] = (register_t)tls_base; + return (0); } Index: sparc64/sparc64/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/vm_machdep.c,v retrieving revision 1.73 diff -u -r1.73 vm_machdep.c --- sparc64/sparc64/vm_machdep.c 23 Apr 2005 02:32:31 -0000 1.73 +++ sparc64/sparc64/vm_machdep.c 2 Jul 2005 12:33:40 -0000 @@ -196,13 +196,14 @@ td->td_retval[1] = tf->tf_out[1]; } -void +int cpu_set_user_tls(struct thread *td, void *tls_base) { if (td == curthread) flushw(); td->td_frame->tf_global[7] = (uint64_t) tls_base; + return (0); } /* Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.431 diff -u -r1.431 proc.h --- sys/proc.h 30 May 2005 19:33:33 -0000 1.431 +++ sys/proc.h 2 Jul 2005 12:33:41 -0000 @@ -897,7 +897,7 @@ void kseinit(void); void cpu_set_upcall(struct thread *td, struct thread *td0); void cpu_set_upcall_kse(struct thread *, void (*)(void *), void *, stack_t *); -void cpu_set_user_tls(struct thread *, void *tls_base); +int cpu_set_user_tls(struct thread *, void *tls_base); void cpu_thread_clean(struct thread *); void cpu_thread_exit(struct thread *); void cpu_thread_setup(struct thread *td);