* Apply the given advice to the specified range of addresses within the * given pmap. Depending on the advice, clear the referenced and/or * modified flags in each mapping and set the mapped page's dirty field. */
| 8660 | * modified flags in each mapping and set the mapped page's dirty field. |
| 8661 | */ |
| 8662 | void |
| 8663 | pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice) |
| 8664 | { |
| 8665 | struct rwlock *lock; |
| 8666 | pml4_entry_t *pml4e; |
| 8667 | pdp_entry_t *pdpe; |
| 8668 | pd_entry_t oldpde, *pde; |
| 8669 | pt_entry_t *pte, PG_A, PG_G, PG_M, PG_RW, PG_V; |
| 8670 | vm_offset_t va, va_next; |
| 8671 | vm_page_t m; |
| 8672 | bool anychanged; |
| 8673 | |
| 8674 | if (advice != MADV_DONTNEED && advice != MADV_FREE) |
| 8675 | return; |
| 8676 | |
| 8677 | /* |
| 8678 | * A/D bit emulation requires an alternate code path when clearing |
| 8679 | * the modified and accessed bits below. Since this function is |
| 8680 | * advisory in nature we skip it entirely for pmaps that require |
| 8681 | * A/D bit emulation. |
| 8682 | */ |
| 8683 | if (pmap_emulate_ad_bits(pmap)) |
| 8684 | return; |
| 8685 | |
| 8686 | PG_A = pmap_accessed_bit(pmap); |
| 8687 | PG_G = pmap_global_bit(pmap); |
| 8688 | PG_M = pmap_modified_bit(pmap); |
| 8689 | PG_V = pmap_valid_bit(pmap); |
| 8690 | PG_RW = pmap_rw_bit(pmap); |
| 8691 | anychanged = false; |
| 8692 | pmap_delayed_invl_start(); |
| 8693 | PMAP_LOCK(pmap); |
| 8694 | for (; sva < eva; sva = va_next) { |
| 8695 | pml4e = pmap_pml4e(pmap, sva); |
| 8696 | if (pml4e == NULL || (*pml4e & PG_V) == 0) { |
| 8697 | va_next = (sva + NBPML4) & ~PML4MASK; |
| 8698 | if (va_next < sva) |
| 8699 | va_next = eva; |
| 8700 | continue; |
| 8701 | } |
| 8702 | |
| 8703 | va_next = (sva + NBPDP) & ~PDPMASK; |
| 8704 | if (va_next < sva) |
| 8705 | va_next = eva; |
| 8706 | pdpe = pmap_pml4e_to_pdpe(pml4e, sva); |
| 8707 | if ((*pdpe & PG_V) == 0) |
| 8708 | continue; |
| 8709 | if ((*pdpe & PG_PS) != 0) { |
| 8710 | KASSERT(va_next <= eva, |
| 8711 | ("partial update of non-transparent 1G mapping " |
| 8712 | "pdpe %#lx sva %#lx eva %#lx va_next %#lx", |
| 8713 | *pdpe, sva, eva, va_next)); |
| 8714 | continue; |
| 8715 | } |
| 8716 | |
| 8717 | va_next = (sva + NBPDR) & ~PDRMASK; |
| 8718 | if (va_next < sva) |
| 8719 | va_next = eva; |
nothing calls this directly
no test coverage detected