* Do the things to unmap a section in a process */
| 3608 | * Do the things to unmap a section in a process |
| 3609 | */ |
| 3610 | static void |
| 3611 | pmap_remove_pte1(pmap_t pmap, pt1_entry_t *pte1p, vm_offset_t sva, |
| 3612 | struct spglist *free) |
| 3613 | { |
| 3614 | pt1_entry_t opte1; |
| 3615 | struct md_page *pvh; |
| 3616 | vm_offset_t eva, va; |
| 3617 | vm_page_t m; |
| 3618 | |
| 3619 | PDEBUG(6, printf("%s(%p): va %#x pte1 %#x at %p\n", __func__, pmap, sva, |
| 3620 | pte1_load(pte1p), pte1p)); |
| 3621 | |
| 3622 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 3623 | KASSERT((sva & PTE1_OFFSET) == 0, |
| 3624 | ("%s: sva is not 1mpage aligned", __func__)); |
| 3625 | |
| 3626 | /* |
| 3627 | * Clear and invalidate the mapping. It should occupy one and only TLB |
| 3628 | * entry. So, pmap_tlb_flush() called with aligned address should be |
| 3629 | * sufficient. |
| 3630 | */ |
| 3631 | opte1 = pte1_load_clear(pte1p); |
| 3632 | pmap_tlb_flush(pmap, sva); |
| 3633 | |
| 3634 | if (pte1_is_wired(opte1)) |
| 3635 | pmap->pm_stats.wired_count -= PTE1_SIZE / PAGE_SIZE; |
| 3636 | pmap->pm_stats.resident_count -= PTE1_SIZE / PAGE_SIZE; |
| 3637 | if (pte1_is_managed(opte1)) { |
| 3638 | pvh = pa_to_pvh(pte1_pa(opte1)); |
| 3639 | pmap_pvh_free(pvh, pmap, sva); |
| 3640 | eva = sva + PTE1_SIZE; |
| 3641 | for (va = sva, m = PHYS_TO_VM_PAGE(pte1_pa(opte1)); |
| 3642 | va < eva; va += PAGE_SIZE, m++) { |
| 3643 | if (pte1_is_dirty(opte1)) |
| 3644 | vm_page_dirty(m); |
| 3645 | if (opte1 & PTE1_A) |
| 3646 | vm_page_aflag_set(m, PGA_REFERENCED); |
| 3647 | if (TAILQ_EMPTY(&m->md.pv_list) && |
| 3648 | TAILQ_EMPTY(&pvh->pv_list)) |
| 3649 | vm_page_aflag_clear(m, PGA_WRITEABLE); |
| 3650 | } |
| 3651 | } |
| 3652 | if (pmap == kernel_pmap) { |
| 3653 | /* |
| 3654 | * L2 page table(s) can't be removed from kernel map as |
| 3655 | * kernel counts on it (stuff around pmap_growkernel()). |
| 3656 | */ |
| 3657 | pmap_remove_kernel_pte1(pmap, pte1p, sva); |
| 3658 | } else { |
| 3659 | /* |
| 3660 | * Get associated L2 page table page. |
| 3661 | * It's possible that the page was never allocated. |
| 3662 | */ |
| 3663 | m = pmap_pt2_page(pmap, sva); |
| 3664 | if (m != NULL) |
| 3665 | pmap_unwire_pt2_all(pmap, sva, m, free); |
| 3666 | } |
| 3667 | } |
no test coverage detected