Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/pmap-v6.c
Show First 20 Lines • Show All 2,063 Lines • ▼ Show 20 Lines | while (kernel_vm_end < addr) { | ||||
*/ | */ | ||||
kernel_vm_end_new = kernel_vm_end + PTE1_SIZE; | kernel_vm_end_new = kernel_vm_end + PTE1_SIZE; | ||||
pte2 = pt2tab_load(kern_pt2tab_entry(kernel_vm_end)); | pte2 = pt2tab_load(kern_pt2tab_entry(kernel_vm_end)); | ||||
if (!pte2_is_valid(pte2)) { | if (!pte2_is_valid(pte2)) { | ||||
/* | /* | ||||
* Install new PT2s page into kernel PT2TAB. | * Install new PT2s page into kernel PT2TAB. | ||||
*/ | */ | ||||
m = vm_page_alloc(NULL, | m = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT | | ||||
pte1_index(kernel_vm_end) & ~PT2PG_MASK, | |||||
VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | | |||||
VM_ALLOC_WIRED | VM_ALLOC_ZERO); | VM_ALLOC_WIRED | VM_ALLOC_ZERO); | ||||
if (m == NULL) | if (m == NULL) | ||||
panic("%s: no memory to grow kernel", __func__); | panic("%s: no memory to grow kernel", __func__); | ||||
m->pindex = pte1_index(kernel_vm_end) & ~PT2PG_MASK; | |||||
/* | /* | ||||
* QQQ: To link all new L2 page tables from L1 page | * QQQ: To link all new L2 page tables from L1 page | ||||
* table now and so pmap_kenter_pte1() them | * table now and so pmap_kenter_pte1() them | ||||
* at once together with pmap_kenter_pt2tab() | * at once together with pmap_kenter_pt2tab() | ||||
* could be nice speed up. However, | * could be nice speed up. However, | ||||
* pmap_growkernel() does not happen so often... | * pmap_growkernel() does not happen so often... | ||||
* QQQ: The other TTBR is another option. | * QQQ: The other TTBR is another option. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 397 Lines • ▼ Show 20 Lines | KASSERT(pte1_load(pte1p) == 0, | ||||
("%s: pm_pt1[%#x] is not zero: %#x", __func__, pte1_idx, | ("%s: pm_pt1[%#x] is not zero: %#x", __func__, pte1_idx, | ||||
pte1_load(pte1p))); | pte1_load(pte1p))); | ||||
pte2 = pt2tab_load(pmap_pt2tab_entry(pmap, va)); | pte2 = pt2tab_load(pmap_pt2tab_entry(pmap, va)); | ||||
if (!pte2_is_valid(pte2)) { | if (!pte2_is_valid(pte2)) { | ||||
/* | /* | ||||
* Install new PT2s page into pmap PT2TAB. | * Install new PT2s page into pmap PT2TAB. | ||||
*/ | */ | ||||
m = vm_page_alloc(NULL, pte1_idx & ~PT2PG_MASK, | m = vm_page_alloc_noobj(VM_ALLOC_WIRED | VM_ALLOC_ZERO); | ||||
VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO); | |||||
if (m == NULL) { | if (m == NULL) { | ||||
if ((flags & PMAP_ENTER_NOSLEEP) == 0) { | if ((flags & PMAP_ENTER_NOSLEEP) == 0) { | ||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
rw_wunlock(&pvh_global_lock); | rw_wunlock(&pvh_global_lock); | ||||
vm_wait(NULL); | vm_wait(NULL); | ||||
rw_wlock(&pvh_global_lock); | rw_wlock(&pvh_global_lock); | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
} | } | ||||
/* | /* | ||||
* Indicate the need to retry. While waiting, | * Indicate the need to retry. While waiting, | ||||
* the L2 page table page may have been allocated. | * the L2 page table page may have been allocated. | ||||
*/ | */ | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
m->pindex = pte1_idx & ~PT2PG_MASK; | |||||
pmap->pm_stats.resident_count++; | pmap->pm_stats.resident_count++; | ||||
pt2pg_pa = pmap_pt2pg_init(pmap, va, m); | pt2pg_pa = pmap_pt2pg_init(pmap, va, m); | ||||
} else { | } else { | ||||
pt2pg_pa = pte2_pa(pte2); | pt2pg_pa = pte2_pa(pte2); | ||||
m = PHYS_TO_VM_PAGE(pt2pg_pa); | m = PHYS_TO_VM_PAGE(pt2pg_pa); | ||||
} | } | ||||
pt2_wirecount_inc(m, pte1_idx); | pt2_wirecount_inc(m, pte1_idx); | ||||
▲ Show 20 Lines • Show All 541 Lines • ▼ Show 20 Lines | if (field < _NPCM) { | ||||
return (pv); | return (pv); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Access to the pte2list "pv_vafree" is synchronized by the pvh | * Access to the pte2list "pv_vafree" is synchronized by the pvh | ||||
* global lock. If "pv_vafree" is currently non-empty, it will | * global lock. If "pv_vafree" is currently non-empty, it will | ||||
* remain non-empty until pmap_pte2list_alloc() completes. | * remain non-empty until pmap_pte2list_alloc() completes. | ||||
*/ | */ | ||||
if (pv_vafree == 0 || (m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | | if (pv_vafree == 0 || | ||||
VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) { | (m = vm_page_alloc_noobj(VM_ALLOC_WIRED)) == NULL) { | ||||
if (try) { | if (try) { | ||||
pv_entry_count--; | pv_entry_count--; | ||||
PV_STAT(pc_chunk_tryfail++); | PV_STAT(pc_chunk_tryfail++); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
m = pmap_pv_reclaim(pmap); | m = pmap_pv_reclaim(pmap); | ||||
if (m == NULL) | if (m == NULL) | ||||
goto retry; | goto retry; | ||||
▲ Show 20 Lines • Show All 631 Lines • ▼ Show 20 Lines | if ((opte1 & PTE1_A) == 0 || (m = pmap_pt2_page(pmap, va)) == NULL) { | ||||
KASSERT(!pte1_is_wired(opte1), | KASSERT(!pte1_is_wired(opte1), | ||||
("%s: PT2 page for a wired mapping is missing", __func__)); | ("%s: PT2 page for a wired mapping is missing", __func__)); | ||||
/* | /* | ||||
* Invalidate the 1MB page mapping and return | * Invalidate the 1MB page mapping and return | ||||
* "failure" if the mapping was never accessed or the | * "failure" if the mapping was never accessed or the | ||||
* allocation of the new page table page fails. | * allocation of the new page table page fails. | ||||
*/ | */ | ||||
if ((opte1 & PTE1_A) == 0 || (m = vm_page_alloc(NULL, | if ((opte1 & PTE1_A) == 0 || | ||||
pte1_index(va) & ~PT2PG_MASK, VM_ALLOC_NOOBJ | | (m = vm_page_alloc_noobj(VM_ALLOC_WIRED)) == NULL) { | ||||
VM_ALLOC_NORMAL | VM_ALLOC_WIRED)) == NULL) { | |||||
SLIST_INIT(&free); | SLIST_INIT(&free); | ||||
pmap_remove_pte1(pmap, pte1p, pte1_trunc(va), &free); | pmap_remove_pte1(pmap, pte1p, pte1_trunc(va), &free); | ||||
vm_page_free_pages_toq(&free, false); | vm_page_free_pages_toq(&free, false); | ||||
CTR3(KTR_PMAP, "%s: failure for va %#x in pmap %p", | CTR3(KTR_PMAP, "%s: failure for va %#x in pmap %p", | ||||
__func__, va, pmap); | __func__, va, pmap); | ||||
return (FALSE); | return (FALSE); | ||||
} | } | ||||
m->pindex = pte1_index(va) & ~PT2PG_MASK; | |||||
if (va < VM_MAXUSER_ADDRESS) | if (va < VM_MAXUSER_ADDRESS) | ||||
pmap->pm_stats.resident_count++; | pmap->pm_stats.resident_count++; | ||||
isnew = 1; | isnew = 1; | ||||
/* | /* | ||||
* We init all L2 page tables in the page even if | * We init all L2 page tables in the page even if | ||||
* we are going to change everything for one L2 page | * we are going to change everything for one L2 page | ||||
▲ Show 20 Lines • Show All 3,224 Lines • Show Last 20 Lines |