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>