Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Nov 2016 15:34:16 -0800
From:      Adrian Chadd <adrian.chadd@gmail.com>
To:        Brooks Davis <brooks@freebsd.org>,  "freebsd-mips@freebsd.org" <freebsd-mips@freebsd.org>
Cc:        "src-committers@freebsd.org" <src-committers@freebsd.org>,  "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>,  "svn-src-head@freebsd.org" <svn-src-head@freebsd.org>
Subject:   Re: svn commit: r305843 - in head/sys/mips: include mips
Message-ID:  <CAJ-VmonGMfKXqoGB%2BNCLPiCzztzxk3RGtA5RRVrTS_SuxwDfsQ@mail.gmail.com>
In-Reply-To: <201609151725.u8FHPqFH081568@repo.freebsd.org>
References:  <201609151725.u8FHPqFH081568@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
hi,

This patch breaks stuff on my mips24k SoCs (ie, all the atheros chips.)

BAD_PAGE_FAULT: pid 1 tid 100001 (init), uid 0: pc 0x4002a4 got a read
fault (type 0x2) at 0
Trapframe Register Dump:
    zero: 0    at: 0    v0: 0    v1: 0
    a0: 0x7fffeecc    a1: 0    a2: 0    a3: 0
    t0: 0    t1: 0    t2: 0    t3: 0
    t4: 0    t5: 0    t6: 0    t7: 0
    t8: 0    t9: 0x400260    s0: 0x10    s1: 0x2
    s2: 0x7fffeed0    s3: 0    s4: 0    s5: 0
    s6: 0    s7: 0    k0: 0    k1: 0
    gp: 0x4d55d0    sp: 0x7ffeee90    s8: 0    ra: 0
    sr: 0xfc13    mullo: 0    mulhi: 0    badvaddr: 0
    cause: 0x8    pc: 0x4002a4
Page table info for pc address 0x4002a4: pde = 0x809a8000, pte = 0xa001b35a
Dumping 4 words starting at pc address 0x4002a4:
8c420000 14400003 00908021 8f828024
Page table info for bad address 0: pde = 0, pte = 0




-adrian


On 15 September 2016 at 10:25, Brooks Davis <brooks@freebsd.org> wrote:
> 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);
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmonGMfKXqoGB%2BNCLPiCzztzxk3RGtA5RRVrTS_SuxwDfsQ>