Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/vmm/vmm_mmu.c
| Show First 20 Lines • Show All 344 Lines • ▼ Show 20 Lines | vmmpmap_remove(vm_offset_t va, vm_size_t size, bool invalidate) | ||||
| size_t i; | size_t i; | ||||
| KASSERT((va & L3_OFFSET) == 0, | KASSERT((va & L3_OFFSET) == 0, | ||||
| ("%s: Invalid virtual address", __func__)); | ("%s: Invalid virtual address", __func__)); | ||||
| KASSERT((size & PAGE_MASK) == 0, | KASSERT((size & PAGE_MASK) == 0, | ||||
| ("%s: Mapping is not page-sized", __func__)); | ("%s: Mapping is not page-sized", __func__)); | ||||
| if (invalidate) { | if (invalidate) { | ||||
| l3_list = malloc((size / PAGE_SIZE) * sizeof(l3_list[0]), | l3_list = malloc(atop(size) * sizeof(l3_list[0]), M_TEMP, | ||||
| M_TEMP, M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
| } | } | ||||
| sva = va; | sva = va; | ||||
| eva = va + size; | eva = va + size; | ||||
| mtx_lock(&vmmpmap_mtx); | mtx_lock(&vmmpmap_mtx); | ||||
| for (i = 0; va < eva; va = va_next) { | for (i = 0; va < eva; va = va_next) { | ||||
| l0e = atomic_load_64(&l0[pmap_l0_index(va)]); | l0e = atomic_load_64(&l0[pmap_l0_index(va)]); | ||||
| if (l0e == 0) { | MPASS(l0e != 0); | ||||
| va_next = (va + L0_SIZE) & ~L0_OFFSET; | |||||
| if (va_next < va) | |||||
| va_next = eva; | |||||
| continue; | |||||
| } | |||||
| MPASS((l0e & ATTR_DESCR_MASK) == L0_TABLE); | MPASS((l0e & ATTR_DESCR_MASK) == L0_TABLE); | ||||
| l1 = (pd_entry_t *)PHYS_TO_DMAP(l0e & ~ATTR_MASK); | l1 = (pd_entry_t *)PHYS_TO_DMAP(l0e & ~ATTR_MASK); | ||||
| l1e = atomic_load_64(&l1[pmap_l1_index(va)]); | l1e = atomic_load_64(&l1[pmap_l1_index(va)]); | ||||
| if (l1e == 0) { | MPASS(l1e != 0); | ||||
| va_next = (va + L1_SIZE) & ~L1_OFFSET; | |||||
| if (va_next < va) | |||||
| va_next = eva; | |||||
| continue; | |||||
| } | |||||
| MPASS((l1e & ATTR_DESCR_MASK) == L1_TABLE); | MPASS((l1e & ATTR_DESCR_MASK) == L1_TABLE); | ||||
| l2 = (pd_entry_t *)PHYS_TO_DMAP(l1e & ~ATTR_MASK); | l2 = (pd_entry_t *)PHYS_TO_DMAP(l1e & ~ATTR_MASK); | ||||
| l2e = atomic_load_64(&l2[pmap_l2_index(va)]); | l2e = atomic_load_64(&l2[pmap_l2_index(va)]); | ||||
| if (l2e == 0) { | MPASS(l2e != 0); | ||||
| va_next = (va + L2_SIZE) & ~L2_OFFSET; | |||||
| if (va_next < va) | |||||
| va_next = eva; | |||||
| continue; | |||||
| } | |||||
| MPASS((l2e & ATTR_DESCR_MASK) == L2_TABLE); | MPASS((l2e & ATTR_DESCR_MASK) == L2_TABLE); | ||||
| l3 = (pd_entry_t *)PHYS_TO_DMAP(l2e & ~ATTR_MASK); | l3 = (pd_entry_t *)PHYS_TO_DMAP(l2e & ~ATTR_MASK); | ||||
| if (invalidate) { | if (invalidate) { | ||||
| l3e = atomic_load_64(&l3[pmap_l3_index(va)]); | l3e = atomic_load_64(&l3[pmap_l3_index(va)]); | ||||
| MPASS(l3e != 0); | MPASS(l3e != 0); | ||||
| /* | /* | ||||
| * Mark memory as read-only so we can invalidate | * Mark memory as read-only so we can invalidate | ||||
| Show All 18 Lines | if (va_next < va) | ||||
| va_next = eva; | va_next = eva; | ||||
| } | } | ||||
| mtx_unlock(&vmmpmap_mtx); | mtx_unlock(&vmmpmap_mtx); | ||||
| if (invalidate) { | if (invalidate) { | ||||
| /* Invalidate the memory from the D-cache */ | /* Invalidate the memory from the D-cache */ | ||||
| vmm_call_hyp(HYP_DC_CIVAC, sva, size); | vmm_call_hyp(HYP_DC_CIVAC, sva, size); | ||||
| for (i = 0; i < (size / PAGE_SIZE); i++) { | for (i = 0; i < atop(size); i++) { | ||||
| atomic_store_64(l3_list[i], 0); | atomic_store_64(l3_list[i], 0); | ||||
| } | } | ||||
| vmm_call_hyp(HYP_EL2_TLBI, HYP_EL2_TLBI_VA, sva, size); | vmm_call_hyp(HYP_EL2_TLBI, HYP_EL2_TLBI_VA, sva, size); | ||||
| free(l3_list, M_TEMP); | free(l3_list, M_TEMP); | ||||
| } | } | ||||
| } | } | ||||