Port-pmax archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

pmap_tlb_asid_check() assertion with DIAGNOSTIC and DEBUG kernel on MIPS1



Erik Bertelsen wrote on port-pmax@:
 http://mail-index.NetBSD.org/port-pmax/2011/05/02/msg000107.html

> pid 1(init): ABI set to O32 (e_flags=0x1007)
> panic: tlb_hi (0xc3ec1000) asid (0) != current asid (0x3)
> cpu0: Begin traceback...
> pid -1007936632 not found
> cpu0: End traceback...
> 0xc3ec1b70: cpu_reboot+3c (104,0,b1,80357858) ra 802242fc sz 24
> 0xc3ec1b88: panic+258 (104,c3ec1000,0,3) ra 801d5d7c sz 56
> 0xc3ec1bc0: pmap_tlb_asid_check+4c (104,c3ec1000,0,3) ra 801d65dc sz 24
> 0xc3ec1bd8: pmap_tlb_update_addr+8c (104,c3ec1000,0,3) ra 801d4a2c sz 40
> 0xc3ec1c00: pmap_enter+220 (104,c3ec1000,0,3) ra 802a961c sz 72
> 0xc3ec1c48: uvm_fault_lower+618 (104,c3ec1000,0,3) ra 802aab4c sz 96
> 0xc3ec1ca8: uvm_fault_internal+834 (81ee5d20,c3ec1000,7de99000,0) ra
> 80263db4 sz 272
> 0xc3ec1db8: trap+970 (8,8,7de99000,7de99c08) ra 80176950 sz 400
> 0xc3ec1f48: mips1_user_gen_exception+e0 (8,8,7de99000,7de99c08) ra 0 sz 0
> User-level: pid 2.1

This is reproducible on gxemul emulating 3MAX:

---

Building databases: dev, utmp, utmpx done
Starting syslogd.
panic: tlb_hi (0xc645f000) asid (0) != current asid (0xf)
kernel: breakpoint trap
Stopped in pid 122.1 (sh) at    netbsd:cpu_Debugger+0x4:        jr     ra
                bdslot: nop
db> tr
0xc6463e80: cpu_Debugger+4 (83fff000,803d9b18,b1,803d9b34) ra 80291fb4 sz 0
0xc6463e80: panic+260 (83fff000,c645f000,0,f) ra 8020a8bc sz 56
0xc6463eb8: pmap_tlb_asid_check+6c (83fff000,c645f000,0,f) ra 8020acd8 sz 24
0xc6463ed0: pmap_tlb_asid_acquire+3d0 (83fff000,c645f000,0,f) ra 802073cc sz 56
0xc6463f08: pmap_activate+50 (83fff000,c645f000,0,f) ra 80150494 sz 32
0xc646ef28: lwp_startup+74 (83fff000,c645f000,0,f) ra 801a7154 sz 32
0xc6463f48: mips1_lwp_trampoline+10 (83fff000,c645f000,0,f) ra 0 sz 24
User-level: pid 122.1
db> 

---

I wonder how pmap_tlb_asid_check called from pmap_tlb_asid_acquire()
could fail..

---
pmap_tlb_asid_acquire(pmap_t pm, struct lwp *l)
{
        struct cpu_info * const ci = l->l_cpu;
        struct pmap_tlb_info * const ti = ci->ci_tlb_info;
        struct pmap_asid_info * const pai = PMAP_PAI(pm, ti);

 :
        if (l == curlwp) {
 :
                ci->ci_pmap_asid_cur = pai->pai_asid;
                tlb_set_asid(pai->pai_asid);
                pmap_tlb_asid_check();

 :

void
pmap_tlb_asid_check(void)
{
#ifdef DEBUG
        kpreempt_disable();
        uint32_t tlb_hi;
        __asm("mfc0 %0,$%1" : "=r"(tlb_hi) : "n"(MIPS_COP_0_TLB_HI));
        uint32_t asid = (tlb_hi & MIPS_TLB_PID) >> MIPS_TLB_PID_SHIFT;
        KDASSERTMSG(asid == curcpu()->ci_pmap_asid_cur,
           ("tlb_hi (%#x) asid (%#x) != current asid (%#x)",
            tlb_hi, asid, curcpu()->ci_pmap_asid_cur));
        kpreempt_enable();
#endif
}

---


I put the following changes to locore_mips1.S, but the asid assetion
still happens. (I'm not sure if these fixes are necessary)

 - use MIPS1_TLB_PID and MIPS1_TLB_PID_SHIFT rather than
   PG_ASID to get ASID in tlb_invalidates_asids()
 - use MIPS1_TLB_PID and MIPS1_TLB_PID_SHIFT rather than
   PG_ASID and MIPS1_TLB_INDEX_SHIFT to get ASID in tlb_record_asids()
 - save and restore MIPS_COP_0_TLB_HI in tlb_invalidate_all() and
   cpu_switch_resume as mipsX_subr.S does

---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index