| 1002 | } |
| 1003 | |
| 1004 | static void |
| 1005 | _pmap_unwire_ptp(pmap_t pmap, vm_offset_t va, vm_page_t m) |
| 1006 | { |
| 1007 | pd_entry_t *pde; |
| 1008 | vm_offset_t sva, eva; |
| 1009 | |
| 1010 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 1011 | /* |
| 1012 | * unmap the page table page |
| 1013 | */ |
| 1014 | #ifdef __mips_n64 |
| 1015 | if (m->pindex < NUPDE) { |
| 1016 | pde = pmap_pde(pmap, va); |
| 1017 | sva = va & ~PDRMASK; |
| 1018 | eva = sva + NBPDR; |
| 1019 | } else { |
| 1020 | pde = pmap_segmap(pmap, va); |
| 1021 | sva = va & ~SEGMASK; |
| 1022 | eva = sva + NBSEG; |
| 1023 | } |
| 1024 | #else |
| 1025 | pde = pmap_pde(pmap, va); |
| 1026 | sva = va & ~SEGMASK; |
| 1027 | eva = sva + NBSEG; |
| 1028 | #endif |
| 1029 | *pde = 0; |
| 1030 | pmap->pm_stats.resident_count--; |
| 1031 | |
| 1032 | #ifdef __mips_n64 |
| 1033 | if (m->pindex < NUPDE) { |
| 1034 | pd_entry_t *pdp; |
| 1035 | vm_page_t pdpg; |
| 1036 | |
| 1037 | /* |
| 1038 | * Recursively decrement next level pagetable refcount. |
| 1039 | * Either that shoots down a larger range from TLBs (below) |
| 1040 | * or we're to shoot down just the page in question. |
| 1041 | */ |
| 1042 | pdp = (pd_entry_t *)*pmap_segmap(pmap, va); |
| 1043 | pdpg = PHYS_TO_VM_PAGE(MIPS_DIRECT_TO_PHYS(pdp)); |
| 1044 | if (!pmap_unwire_ptp(pmap, va, pdpg)) { |
| 1045 | pmap_invalidate_range(pmap, sva, eva); |
| 1046 | } |
| 1047 | } else { |
| 1048 | /* Segmap entry shootdown */ |
| 1049 | pmap_invalidate_range(pmap, sva, eva); |
| 1050 | } |
| 1051 | #else |
| 1052 | /* Segmap entry shootdown */ |
| 1053 | pmap_invalidate_range(pmap, sva, eva); |
| 1054 | #endif |
| 1055 | |
| 1056 | /* |
| 1057 | * If the page is finally unwired, simply free it. |
| 1058 | */ |
| 1059 | vm_page_free_zero(m); |
| 1060 | vm_wire_sub(1); |
| 1061 | } |
no test coverage detected