* Clear the wired attribute from the mappings for the specified range of * addresses in the given pmap. Every valid mapping within that range * must have the wired attribute set. In contrast, invalid mappings * cannot have the wired attribute set, so they are ignored. * * The wired attribute of the page table entry is not a hardware * feature, so there is no need to invalidate any TLB entr
| 7472 | * function are not needed. |
| 7473 | */ |
| 7474 | void |
| 7475 | pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) |
| 7476 | { |
| 7477 | vm_offset_t va_next; |
| 7478 | pml4_entry_t *pml4e; |
| 7479 | pdp_entry_t *pdpe; |
| 7480 | pd_entry_t *pde; |
| 7481 | pt_entry_t *pte, PG_V, PG_G; |
| 7482 | |
| 7483 | PG_V = pmap_valid_bit(pmap); |
| 7484 | PG_G = pmap_global_bit(pmap); |
| 7485 | PMAP_LOCK(pmap); |
| 7486 | for (; sva < eva; sva = va_next) { |
| 7487 | pml4e = pmap_pml4e(pmap, sva); |
| 7488 | if (pml4e == NULL || (*pml4e & PG_V) == 0) { |
| 7489 | va_next = (sva + NBPML4) & ~PML4MASK; |
| 7490 | if (va_next < sva) |
| 7491 | va_next = eva; |
| 7492 | continue; |
| 7493 | } |
| 7494 | |
| 7495 | va_next = (sva + NBPDP) & ~PDPMASK; |
| 7496 | if (va_next < sva) |
| 7497 | va_next = eva; |
| 7498 | pdpe = pmap_pml4e_to_pdpe(pml4e, sva); |
| 7499 | if ((*pdpe & PG_V) == 0) |
| 7500 | continue; |
| 7501 | if ((*pdpe & PG_PS) != 0) { |
| 7502 | KASSERT(va_next <= eva, |
| 7503 | ("partial update of non-transparent 1G mapping " |
| 7504 | "pdpe %#lx sva %#lx eva %#lx va_next %#lx", |
| 7505 | *pdpe, sva, eva, va_next)); |
| 7506 | MPASS(pmap != kernel_pmap); /* XXXKIB */ |
| 7507 | MPASS((*pdpe & (PG_MANAGED | PG_G)) == 0); |
| 7508 | atomic_clear_long(pdpe, PG_W); |
| 7509 | pmap->pm_stats.wired_count -= NBPDP / PAGE_SIZE; |
| 7510 | continue; |
| 7511 | } |
| 7512 | |
| 7513 | va_next = (sva + NBPDR) & ~PDRMASK; |
| 7514 | if (va_next < sva) |
| 7515 | va_next = eva; |
| 7516 | pde = pmap_pdpe_to_pde(pdpe, sva); |
| 7517 | if ((*pde & PG_V) == 0) |
| 7518 | continue; |
| 7519 | if ((*pde & PG_PS) != 0) { |
| 7520 | if ((*pde & PG_W) == 0) |
| 7521 | panic("pmap_unwire: pde %#jx is missing PG_W", |
| 7522 | (uintmax_t)*pde); |
| 7523 | |
| 7524 | /* |
| 7525 | * Are we unwiring the entire large page? If not, |
| 7526 | * demote the mapping and fall through. |
| 7527 | */ |
| 7528 | if (sva + NBPDR == va_next && eva >= va_next) { |
| 7529 | atomic_clear_long(pde, PG_W); |
| 7530 | pmap->pm_stats.wired_count -= NBPDR / |
| 7531 | PAGE_SIZE; |
nothing calls this directly
no test coverage detected