* Apply the given advice to the specified range of addresses within the * given pmap. Depending on the advice, clear the referenced and/or * modified flags in each mapping and set the mapped page's dirty field. */
| 3074 | * modified flags in each mapping and set the mapped page's dirty field. |
| 3075 | */ |
| 3076 | void |
| 3077 | pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice) |
| 3078 | { |
| 3079 | pd_entry_t *pde, *pdpe; |
| 3080 | pt_entry_t *pte; |
| 3081 | vm_offset_t va, va_next; |
| 3082 | vm_paddr_t pa; |
| 3083 | vm_page_t m; |
| 3084 | |
| 3085 | if (advice != MADV_DONTNEED && advice != MADV_FREE) |
| 3086 | return; |
| 3087 | rw_wlock(&pvh_global_lock); |
| 3088 | PMAP_LOCK(pmap); |
| 3089 | for (; sva < eva; sva = va_next) { |
| 3090 | pdpe = pmap_segmap(pmap, sva); |
| 3091 | #ifdef __mips_n64 |
| 3092 | if (*pdpe == 0) { |
| 3093 | va_next = (sva + NBSEG) & ~SEGMASK; |
| 3094 | if (va_next < sva) |
| 3095 | va_next = eva; |
| 3096 | continue; |
| 3097 | } |
| 3098 | #endif |
| 3099 | va_next = (sva + NBPDR) & ~PDRMASK; |
| 3100 | if (va_next < sva) |
| 3101 | va_next = eva; |
| 3102 | |
| 3103 | pde = pmap_pdpe_to_pde(pdpe, sva); |
| 3104 | if (*pde == NULL) |
| 3105 | continue; |
| 3106 | |
| 3107 | /* |
| 3108 | * Limit our scan to either the end of the va represented |
| 3109 | * by the current page table page, or to the end of the |
| 3110 | * range being write protected. |
| 3111 | */ |
| 3112 | if (va_next > eva) |
| 3113 | va_next = eva; |
| 3114 | |
| 3115 | va = va_next; |
| 3116 | for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++, |
| 3117 | sva += PAGE_SIZE) { |
| 3118 | if (!pte_test(pte, PTE_MANAGED | PTE_V)) { |
| 3119 | if (va != va_next) { |
| 3120 | pmap_invalidate_range(pmap, va, sva); |
| 3121 | va = va_next; |
| 3122 | } |
| 3123 | continue; |
| 3124 | } |
| 3125 | pa = TLBLO_PTE_TO_PA(*pte); |
| 3126 | m = PHYS_TO_VM_PAGE(pa); |
| 3127 | m->md.pv_flags &= ~PV_TABLE_REF; |
| 3128 | if (pte_test(pte, PTE_D)) { |
| 3129 | if (advice == MADV_DONTNEED) { |
| 3130 | /* |
| 3131 | * Future calls to pmap_is_modified() |
| 3132 | * can be avoided by making the page |
| 3133 | * dirty now. |
no test coverage detected