Index: sys/arch/mips/mips/pmap_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/mips/mips/pmap_machdep.c,v retrieving revision 1.16 diff -u -p -r1.16 pmap_machdep.c --- sys/arch/mips/mips/pmap_machdep.c 12 May 2017 06:49:31 -0000 1.16 +++ sys/arch/mips/mips/pmap_machdep.c 12 May 2017 10:03:34 -0000 @@ -661,8 +661,61 @@ pmap_md_page_syncicache(struct vm_page * if (MIPS_HAS_R4K_MMU) { if (VM_PAGEMD_CACHED_P(mdpg)) { /* This was probably mapped cached by UBC so flush it */ +#if 0 + // index ops are BAD mips_dcache_wbinv_range_index(va, PAGE_SIZE); mips_icache_sync_range_index(va, PAGE_SIZE); +#else + + kpreempt_disable(); + struct cpu_info * const ci = curcpu(); + const paddr_t pa = VM_PAGE_TO_PHYS(pg); + // Read only?? + const int prot = VM_PROT_READ | VM_PROT_WRITE; + if (false +#ifndef _LP64 + || pmap_limits.avail_end > MIPS_KSEG1_START - MIPS_KSEG0_START +#endif + || MIPS_CACHE_VIRTUAL_ALIAS + || MIPS_ICACHE_VIRTUAL_ALIAS) { + KASSERT(ci->ci_pmap_dstbase != 0); + KASSERT(ci->ci_pmap_srcbase != 0); + + vaddr_t tva = (prot & VM_PROT_WRITE + ? ci->ci_pmap_dstbase + : ci->ci_pmap_srcbase) + + pmap_md_cache_indexof(MIPS_CACHE_VIRTUAL_ALIAS + ? va : pa); + + /* + * Now to make and write the new PTE to map the PA. + */ + const pt_entry_t npte = pte_make_kenter_pa(pa, mdpg, prot, 0); + pt_entry_t * const ptep = pmap_pte_lookup(pmap_kernel(), tva); + pt_entry_t old_pte = *ptep; // save + bool rv __diagused; + *ptep = npte; // update page table + + // update the TLB directly making sure we force the new + // entry into it. + rv = tlb_update_addr(tva, KERNEL_PID, npte, true); + KASSERTMSG(rv == 1, "va %#"PRIxREGISTER" pte=%#"PRIxPTE" rv=%d", + tva, pte_value(npte), rv); + + mips_dcache_wbinv_range(tva, PAGE_SIZE); + mips_icache_sync_range(tva, PAGE_SIZE); + + *ptep = old_pte; + if (pte_valid_p(old_pte)) { + // Update the TLB with the old mapping. + tlb_update_addr(tva, KERNEL_PID, old_pte, 0); + } else { + // Invalidate TLB entry if the old pte wasn't valid. + tlb_invalidate_addr(tva, KERNEL_PID); + } + } + kpreempt_enable(); // Restore preemption +#endif } } else { mips_icache_sync_range(MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(pg)),