Hi, TWR-P1025 works with multi-processor now. However, the attached patch is still necessary. The patch will resolve the conflict of PTE update and TLB miss walk. If do not apply it, check fails that PTE and TLB are matched. ----- panic: kernel diagnostic assertion "pte == xpte" failed: file "/usr/src/sys/arch/powerpc/booke/booke_pmap.c", line 423 pm=0x1fd9ce00 va=0xefc34000 asid=22: TLB pte (0x1f878144) != real pte (0x1f878044/0x1f878044) ----- If there is no objection, I'll commit it at next week. Regards, -- NONAKA Kimihiro
Index: sys/arch/powerpc/booke/booke_pmap.c =================================================================== RCS file: /cvsroot/src/sys/arch/powerpc/booke/booke_pmap.c,v retrieving revision 1.21 diff -u -r1.21 booke_pmap.c --- sys/arch/powerpc/booke/booke_pmap.c 23 Jan 2015 06:39:41 -0000 1.21 +++ sys/arch/powerpc/booke/booke_pmap.c 23 Jan 2015 09:08:03 -0000 @@ -43,11 +43,16 @@ #include <sys/param.h> #include <sys/kcore.h> #include <sys/buf.h> +#include <sys/mutex.h> #include <uvm/uvm.h> #include <machine/pmap.h> +#if defined(MULTIPROCESSOR) +kmutex_t pmap_tlb_miss_lock; +#endif + /* * Initialize the kernel pmap. */ @@ -166,6 +171,10 @@ /* init the lock */ pmap_tlb_info_init(&pmap_tlb0_info); +#if defined(MULTIPROCESSOR) + mutex_init(&pmap_tlb_miss_lock, MUTEX_SPIN, IPL_HIGH); +#endif + /* * Compute the number of pages kmem_arena will have. */ @@ -427,4 +436,18 @@ { /* nothing */ } + +void +pmap_md_tlb_miss_lock_enter(void) +{ + + mutex_spin_enter(&pmap_tlb_miss_lock); +} + +void +pmap_md_tlb_miss_lock_exit(void) +{ + + mutex_spin_exit(&pmap_tlb_miss_lock); +} #endif /* MULTIPROCESSOR */ Index: sys/arch/powerpc/booke/genassym.cf =================================================================== RCS file: /cvsroot/src/sys/arch/powerpc/booke/genassym.cf,v retrieving revision 1.10 diff -u -r1.10 genassym.cf --- sys/arch/powerpc/booke/genassym.cf 27 Nov 2012 19:24:46 -0000 1.10 +++ sys/arch/powerpc/booke/genassym.cf 23 Jan 2015 09:08:03 -0000 @@ -111,4 +111,7 @@ define HATCH_TBU offsetof(struct cpu_hatch_data, hatch_tbu) define HATCH_TBL offsetof(struct cpu_hatch_data, hatch_tbl) define HATCH_TLBIDX offsetof(struct cpu_hatch_data, hatch_tlbidx) + +define __SIMPLELOCK_LOCKED __SIMPLELOCK_LOCKED +define __SIMPLELOCK_UNLOCKED __SIMPLELOCK_UNLOCKED endif Index: sys/arch/powerpc/booke/trap_subr.S =================================================================== RCS file: /cvsroot/src/sys/arch/powerpc/booke/trap_subr.S,v retrieving revision 1.11 diff -u -r1.11 trap_subr.S --- sys/arch/powerpc/booke/trap_subr.S 18 Sep 2014 23:37:51 -0000 1.11 +++ sys/arch/powerpc/booke/trap_subr.S 23 Jan 2015 09:08:03 -0000 @@ -346,6 +346,50 @@ RESTORE_SPRG1(%r6); \ FRAME_INTR_XEXIT(rfci, CSRR) +#if defined(MULTIPROCESSOR) +#define FRAME_TLBMISSLOCK \ + GET_CPUINFO(%r23); \ + ldint %r22, CI_MTX_COUNT(%r23); \ + subi %r22, %r22, 1; \ + stint %r22, CI_MTX_COUNT(%r23); \ + isync; \ + cmpwi %r22, 0; \ + bne 1f; \ + ldint %r22, CI_CPL(%r23); \ + stint %r22, CI_MTX_OLDSPL(%r23); \ +1: lis %r23, _C_LABEL(pmap_tlb_miss_lock)@h; \ + ori %r23, %r23, _C_LABEL(pmap_tlb_miss_lock)@l; \ + li %r20, MTX_LOCK; \ +2: lwarx %r22, %r20, %r23; \ + cmpwi %r22, __SIMPLELOCK_UNLOCKED; \ + beq+ 4f; \ +3: lwzx %r22, %r20, %r23; \ + cmpwi %r22, __SIMPLELOCK_UNLOCKED; \ + beq+ 2b; \ + b 3b; \ +4: li %r21, __SIMPLELOCK_LOCKED; \ + stwcx. %r21, %r20, %r23; \ + bne- 2b; \ + isync; \ + msync; +#define FRAME_TLBMISSUNLOCK \ + sync; \ + lis %r23, _C_LABEL(pmap_tlb_miss_lock)@h; \ + ori %r23, %r23, _C_LABEL(pmap_tlb_miss_lock)@l; \ + li %r22, __SIMPLELOCK_UNLOCKED; \ + stw %r22, MTX_LOCK(%r23); \ + isync; \ + msync; \ + GET_CPUINFO(%r23); \ + ldint %r22, CI_MTX_COUNT(%r23); \ + addi %r22, %r22, 1; \ + stint %r22, CI_MTX_COUNT(%r23); \ + isync; +#else /* !MULTIPROCESSOR */ +#define FRAME_TLBMISSLOCK +#define FRAME_TLBMISSUNLOCK +#endif /* MULTIPROCESSOR */ + .text .p2align 4 _C_LABEL(critical_input_vector): @@ -535,6 +579,7 @@ _C_LABEL(data_tlb_error_vector): /* MSR[CE], MSR[ME], MSR[DE] are unchanged, all others cleared */ FRAME_TLBPROLOGUE + FRAME_TLBMISSLOCK /* * Registers as this point: * @@ -577,6 +622,7 @@ 31-PTR_SCALESHIFT, \ 31-PTR_SCALESHIFT /* move PSL_DS[27] to bit 29 */ bl pte_load + FRAME_TLBMISSUNLOCK mtlr %r29 /* restore LR */ /* * If we returned, pte load failed so let trap deal with it but @@ -590,6 +636,7 @@ _C_LABEL(instruction_tlb_error_vector): /* MSR[CE], MSR[ME], MSR[DE] are unchanged, all others cleared */ FRAME_TLBPROLOGUE + FRAME_TLBMISSLOCK /* * Attempt to update the TLB from the page table. */ @@ -600,6 +647,7 @@ 31-PTR_SCALESHIFT, \ 31-PTR_SCALESHIFT /* move PSL_IS[26] to bit 29 */ bl pte_load + FRAME_TLBMISSUNLOCK mtlr %r29 /* restore LR */ /* * If we returned, pte load failed so let trap deal with it but @@ -764,6 +812,9 @@ addic %r31, %r31, 1 addze %r30, %r30 stmw %r30, CI_EV_TLBMISS_SOFT(%r2) + + FRAME_TLBMISSUNLOCK + /* * Cleanup and leave. We know any higher priority exception will * save and restore SPRG1 and %r2 thereby preserving their values. Index: sys/arch/powerpc/include/booke/pmap.h =================================================================== RCS file: /cvsroot/src/sys/arch/powerpc/include/booke/pmap.h,v retrieving revision 1.14 diff -u -r1.14 pmap.h --- sys/arch/powerpc/include/booke/pmap.h 3 Apr 2014 13:55:34 -0000 1.14 +++ sys/arch/powerpc/include/booke/pmap.h 23 Jan 2015 09:08:03 -0000 @@ -92,6 +92,12 @@ bool pmap_md_tlb_check_entry(void *, vaddr_t, tlb_asid_t, pt_entry_t); +#ifdef MULTIPROCESSOR +#define PMAP_MD_NEED_TLB_MISS_LOCK +void pmap_md_tlb_miss_lock_enter(void); +void pmap_md_tlb_miss_lock_exit(void); +#endif /* MULTIPROCESSOR */ + #ifdef PMAP_MINIMALTLB vaddr_t pmap_kvptefill(vaddr_t, vaddr_t, pt_entry_t); #endif Index: sys/uvm/pmap/pmap.c =================================================================== RCS file: /cvsroot/src/sys/uvm/pmap/pmap.c,v retrieving revision 1.9 diff -u -r1.9 pmap.c --- sys/uvm/pmap/pmap.c 5 Jan 2015 05:35:18 -0000 1.9 +++ sys/uvm/pmap/pmap.c 23 Jan 2015 09:08:03 -0000 @@ -263,6 +263,11 @@ #define pmap_pv_alloc() pool_get(&pmap_pv_pool, PR_NOWAIT) #define pmap_pv_free(pv) pool_put(&pmap_pv_pool, (pv)) +#if !defined(MULTIPROCESSOR) || !defined(PMAP_MD_NEED_TLB_MISS_LOCK) +#define pmap_md_tlb_miss_lock_enter() do { } while(/*CONSTCOND*/0) +#define pmap_md_tlb_miss_lock_exit() do { } while(/*CONSTCOND*/0) +#endif /* !MULTIPROCESSOR || !PMAP_MD_NEED_TLB_MISS_LOCK */ + /* * Misc. functions. */ @@ -541,8 +546,10 @@ KASSERT(pmap->pm_count == 0); PMAP_COUNT(destroy); kpreempt_disable(); + pmap_md_tlb_miss_lock_enter(); pmap_tlb_asid_release_all(pmap); pmap_segtab_destroy(pmap, NULL, 0); + pmap_md_tlb_miss_lock_exit(); #ifdef MULTIPROCESSOR kcpuset_destroy(pmap->pm_active); @@ -586,10 +593,12 @@ PMAP_COUNT(activate); kpreempt_disable(); + pmap_md_tlb_miss_lock_enter(); pmap_tlb_asid_acquire(pmap, l); if (l == curlwp) { pmap_segtab_activate(pmap, l); } + pmap_md_tlb_miss_lock_exit(); kpreempt_enable(); UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0); @@ -608,8 +617,10 @@ PMAP_COUNT(deactivate); kpreempt_disable(); + pmap_md_tlb_miss_lock_enter(); curcpu()->ci_pmap_user_segtab = PMAP_INVALID_SEGTAB_ADDRESS; pmap_tlb_asid_deactivate(pmap); + pmap_md_tlb_miss_lock_exit(); kpreempt_enable(); UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0); @@ -629,6 +640,7 @@ if (pending && pmap_tlb_shootdown_bystanders(pmap)) PMAP_COUNT(shootdown_ipis); #endif + pmap_md_tlb_miss_lock_enter(); #ifdef DEBUG pmap_tlb_check(pmap, pmap_md_tlb_check_entry); #endif /* DEBUG */ @@ -642,6 +654,7 @@ pmap_tlb_asid_acquire(pmap, curlwp); pmap_segtab_activate(pmap, curlwp); } + pmap_md_tlb_miss_lock_exit(); kpreempt_enable(); UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0); @@ -685,11 +698,13 @@ pmap_remove_pv(pmap, sva, pg, pte_modified_p(pt_entry)); } + pmap_md_tlb_miss_lock_enter(); *ptep = npte; /* * Flush the TLB for the given address. */ pmap_tlb_invalidate_addr(pmap, sva); + pmap_md_tlb_miss_lock_exit(); } return false; } @@ -843,12 +858,14 @@ } pt_entry = pte_prot_downgrade(pt_entry, prot); if (*ptep != pt_entry) { + pmap_md_tlb_miss_lock_enter(); *ptep = pt_entry; /* * Update the TLB if needed. */ pmap_tlb_update_addr(pmap, sva, pt_entry, PMAP_TLB_NEED_IPI); + pmap_md_tlb_miss_lock_exit(); } } return false; @@ -937,9 +954,11 @@ pt_entry_t pt_entry = *ptep; if (pte_valid_p(pt_entry)) { pt_entry = pte_cached_change(pt_entry, cached); + pmap_md_tlb_miss_lock_enter(); *ptep = pt_entry; pmap_tlb_update_addr(pmap, va, pt_entry, PMAP_TLB_NEED_IPI); + pmap_md_tlb_miss_lock_exit(); } } UVMHIST_LOG(pmaphist, "<- done", 0,0,0,0); @@ -1060,11 +1079,13 @@ bool resident = pte_valid_p(opte); if (!resident) pmap->pm_stats.resident_count++; + pmap_md_tlb_miss_lock_enter(); *ptep = npte; pmap_tlb_update_addr(pmap, va, npte, ((flags & VM_PROT_ALL) ? PMAP_TLB_INSERT : 0) | (resident ? PMAP_TLB_NEED_IPI : 0)); + pmap_md_tlb_miss_lock_exit(); kpreempt_enable(); if (pg != NULL && (prot == (VM_PROT_READ | VM_PROT_EXECUTE))) { @@ -1138,12 +1159,14 @@ pt_entry_t * const ptep = pmap_pte_reserve(pmap_kernel(), va, 0); KASSERT(ptep != NULL); KASSERT(!pte_valid_p(*ptep)); + pmap_md_tlb_miss_lock_enter(); *ptep = npte; /* * We have the option to force this mapping into the TLB but we * don't. Instead let the next reference to the page do it. */ pmap_tlb_update_addr(pmap_kernel(), va, npte, 0); + pmap_md_tlb_miss_lock_exit(); kpreempt_enable(); #if DEBUG > 1 for (u_int i = 0; i < PAGE_SIZE / sizeof(long); i++) { @@ -1179,8 +1202,10 @@ if (pg != NULL) pmap_md_vca_clean(pg, sva, PMAP_WBINV); + pmap_md_tlb_miss_lock_enter(); *ptep = new_pt_entry; pmap_tlb_invalidate_addr(pmap_kernel(), sva); + pmap_md_tlb_miss_lock_exit(); } return false; @@ -1213,8 +1238,10 @@ * Free all of our ASIDs which means we can skip doing all the * tlb_invalidate_addrs(). */ + pmap_md_tlb_miss_lock_enter(); pmap_tlb_asid_deactivate(pmap); pmap_tlb_asid_release_all(pmap); + pmap_md_tlb_miss_lock_exit(); pmap->pm_flags |= PMAP_DEFERRED_ACTIVATE; kpreempt_enable(); @@ -1258,7 +1285,9 @@ #endif if (pte_wired_p(pt_entry)) { + pmap_md_tlb_miss_lock_enter(); *ptep = pte_unwire_entry(*ptep); + pmap_md_tlb_miss_lock_exit(); pmap->pm_stats.wired_count--; } #ifdef DIAGNOSTIC @@ -1421,9 +1450,11 @@ continue; } pmap_md_vca_clean(pg, va, PMAP_WBINV); + pmap_md_tlb_miss_lock_enter(); *ptep = pt_entry; VM_PAGEMD_PVLIST_UNLOCK(mdpg); pmap_tlb_invalidate_addr(pmap, va); + pmap_md_tlb_miss_lock_exit(); pmap_update(pmap); if (__predict_false(gen != VM_PAGEMD_PVLIST_LOCK(mdpg, false))) { /*
Attachment:
TWR-P1025.MP-boot.log
Description: Binary data