* 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. */
| 3027 | * rounded to the page size. |
| 3028 | */ |
| 3029 | void |
| 3030 | pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) |
| 3031 | { |
| 3032 | struct rwlock *lock; |
| 3033 | vm_offset_t va_next; |
| 3034 | pd_entry_t *l0, *l1, *l2; |
| 3035 | pt_entry_t l3_paddr; |
| 3036 | struct spglist free; |
| 3037 | |
| 3038 | /* |
| 3039 | * Perform an unsynchronized read. This is, however, safe. |
| 3040 | */ |
| 3041 | if (pmap->pm_stats.resident_count == 0) |
| 3042 | return; |
| 3043 | |
| 3044 | SLIST_INIT(&free); |
| 3045 | |
| 3046 | PMAP_LOCK(pmap); |
| 3047 | |
| 3048 | lock = NULL; |
| 3049 | for (; sva < eva; sva = va_next) { |
| 3050 | if (pmap->pm_stats.resident_count == 0) |
| 3051 | break; |
| 3052 | |
| 3053 | l0 = pmap_l0(pmap, sva); |
| 3054 | if (pmap_load(l0) == 0) { |
| 3055 | va_next = (sva + L0_SIZE) & ~L0_OFFSET; |
| 3056 | if (va_next < sva) |
| 3057 | va_next = eva; |
| 3058 | continue; |
| 3059 | } |
| 3060 | |
| 3061 | va_next = (sva + L1_SIZE) & ~L1_OFFSET; |
| 3062 | if (va_next < sva) |
| 3063 | va_next = eva; |
| 3064 | l1 = pmap_l0_to_l1(l0, sva); |
| 3065 | if (pmap_load(l1) == 0) |
| 3066 | continue; |
| 3067 | if ((pmap_load(l1) & ATTR_DESCR_MASK) == L1_BLOCK) { |
| 3068 | KASSERT(va_next <= eva, |
| 3069 | ("partial update of non-transparent 1G page " |
| 3070 | "l1 %#lx sva %#lx eva %#lx va_next %#lx", |
| 3071 | pmap_load(l1), sva, eva, va_next)); |
| 3072 | MPASS(pmap != kernel_pmap); |
| 3073 | MPASS((pmap_load(l1) & ATTR_SW_MANAGED) == 0); |
| 3074 | pmap_clear(l1); |
| 3075 | pmap_invalidate_page(pmap, sva); |
| 3076 | pmap_resident_count_dec(pmap, L1_SIZE / PAGE_SIZE); |
| 3077 | pmap_unuse_pt(pmap, sva, pmap_load(l0), &free); |
| 3078 | continue; |
| 3079 | } |
| 3080 | |
| 3081 | /* |
| 3082 | * Calculate index for next page table. |
| 3083 | */ |
| 3084 | va_next = (sva + L2_SIZE) & ~L2_OFFSET; |
| 3085 | if (va_next < sva) |
| 3086 | va_next = eva; |
no test coverage detected