* Given a leaf PTE, derive the mapping's attributes. If they do not match * those of the current run, dump the address range and its attributes, and * begin a new run. */
| 11244 | * begin a new run. |
| 11245 | */ |
| 11246 | static void |
| 11247 | sysctl_kmaps_check(struct sbuf *sb, struct pmap_kernel_map_range *range, |
| 11248 | vm_offset_t va, pml4_entry_t pml4e, pdp_entry_t pdpe, pd_entry_t pde, |
| 11249 | pt_entry_t pte) |
| 11250 | { |
| 11251 | pt_entry_t attrs; |
| 11252 | |
| 11253 | attrs = pml4e & (X86_PG_RW | X86_PG_U | pg_nx); |
| 11254 | |
| 11255 | attrs |= pdpe & pg_nx; |
| 11256 | attrs &= pg_nx | (pdpe & (X86_PG_RW | X86_PG_U)); |
| 11257 | if ((pdpe & PG_PS) != 0) { |
| 11258 | attrs |= pdpe & (X86_PG_G | X86_PG_PDE_CACHE); |
| 11259 | } else if (pde != 0) { |
| 11260 | attrs |= pde & pg_nx; |
| 11261 | attrs &= pg_nx | (pde & (X86_PG_RW | X86_PG_U)); |
| 11262 | } |
| 11263 | if ((pde & PG_PS) != 0) { |
| 11264 | attrs |= pde & (X86_PG_G | X86_PG_PDE_CACHE); |
| 11265 | } else if (pte != 0) { |
| 11266 | attrs |= pte & pg_nx; |
| 11267 | attrs &= pg_nx | (pte & (X86_PG_RW | X86_PG_U)); |
| 11268 | attrs |= pte & (X86_PG_G | X86_PG_PTE_CACHE); |
| 11269 | |
| 11270 | /* Canonicalize by always using the PDE PAT bit. */ |
| 11271 | if ((attrs & X86_PG_PTE_PAT) != 0) |
| 11272 | attrs ^= X86_PG_PDE_PAT | X86_PG_PTE_PAT; |
| 11273 | } |
| 11274 | |
| 11275 | if (range->sva > va || !sysctl_kmaps_match(range, attrs)) { |
| 11276 | sysctl_kmaps_dump(sb, range, va); |
| 11277 | sysctl_kmaps_reinit(range, va, attrs); |
| 11278 | } |
| 11279 | } |
| 11280 | |
| 11281 | static int |
| 11282 | sysctl_kmaps(SYSCTL_HANDLER_ARGS) |
no test coverage detected