Author: brooks
Date: Thu Sep 15 17:25:52 2016
New Revision: 305843
URL: https://svnweb.freebsd.org/changeset/base/305843

Log:
  The TLS offset is a property of the process ABI.
  
  Move to a per-proc TLS offset rather than incorrectly keying off the
  presense of freebsd32 compability in the kernel.
  
  Reviewed by:  adrian, sbruno
  Obtained from:        CheriBSD
  Sponsored by: DARPA, AFRL
  Differential Revision:        https://reviews.freebsd.org/D7843

Modified:
  head/sys/mips/include/proc.h
  head/sys/mips/mips/cpu.c
  head/sys/mips/mips/freebsd32_machdep.c
  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        Thu Sep 15 17:25:11 2016        
(r305842)
+++ head/sys/mips/include/proc.h        Thu Sep 15 17:25:52 2016        
(r305843)
@@ -62,6 +62,7 @@ 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 */

Modified: head/sys/mips/mips/cpu.c
==============================================================================
--- head/sys/mips/mips/cpu.c    Thu Sep 15 17:25:11 2016        (r305842)
+++ head/sys/mips/mips/cpu.c    Thu Sep 15 17:25:52 2016        (r305843)
@@ -71,13 +71,12 @@ struct mips_cpuinfo cpuinfo;
 #   define     _LOAD_T0_MDTLS_A1 \
     _ENCODE_INSN(OP_LD, A1, T0, 0, offsetof(struct thread, td_md.md_tls))
 
-#   if defined(COMPAT_FREEBSD32)
-#   define     _ADDIU_V0_T0_TLS_OFFSET \
-    _ENCODE_INSN(OP_DADDIU, T0, V0, 0, (TLS_TP_OFFSET + TLS_TCB_SIZE32))
-#   else
-#   define     _ADDIU_V0_T0_TLS_OFFSET \
-    _ENCODE_INSN(OP_DADDIU, T0, V0, 0, (TLS_TP_OFFSET + TLS_TCB_SIZE))
-#   endif /* ! COMPAT_FREEBSD32 */
+#   define     _LOAD_T0_MDTLS_TCV_OFFSET_A1 \
+    _ENCODE_INSN(OP_LD, A1, T1, 0, \
+    offsetof(struct thread, td_md.md_tls_tcb_offset))
+
+#   define     _ADDU_V0_T0_T1 \
+    _ENCODE_INSN(0, T0, T1, V0, OP_DADDU)
 
 #   define _MTC0_V0_USERLOCAL \
     _ENCODE_INSN(OP_COP0, OP_DMT, V0, 4, 2)
@@ -86,8 +85,14 @@ struct mips_cpuinfo cpuinfo;
 
 #   define     _LOAD_T0_MDTLS_A1 \
     _ENCODE_INSN(OP_LW, A1, T0, 0, offsetof(struct thread, td_md.md_tls))
-#   define     _ADDIU_V0_T0_TLS_OFFSET \
-    _ENCODE_INSN(OP_ADDIU, T0, V0, 0, (TLS_TP_OFFSET + TLS_TCB_SIZE))
+
+#   define     _LOAD_T0_MDTLS_TCV_OFFSET_A1 \
+    _ENCODE_INSN(OP_LW, A1, T1, 0, \
+    offsetof(struct thread, td_md.md_tls_tcb_offset))
+
+#   define     _ADDU_V0_T0_T1 \
+    _ENCODE_INSN(0, T0, T1, V0, OP_ADDU)
+
 #   define _MTC0_V0_USERLOCAL \
     _ENCODE_INSN(OP_COP0, OP_MT, V0, 4, 2)
 
@@ -111,8 +116,9 @@ remove_userlocal_code(uint32_t *cpu_swit
                if (instructp[0] == _JR_RA)
                        panic("%s: Unable to patch cpu_switch().", __func__);
                if (instructp[0] == _LOAD_T0_MDTLS_A1 &&
-                   instructp[1] == _ADDIU_V0_T0_TLS_OFFSET &&
-                   instructp[2] == _MTC0_V0_USERLOCAL) {
+                   instructp[1] == _LOAD_T0_MDTLS_TCV_OFFSET_A1 &&
+                   instructp[2] == _ADDU_V0_T0_T1 &&
+                   instructp[3] == _MTC0_V0_USERLOCAL) {
                        instructp[0] = _JR_RA;
                        instructp[1] = _NOP;
                        break;

Modified: head/sys/mips/mips/freebsd32_machdep.c
==============================================================================
--- head/sys/mips/mips/freebsd32_machdep.c      Thu Sep 15 17:25:11 2016        
(r305842)
+++ head/sys/mips/mips/freebsd32_machdep.c      Thu Sep 15 17:25:52 2016        
(r305843)
@@ -61,6 +61,7 @@
 #include <machine/reg.h>
 #include <machine/sigframe.h>
 #include <machine/sysarch.h>
+#include <machine/tls.h>
 
 #include <compat/freebsd32/freebsd32_signal.h>
 #include <compat/freebsd32/freebsd32_util.h>
@@ -138,6 +139,8 @@ freebsd32_exec_setregs(struct thread *td
         * Clear extended address space bit for userland.
         */
        td->td_frame->sr &= ~MIPS_SR_UX;
+
+       td->td_md.md_tls_tcb_offset = TLS_TP_OFFSET + TLS_TCB_SIZE32;
 }
 
 int

Modified: head/sys/mips/mips/genassym.c
==============================================================================
--- head/sys/mips/mips/genassym.c       Thu Sep 15 17:25:11 2016        
(r305842)
+++ head/sys/mips/mips/genassym.c       Thu Sep 15 17:25:52 2016        
(r305843)
@@ -74,12 +74,7 @@ ASSYM(TD_FLAGS, offsetof(struct thread, 
 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));
-
-#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
-ASSYM(TLS_TCB_OFFSET, (TLS_TP_OFFSET + TLS_TCB_SIZE32));
-#else
-ASSYM(TLS_TCB_OFFSET, (TLS_TP_OFFSET + TLS_TCB_SIZE));
-#endif
+ASSYM(TD_MDTLS_TCB_OFFSET, offsetof(struct thread, td_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     Thu Sep 15 17:25:11 2016        
(r305842)
+++ head/sys/mips/mips/pm_machdep.c     Thu Sep 15 17:25:52 2016        
(r305843)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/reg.h>
 #include <machine/md_var.h>
 #include <machine/sigframe.h>
+#include <machine/tls.h>
 #include <machine/vmparam.h>
 #include <sys/vnode.h>
 #include <fs/pseudofs/pseudofs.h>
@@ -466,6 +467,8 @@ exec_setregs(struct thread *td, struct i
        if (PCPU_GET(fpcurthread) == td)
            PCPU_SET(fpcurthread, (struct thread *)0);
        td->td_md.md_ss_addr = 0;
+
+       td->td_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  Thu Sep 15 17:25:11 2016        (r305842)
+++ head/sys/mips/mips/swtch.S  Thu Sep 15 17:25:52 2016        (r305843)
@@ -385,7 +385,8 @@ sw2:
  * remove_userlocal_code() in cpu.c.
  */
        PTR_L   t0, TD_MDTLS(a1)                # Get TLS pointer
-       PTR_ADDIU v0, t0, TLS_TCB_OFFSET        # Add TLS/TCB offset
+       PTR_L   t1, TD_MDTLS_TCB_OFFSET(a1)     # Get TLS/TCB offset
+       PTR_ADDU v0, t0, t1
        MTC0    v0, MIPS_COP_0_USERLOCAL, 2     # write it to ULR for rdhwr
 
        j       ra

Modified: head/sys/mips/mips/sys_machdep.c
==============================================================================
--- head/sys/mips/mips/sys_machdep.c    Thu Sep 15 17:25:11 2016        
(r305842)
+++ head/sys/mips/mips/sys_machdep.c    Thu Sep 15 17:25:52 2016        
(r305843)
@@ -69,13 +69,8 @@ sysarch(struct thread *td, struct sysarc
                 * rdhwr trap() instruction handler.
                 */
                if (cpuinfo.userlocal_reg == true) {
-#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
                        mips_wr_userlocal((unsigned long)(uap->parms +
-                           TLS_TP_OFFSET + TLS_TCB_SIZE32));
-#else
-                       mips_wr_userlocal((unsigned long)(uap->parms +
-                           TLS_TP_OFFSET + TLS_TCB_SIZE));
-#endif
+                           td->td_md.md_tls_tcb_offset));
                }
                return (0);
        case MIPS_GET_TLS: 

Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c   Thu Sep 15 17:25:11 2016        (r305842)
+++ head/sys/mips/mips/trap.c   Thu Sep 15 17:25:52 2016        (r305843)
@@ -909,12 +909,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;
-#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
-                                               if (SV_PROC_FLAG(td->td_proc, 
SV_ILP32))
-                                                       
frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE32;
-                                               else
-#endif
-                                               frame_regs[inst.RType.rt] += 
TLS_TP_OFFSET + TLS_TCB_SIZE;
+                                               frame_regs[inst.RType.rt] += 
td->td_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     Thu Sep 15 17:25:11 2016        
(r305842)
+++ head/sys/mips/mips/vm_machdep.c     Thu Sep 15 17:25:52 2016        
(r305843)
@@ -154,6 +154,7 @@ cpu_fork(register struct thread *td1,reg
         */
 
        td2->td_md.md_tls = td1->td_md.md_tls;
+       td2->td_md.md_tls_tcb_offset = td1->td_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
@@ -494,15 +495,16 @@ int
 cpu_set_user_tls(struct thread *td, void *tls_base)
 {
 
-       td->td_md.md_tls = (char*)tls_base;
-       if (td == curthread && cpuinfo.userlocal_reg == true) {
 #if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
-               mips_wr_userlocal((unsigned long)tls_base + TLS_TP_OFFSET +
-                   TLS_TCB_SIZE32);
-#else
-               mips_wr_userlocal((unsigned long)tls_base + TLS_TP_OFFSET +
-                   TLS_TCB_SIZE);
+       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);
        }
 
        return (0);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to