| 9182 | } |
| 9183 | |
| 9184 | static int |
| 9185 | pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot, |
| 9186 | int mode, int flags) |
| 9187 | { |
| 9188 | vm_offset_t base, offset, tmpva; |
| 9189 | vm_paddr_t pa_start, pa_end, pa_end1; |
| 9190 | pdp_entry_t *pdpe; |
| 9191 | pd_entry_t *pde, pde_bits, pde_mask; |
| 9192 | pt_entry_t *pte, pte_bits, pte_mask; |
| 9193 | int error; |
| 9194 | bool changed; |
| 9195 | |
| 9196 | PMAP_LOCK_ASSERT(kernel_pmap, MA_OWNED); |
| 9197 | base = trunc_page(va); |
| 9198 | offset = va & PAGE_MASK; |
| 9199 | size = round_page(offset + size); |
| 9200 | |
| 9201 | /* |
| 9202 | * Only supported on kernel virtual addresses, including the direct |
| 9203 | * map but excluding the recursive map. |
| 9204 | */ |
| 9205 | if (base < DMAP_MIN_ADDRESS) |
| 9206 | return (EINVAL); |
| 9207 | |
| 9208 | /* |
| 9209 | * Construct our flag sets and masks. "bits" is the subset of |
| 9210 | * "mask" that will be set in each modified PTE. |
| 9211 | * |
| 9212 | * Mappings in the direct map are never allowed to be executable. |
| 9213 | */ |
| 9214 | pde_bits = pte_bits = 0; |
| 9215 | pde_mask = pte_mask = 0; |
| 9216 | if (mode != -1) { |
| 9217 | pde_bits |= pmap_cache_bits(kernel_pmap, mode, true); |
| 9218 | pde_mask |= X86_PG_PDE_CACHE; |
| 9219 | pte_bits |= pmap_cache_bits(kernel_pmap, mode, false); |
| 9220 | pte_mask |= X86_PG_PTE_CACHE; |
| 9221 | } |
| 9222 | if (prot != VM_PROT_NONE) { |
| 9223 | if ((prot & VM_PROT_WRITE) != 0) { |
| 9224 | pde_bits |= X86_PG_RW; |
| 9225 | pte_bits |= X86_PG_RW; |
| 9226 | } |
| 9227 | if ((prot & VM_PROT_EXECUTE) == 0 || |
| 9228 | va < VM_MIN_KERNEL_ADDRESS) { |
| 9229 | pde_bits |= pg_nx; |
| 9230 | pte_bits |= pg_nx; |
| 9231 | } |
| 9232 | pde_mask |= X86_PG_RW | pg_nx; |
| 9233 | pte_mask |= X86_PG_RW | pg_nx; |
| 9234 | } |
| 9235 | |
| 9236 | /* |
| 9237 | * Pages that aren't mapped aren't supported. Also break down 2MB pages |
| 9238 | * into 4KB pages if required. |
| 9239 | */ |
| 9240 | for (tmpva = base; tmpva < base + size; ) { |
| 9241 | pdpe = pmap_pdpe(kernel_pmap, tmpva); |
no test coverage detected