* Insert the given physical page (p) at * the specified virtual address (v) in the * target physical map with the protection requested. * * If specified, the page will be wired down, meaning * that the related pte can not be reclaimed. * * NB: This is the only routine which MAY NOT lazy-evaluate * or lose information. That is, this routine must actually * insert this page into the given
| 6723 | * lock, so we do not need pmap_delayed_invl_page() calls here. |
| 6724 | */ |
| 6725 | int |
| 6726 | pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, |
| 6727 | u_int flags, int8_t psind) |
| 6728 | { |
| 6729 | struct rwlock *lock; |
| 6730 | pd_entry_t *pde; |
| 6731 | pt_entry_t *pte, PG_G, PG_A, PG_M, PG_RW, PG_V; |
| 6732 | pt_entry_t newpte, origpte; |
| 6733 | pv_entry_t pv; |
| 6734 | vm_paddr_t opa, pa; |
| 6735 | vm_page_t mpte, om; |
| 6736 | int rv; |
| 6737 | boolean_t nosleep; |
| 6738 | |
| 6739 | PG_A = pmap_accessed_bit(pmap); |
| 6740 | PG_G = pmap_global_bit(pmap); |
| 6741 | PG_M = pmap_modified_bit(pmap); |
| 6742 | PG_V = pmap_valid_bit(pmap); |
| 6743 | PG_RW = pmap_rw_bit(pmap); |
| 6744 | |
| 6745 | va = trunc_page(va); |
| 6746 | KASSERT(va <= VM_MAX_KERNEL_ADDRESS, ("pmap_enter: toobig")); |
| 6747 | KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS, |
| 6748 | ("pmap_enter: invalid to pmap_enter page table pages (va: 0x%lx)", |
| 6749 | va)); |
| 6750 | KASSERT((m->oflags & VPO_UNMANAGED) != 0 || va < kmi.clean_sva || |
| 6751 | va >= kmi.clean_eva, |
| 6752 | ("pmap_enter: managed mapping within the clean submap")); |
| 6753 | if ((m->oflags & VPO_UNMANAGED) == 0) |
| 6754 | VM_PAGE_OBJECT_BUSY_ASSERT(m); |
| 6755 | KASSERT((flags & PMAP_ENTER_RESERVED) == 0, |
| 6756 | ("pmap_enter: flags %u has reserved bits set", flags)); |
| 6757 | pa = VM_PAGE_TO_PHYS(m); |
| 6758 | newpte = (pt_entry_t)(pa | PG_A | PG_V); |
| 6759 | if ((flags & VM_PROT_WRITE) != 0) |
| 6760 | newpte |= PG_M; |
| 6761 | if ((prot & VM_PROT_WRITE) != 0) |
| 6762 | newpte |= PG_RW; |
| 6763 | KASSERT((newpte & (PG_M | PG_RW)) != PG_M, |
| 6764 | ("pmap_enter: flags includes VM_PROT_WRITE but prot doesn't")); |
| 6765 | if ((prot & VM_PROT_EXECUTE) == 0) |
| 6766 | newpte |= pg_nx; |
| 6767 | if ((flags & PMAP_ENTER_WIRED) != 0) |
| 6768 | newpte |= PG_W; |
| 6769 | if (va < VM_MAXUSER_ADDRESS) |
| 6770 | newpte |= PG_U; |
| 6771 | if (pmap == kernel_pmap) |
| 6772 | newpte |= PG_G; |
| 6773 | newpte |= pmap_cache_bits(pmap, m->md.pat_mode, psind > 0); |
| 6774 | |
| 6775 | /* |
| 6776 | * Set modified bit gratuitously for writeable mappings if |
| 6777 | * the page is unmanaged. We do not want to take a fault |
| 6778 | * to do the dirty bit accounting for these mappings. |
| 6779 | */ |
| 6780 | if ((m->oflags & VPO_UNMANAGED) != 0) { |
| 6781 | if ((newpte & PG_RW) != 0) |
| 6782 | newpte |= PG_M; |
nothing calls this directly
no test coverage detected