* Remove the given range of addresses from the specified map. * * It is assumed that the start and end are properly * rounded to the page size. */
| 6010 | * rounded to the page size. |
| 6011 | */ |
| 6012 | void |
| 6013 | pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) |
| 6014 | { |
| 6015 | struct rwlock *lock; |
| 6016 | vm_page_t mt; |
| 6017 | vm_offset_t va_next; |
| 6018 | pml5_entry_t *pml5e; |
| 6019 | pml4_entry_t *pml4e; |
| 6020 | pdp_entry_t *pdpe; |
| 6021 | pd_entry_t ptpaddr, *pde; |
| 6022 | pt_entry_t PG_G, PG_V; |
| 6023 | struct spglist free; |
| 6024 | int anyvalid; |
| 6025 | |
| 6026 | PG_G = pmap_global_bit(pmap); |
| 6027 | PG_V = pmap_valid_bit(pmap); |
| 6028 | |
| 6029 | /* |
| 6030 | * Perform an unsynchronized read. This is, however, safe. |
| 6031 | */ |
| 6032 | if (pmap->pm_stats.resident_count == 0) |
| 6033 | return; |
| 6034 | |
| 6035 | anyvalid = 0; |
| 6036 | SLIST_INIT(&free); |
| 6037 | |
| 6038 | pmap_delayed_invl_start(); |
| 6039 | PMAP_LOCK(pmap); |
| 6040 | pmap_pkru_on_remove(pmap, sva, eva); |
| 6041 | |
| 6042 | /* |
| 6043 | * special handling of removing one page. a very |
| 6044 | * common operation and easy to short circuit some |
| 6045 | * code. |
| 6046 | */ |
| 6047 | if (sva + PAGE_SIZE == eva) { |
| 6048 | pde = pmap_pde(pmap, sva); |
| 6049 | if (pde && (*pde & PG_PS) == 0) { |
| 6050 | pmap_remove_page(pmap, sva, pde, &free); |
| 6051 | goto out; |
| 6052 | } |
| 6053 | } |
| 6054 | |
| 6055 | lock = NULL; |
| 6056 | for (; sva < eva; sva = va_next) { |
| 6057 | if (pmap->pm_stats.resident_count == 0) |
| 6058 | break; |
| 6059 | |
| 6060 | if (pmap_is_la57(pmap)) { |
| 6061 | pml5e = pmap_pml5e(pmap, sva); |
| 6062 | if ((*pml5e & PG_V) == 0) { |
| 6063 | va_next = (sva + NBPML5) & ~PML5MASK; |
| 6064 | if (va_next < sva) |
| 6065 | va_next = eva; |
| 6066 | continue; |
| 6067 | } |
| 6068 | pml4e = pmap_pml5e_to_pml4e(pml5e, sva); |
| 6069 | } else { |
no test coverage detected