Author: jhb Date: Fri Jun 12 21:21:18 2020 New Revision: 362122 URL: https://svnweb.freebsd.org/changeset/base/362122
Log: Various fixes to TLS for MIPS. - Clear the current thread's TLS pointer on exec. Previously the TLS pointer (and register) remain unchanged. - Explicitly clear the TLS pointer when new threads are created. - Make md_tls_tcb_offset per-process instead of per-thread. The layout of the TLS and TCB are identical for all threads in a process, it is only the TLS pointer values themselves that vary by thread. This also makes setting md_tls_tcb_offset in cpu_set_user_tls() redundant with the setting in exec_setregs(), so only set it in exec_setregs(). Submitted by: Alfredo Mazzinghi (1) Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D24957 Modified: head/sys/mips/include/proc.h head/sys/mips/mips/genassym.c head/sys/mips/mips/pm_machdep.c head/sys/mips/mips/swtch.S head/sys/mips/mips/sys_machdep.c head/sys/mips/mips/trap.c head/sys/mips/mips/vm_machdep.c Modified: head/sys/mips/include/proc.h ============================================================================== --- head/sys/mips/include/proc.h Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/include/proc.h Fri Jun 12 21:21:18 2020 (r362122) @@ -64,7 +64,6 @@ struct mdthread { int md_pc_count; /* performance counter */ int md_pc_spill; /* performance counter spill */ void *md_tls; - size_t md_tls_tcb_offset; /* TCB offset */ #ifdef CPU_CNMIPS struct octeon_cop2_state *md_cop2; /* kernel context */ struct octeon_cop2_state *md_ucop2; /* userland context */ @@ -79,8 +78,7 @@ struct mdthread { #define MDTD_COP2USED 0x0002 /* Process used the COP2 */ struct mdproc { - /* Avoid empty structs because they are undefined behavior. */ - long md_spare; + size_t md_tls_tcb_offset; /* TCB offset */ }; struct syscall_args { Modified: head/sys/mips/mips/genassym.c ============================================================================== --- head/sys/mips/mips/genassym.c Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/mips/genassym.c Fri Jun 12 21:21:18 2020 (r362122) @@ -70,13 +70,15 @@ __FBSDID("$FreeBSD$"); #endif ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); +ASSYM(TD_PROC, offsetof(struct thread, td_proc)); ASSYM(TD_UPTE, offsetof(struct thread, td_md.md_upte)); ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack)); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_LOCK, offsetof(struct thread, td_lock)); ASSYM(TD_MDFLAGS, offsetof(struct thread, td_md.md_flags)); ASSYM(TD_MDTLS, offsetof(struct thread, td_md.md_tls)); -ASSYM(TD_MDTLS_TCB_OFFSET, offsetof(struct thread, td_md.md_tls_tcb_offset)); + +ASSYM(P_MDTLS_TCB_OFFSET, offsetof(struct proc, p_md.md_tls_tcb_offset)); ASSYM(U_PCB_REGS, offsetof(struct pcb, pcb_regs.zero)); ASSYM(U_PCB_CONTEXT, offsetof(struct pcb, pcb_context)); Modified: head/sys/mips/mips/pm_machdep.c ============================================================================== --- head/sys/mips/mips/pm_machdep.c Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/mips/pm_machdep.c Fri Jun 12 21:21:18 2020 (r362122) @@ -473,12 +473,15 @@ exec_setregs(struct thread *td, struct image_params *i PCPU_SET(fpcurthread, (struct thread *)0); td->td_md.md_ss_addr = 0; + td->td_md.md_tls = NULL; #ifdef COMPAT_FREEBSD32 if (!SV_PROC_FLAG(td->td_proc, SV_LP64)) - td->td_md.md_tls_tcb_offset = TLS_TP_OFFSET + TLS_TCB_SIZE32; + td->td_proc->p_md.md_tls_tcb_offset = TLS_TP_OFFSET + + TLS_TCB_SIZE32; else #endif - td->td_md.md_tls_tcb_offset = TLS_TP_OFFSET + TLS_TCB_SIZE; + td->td_proc->p_md.md_tls_tcb_offset = TLS_TP_OFFSET + + TLS_TCB_SIZE; } int Modified: head/sys/mips/mips/swtch.S ============================================================================== --- head/sys/mips/mips/swtch.S Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/mips/swtch.S Fri Jun 12 21:21:18 2020 (r362122) @@ -386,7 +386,8 @@ sw2: .globl cpu_switch_set_userlocal cpu_switch_set_userlocal: PTR_L t0, TD_MDTLS(a1) # Get TLS pointer - PTR_L t1, TD_MDTLS_TCB_OFFSET(a1) # Get TLS/TCB offset + PTR_L t1, TD_PROC(a1) + PTR_L t1, P_MDTLS_TCB_OFFSET(t1) # Get TLS/TCB offset PTR_ADDU v0, t0, t1 MTC0 v0, MIPS_COP_0_USERLOCAL, 2 # write it to ULR for rdhwr Modified: head/sys/mips/mips/sys_machdep.c ============================================================================== --- head/sys/mips/mips/sys_machdep.c Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/mips/sys_machdep.c Fri Jun 12 21:21:18 2020 (r362122) @@ -72,7 +72,7 @@ sysarch(struct thread *td, struct sysarch_args *uap) */ if (cpuinfo.userlocal_reg == true) { mips_wr_userlocal((unsigned long)(uap->parms + - td->td_md.md_tls_tcb_offset)); + td->td_proc->p_md.md_tls_tcb_offset)); } return (0); case MIPS_GET_TLS: Modified: head/sys/mips/mips/trap.c ============================================================================== --- head/sys/mips/mips/trap.c Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/mips/trap.c Fri Jun 12 21:21:18 2020 (r362122) @@ -902,7 +902,7 @@ dofault: if (inst.RType.rd == 29) { frame_regs = &(trapframe->zero); frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls; - frame_regs[inst.RType.rt] += td->td_md.md_tls_tcb_offset; + frame_regs[inst.RType.rt] += td->td_proc->p_md.md_tls_tcb_offset; trapframe->pc += sizeof(int); goto out; } Modified: head/sys/mips/mips/vm_machdep.c ============================================================================== --- head/sys/mips/mips/vm_machdep.c Fri Jun 12 21:17:56 2020 (r362121) +++ head/sys/mips/mips/vm_machdep.c Fri Jun 12 21:21:18 2020 (r362122) @@ -141,7 +141,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct t */ td2->td_md.md_tls = td1->td_md.md_tls; - td2->td_md.md_tls_tcb_offset = td1->td_md.md_tls_tcb_offset; + p2->p_md.md_tls_tcb_offset = td1->td_proc->p_md.md_tls_tcb_offset; td2->td_md.md_saved_intr = MIPS_SR_INT_IE; td2->td_md.md_spinlock_count = 1; #ifdef CPU_CNMIPS @@ -403,6 +403,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0) (MIPS_SR_PX | MIPS_SR_UX | MIPS_SR_KX | MIPS_SR_SX) | (MIPS_SR_INT_IE | MIPS_HARD_INT_MASK)); #endif + td->td_md.md_tls = NULL; } /* @@ -473,16 +474,10 @@ int cpu_set_user_tls(struct thread *td, void *tls_base) { -#if defined(__mips_n64) && defined(COMPAT_FREEBSD32) - if (td->td_proc && SV_PROC_FLAG(td->td_proc, SV_ILP32)) - td->td_md.md_tls_tcb_offset = TLS_TP_OFFSET + TLS_TCB_SIZE32; - else -#endif - td->td_md.md_tls_tcb_offset = TLS_TP_OFFSET + TLS_TCB_SIZE; td->td_md.md_tls = (char*)tls_base; if (td == curthread && cpuinfo.userlocal_reg == true) { mips_wr_userlocal((unsigned long)tls_base + - td->td_md.md_tls_tcb_offset); + td->td_proc->p_md.md_tls_tcb_offset); } return (0); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"