* Set the physical protection on the * specified range of this map as requested. */
| 4953 | * specified range of this map as requested. |
| 4954 | */ |
| 4955 | void |
| 4956 | pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) |
| 4957 | { |
| 4958 | boolean_t pv_lists_locked; |
| 4959 | vm_offset_t nextva; |
| 4960 | pt1_entry_t *pte1p, pte1; |
| 4961 | pt2_entry_t *pte2p, opte2, npte2; |
| 4962 | |
| 4963 | KASSERT((prot & ~VM_PROT_ALL) == 0, ("invalid prot %x", prot)); |
| 4964 | if (prot == VM_PROT_NONE) { |
| 4965 | pmap_remove(pmap, sva, eva); |
| 4966 | return; |
| 4967 | } |
| 4968 | |
| 4969 | if ((prot & (VM_PROT_WRITE | VM_PROT_EXECUTE)) == |
| 4970 | (VM_PROT_WRITE | VM_PROT_EXECUTE)) |
| 4971 | return; |
| 4972 | |
| 4973 | if (pmap_is_current(pmap)) |
| 4974 | pv_lists_locked = FALSE; |
| 4975 | else { |
| 4976 | pv_lists_locked = TRUE; |
| 4977 | resume: |
| 4978 | rw_wlock(&pvh_global_lock); |
| 4979 | sched_pin(); |
| 4980 | } |
| 4981 | |
| 4982 | PMAP_LOCK(pmap); |
| 4983 | for (; sva < eva; sva = nextva) { |
| 4984 | /* |
| 4985 | * Calculate address for next L2 page table. |
| 4986 | */ |
| 4987 | nextva = pte1_trunc(sva + PTE1_SIZE); |
| 4988 | if (nextva < sva) |
| 4989 | nextva = eva; |
| 4990 | |
| 4991 | pte1p = pmap_pte1(pmap, sva); |
| 4992 | pte1 = pte1_load(pte1p); |
| 4993 | |
| 4994 | /* |
| 4995 | * Weed out invalid mappings. Note: we assume that L1 page |
| 4996 | * page table is always allocated, and in kernel virtual. |
| 4997 | */ |
| 4998 | if (pte1 == 0) |
| 4999 | continue; |
| 5000 | |
| 5001 | if (pte1_is_section(pte1)) { |
| 5002 | /* |
| 5003 | * Are we protecting the entire large page? If not, |
| 5004 | * demote the mapping and fall through. |
| 5005 | */ |
| 5006 | if (sva + PTE1_SIZE == nextva && eva >= nextva) { |
| 5007 | pmap_protect_pte1(pmap, pte1p, sva, prot); |
| 5008 | continue; |
| 5009 | } else { |
| 5010 | if (!pv_lists_locked) { |
| 5011 | pv_lists_locked = TRUE; |
| 5012 | if (!rw_try_wlock(&pvh_global_lock)) { |
nothing calls this directly
no test coverage detected