* pmap_protect_pde: do the things to protect a 2mpage in a process */
| 6261 | * pmap_protect_pde: do the things to protect a 2mpage in a process |
| 6262 | */ |
| 6263 | static boolean_t |
| 6264 | pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot) |
| 6265 | { |
| 6266 | pd_entry_t newpde, oldpde; |
| 6267 | vm_page_t m, mt; |
| 6268 | boolean_t anychanged; |
| 6269 | pt_entry_t PG_G, PG_M, PG_RW; |
| 6270 | |
| 6271 | PG_G = pmap_global_bit(pmap); |
| 6272 | PG_M = pmap_modified_bit(pmap); |
| 6273 | PG_RW = pmap_rw_bit(pmap); |
| 6274 | |
| 6275 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 6276 | KASSERT((sva & PDRMASK) == 0, |
| 6277 | ("pmap_protect_pde: sva is not 2mpage aligned")); |
| 6278 | anychanged = FALSE; |
| 6279 | retry: |
| 6280 | oldpde = newpde = *pde; |
| 6281 | if ((prot & VM_PROT_WRITE) == 0) { |
| 6282 | if ((oldpde & (PG_MANAGED | PG_M | PG_RW)) == |
| 6283 | (PG_MANAGED | PG_M | PG_RW)) { |
| 6284 | m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME); |
| 6285 | for (mt = m; mt < &m[NBPDR / PAGE_SIZE]; mt++) |
| 6286 | vm_page_dirty(mt); |
| 6287 | } |
| 6288 | newpde &= ~(PG_RW | PG_M); |
| 6289 | } |
| 6290 | if ((prot & VM_PROT_EXECUTE) == 0) |
| 6291 | newpde |= pg_nx; |
| 6292 | if (newpde != oldpde) { |
| 6293 | /* |
| 6294 | * As an optimization to future operations on this PDE, clear |
| 6295 | * PG_PROMOTED. The impending invalidation will remove any |
| 6296 | * lingering 4KB page mappings from the TLB. |
| 6297 | */ |
| 6298 | if (!atomic_cmpset_long(pde, oldpde, newpde & ~PG_PROMOTED)) |
| 6299 | goto retry; |
| 6300 | if ((oldpde & PG_G) != 0) |
| 6301 | pmap_invalidate_pde_page(kernel_pmap, sva, oldpde); |
| 6302 | else |
| 6303 | anychanged = TRUE; |
| 6304 | } |
| 6305 | return (anychanged); |
| 6306 | } |
| 6307 | |
| 6308 | /* |
| 6309 | * Set the physical protection on the |
no test coverage detected