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"

Reply via email to