Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 3,468 Lines • ▼ Show 20 Lines | pmap_pv_promote_l2(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, | ||||
* a transfer avoids the possibility that get_pv_entry() calls | * a transfer avoids the possibility that get_pv_entry() calls | ||||
* reclaim_pv_chunk() and that reclaim_pv_chunk() removes one of the | * reclaim_pv_chunk() and that reclaim_pv_chunk() removes one of the | ||||
* mappings that is being promoted. | * mappings that is being promoted. | ||||
*/ | */ | ||||
m = PHYS_TO_VM_PAGE(pa); | m = PHYS_TO_VM_PAGE(pa); | ||||
va = va & ~L2_OFFSET; | va = va & ~L2_OFFSET; | ||||
pv = pmap_pvh_remove(&m->md, pmap, va); | pv = pmap_pvh_remove(&m->md, pmap, va); | ||||
KASSERT(pv != NULL, ("pmap_pv_promote_l2: pv not found")); | KASSERT(pv != NULL, ("pmap_pv_promote_l2: pv not found")); | ||||
pvh = pa_to_pvh(pa); | pvh = page_to_pvh(m); | ||||
TAILQ_INSERT_TAIL(&pvh->pv_list, pv, pv_next); | TAILQ_INSERT_TAIL(&pvh->pv_list, pv, pv_next); | ||||
pvh->pv_gen++; | pvh->pv_gen++; | ||||
/* Free the remaining NPTEPG - 1 pv entries. */ | /* Free the remaining NPTEPG - 1 pv entries. */ | ||||
va_last = va + L2_SIZE - PAGE_SIZE; | va_last = va + L2_SIZE - PAGE_SIZE; | ||||
do { | do { | ||||
m++; | m++; | ||||
va += PAGE_SIZE; | va += PAGE_SIZE; | ||||
pmap_pvh_free(&m->md, pmap, va); | pmap_pvh_free(&m->md, pmap, va); | ||||
▲ Show 20 Lines • Show All 405 Lines • ▼ Show 20 Lines | if ((orig_l3 & ATTR_SW_MANAGED) != 0) { | ||||
} | } | ||||
CHANGE_PV_LIST_LOCK_TO_PHYS(&lock, opa); | CHANGE_PV_LIST_LOCK_TO_PHYS(&lock, opa); | ||||
pv = pmap_pvh_remove(&om->md, pmap, va); | pv = pmap_pvh_remove(&om->md, pmap, va); | ||||
if ((m->oflags & VPO_UNMANAGED) != 0) | if ((m->oflags & VPO_UNMANAGED) != 0) | ||||
free_pv_entry(pmap, pv); | free_pv_entry(pmap, pv); | ||||
if ((om->a.flags & PGA_WRITEABLE) != 0 && | if ((om->a.flags & PGA_WRITEABLE) != 0 && | ||||
TAILQ_EMPTY(&om->md.pv_list) && | TAILQ_EMPTY(&om->md.pv_list) && | ||||
((om->flags & PG_FICTITIOUS) != 0 || | ((om->flags & PG_FICTITIOUS) != 0 || | ||||
TAILQ_EMPTY(&pa_to_pvh(opa)->pv_list))) | TAILQ_EMPTY(&page_to_pvh(om)->pv_list))) | ||||
vm_page_aflag_clear(om, PGA_WRITEABLE); | vm_page_aflag_clear(om, PGA_WRITEABLE); | ||||
} else { | } else { | ||||
KASSERT((orig_l3 & ATTR_AF) != 0, | KASSERT((orig_l3 & ATTR_AF) != 0, | ||||
("pmap_enter: unmanaged mapping lacks ATTR_AF")); | ("pmap_enter: unmanaged mapping lacks ATTR_AF")); | ||||
pmap_invalidate_page(pmap, va); | pmap_invalidate_page(pmap, va); | ||||
} | } | ||||
orig_l3 = 0; | orig_l3 = 0; | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 1,087 Lines • ▼ Show 20 Lines | */ | ||||
CHANGE_PV_LIST_LOCK_TO_VM_PAGE(&lock, m); | CHANGE_PV_LIST_LOCK_TO_VM_PAGE(&lock, m); | ||||
/* Mark free */ | /* Mark free */ | ||||
pc->pc_map[field] |= bitmask; | pc->pc_map[field] |= bitmask; | ||||
switch (lvl) { | switch (lvl) { | ||||
case 1: | case 1: | ||||
pmap_resident_count_dec(pmap, | pmap_resident_count_dec(pmap, | ||||
L2_SIZE / PAGE_SIZE); | L2_SIZE / PAGE_SIZE); | ||||
pvh = pa_to_pvh(tpte & ~ATTR_MASK); | pvh = page_to_pvh(m); | ||||
TAILQ_REMOVE(&pvh->pv_list, pv,pv_next); | TAILQ_REMOVE(&pvh->pv_list, pv,pv_next); | ||||
pvh->pv_gen++; | pvh->pv_gen++; | ||||
if (TAILQ_EMPTY(&pvh->pv_list)) { | if (TAILQ_EMPTY(&pvh->pv_list)) { | ||||
for (mt = m; mt < &m[L2_SIZE / PAGE_SIZE]; mt++) | for (mt = m; mt < &m[L2_SIZE / PAGE_SIZE]; mt++) | ||||
if ((mt->a.flags & PGA_WRITEABLE) != 0 && | if ((mt->a.flags & PGA_WRITEABLE) != 0 && | ||||
TAILQ_EMPTY(&mt->md.pv_list)) | TAILQ_EMPTY(&mt->md.pv_list)) | ||||
vm_page_aflag_clear(mt, PGA_WRITEABLE); | vm_page_aflag_clear(mt, PGA_WRITEABLE); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,015 Lines • Show Last 20 Lines |