| 1657 | } |
| 1658 | |
| 1659 | static void |
| 1660 | _pmap_unwire_l3(pmap_t pmap, vm_offset_t va, vm_page_t m, struct spglist *free) |
| 1661 | { |
| 1662 | |
| 1663 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 1664 | /* |
| 1665 | * unmap the page table page |
| 1666 | */ |
| 1667 | if (m->pindex >= (NUL2E + NUL1E)) { |
| 1668 | /* l1 page */ |
| 1669 | pd_entry_t *l0; |
| 1670 | |
| 1671 | l0 = pmap_l0(pmap, va); |
| 1672 | pmap_clear(l0); |
| 1673 | } else if (m->pindex >= NUL2E) { |
| 1674 | /* l2 page */ |
| 1675 | pd_entry_t *l1; |
| 1676 | |
| 1677 | l1 = pmap_l1(pmap, va); |
| 1678 | pmap_clear(l1); |
| 1679 | } else { |
| 1680 | /* l3 page */ |
| 1681 | pd_entry_t *l2; |
| 1682 | |
| 1683 | l2 = pmap_l2(pmap, va); |
| 1684 | pmap_clear(l2); |
| 1685 | } |
| 1686 | pmap_resident_count_dec(pmap, 1); |
| 1687 | if (m->pindex < NUL2E) { |
| 1688 | /* We just released an l3, unhold the matching l2 */ |
| 1689 | pd_entry_t *l1, tl1; |
| 1690 | vm_page_t l2pg; |
| 1691 | |
| 1692 | l1 = pmap_l1(pmap, va); |
| 1693 | tl1 = pmap_load(l1); |
| 1694 | l2pg = PHYS_TO_VM_PAGE(tl1 & ~ATTR_MASK); |
| 1695 | pmap_unwire_l3(pmap, va, l2pg, free); |
| 1696 | } else if (m->pindex < (NUL2E + NUL1E)) { |
| 1697 | /* We just released an l2, unhold the matching l1 */ |
| 1698 | pd_entry_t *l0, tl0; |
| 1699 | vm_page_t l1pg; |
| 1700 | |
| 1701 | l0 = pmap_l0(pmap, va); |
| 1702 | tl0 = pmap_load(l0); |
| 1703 | l1pg = PHYS_TO_VM_PAGE(tl0 & ~ATTR_MASK); |
| 1704 | pmap_unwire_l3(pmap, va, l1pg, free); |
| 1705 | } |
| 1706 | pmap_invalidate_page(pmap, va); |
| 1707 | |
| 1708 | /* |
| 1709 | * Put page on a list so that it is released after |
| 1710 | * *ALL* TLB shootdown is done |
| 1711 | */ |
| 1712 | pmap_add_delayed_free_list(m, free, TRUE); |
| 1713 | } |
| 1714 | |
| 1715 | /* |
| 1716 | * After removing a page table entry, this routine is used to |
no test coverage detected