Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/pmap-v6.c
Show First 20 Lines • Show All 1,627 Lines • ▼ Show 20 Lines | |||||
static __inline void | static __inline void | ||||
pagezero(void *page) | pagezero(void *page) | ||||
{ | { | ||||
bzero(page, PAGE_SIZE); | bzero(page, PAGE_SIZE); | ||||
} | } | ||||
/* | /* | ||||
* Zero L2 page table page. | * Sync L2 page table page. | ||||
* Use same KVA as in pmap_zero_page(). | * Use same KVA as in pmap_zero_page(). | ||||
*/ | */ | ||||
static __inline vm_paddr_t | static __inline vm_paddr_t | ||||
pmap_pt2pg_zero(vm_page_t m) | pmap_pt2pg_sync(vm_page_t m) | ||||
{ | { | ||||
pt2_entry_t *cmap2_pte2p; | pt2_entry_t *cmap2_pte2p; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
struct pcpu *pc; | struct pcpu *pc; | ||||
pa = VM_PAGE_TO_PHYS(m); | pa = VM_PAGE_TO_PHYS(m); | ||||
/* | /* | ||||
* XXX: For now, we map whole page even if it's already zero, | * XXX: For now, we map whole page even if it's already zero, | ||||
* to sync it even if the sync is only DSB. | * to sync it even if the sync is only DSB. | ||||
*/ | */ | ||||
sched_pin(); | sched_pin(); | ||||
pc = get_pcpu(); | pc = get_pcpu(); | ||||
cmap2_pte2p = pc->pc_cmap2_pte2p; | cmap2_pte2p = pc->pc_cmap2_pte2p; | ||||
mtx_lock(&pc->pc_cmap_lock); | mtx_lock(&pc->pc_cmap_lock); | ||||
if (pte2_load(cmap2_pte2p) != 0) | if (pte2_load(cmap2_pte2p) != 0) | ||||
panic("%s: CMAP2 busy", __func__); | panic("%s: CMAP2 busy", __func__); | ||||
pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW, | pte2_store(cmap2_pte2p, PTE2_KERN_NG(pa, PTE2_AP_KRW, | ||||
vm_page_pte2_attr(m))); | vm_page_pte2_attr(m))); | ||||
/* Even VM_ALLOC_ZERO request is only advisory. */ | |||||
if ((m->flags & PG_ZERO) == 0) | |||||
pagezero(pc->pc_cmap2_addr); | |||||
pte2_sync_range((pt2_entry_t *)pc->pc_cmap2_addr, PAGE_SIZE); | pte2_sync_range((pt2_entry_t *)pc->pc_cmap2_addr, PAGE_SIZE); | ||||
pte2_clear(cmap2_pte2p); | pte2_clear(cmap2_pte2p); | ||||
tlb_flush((vm_offset_t)pc->pc_cmap2_addr); | tlb_flush((vm_offset_t)pc->pc_cmap2_addr); | ||||
/* | /* | ||||
* Unpin the thread before releasing the lock. Otherwise the thread | * Unpin the thread before releasing the lock. Otherwise the thread | ||||
* could be rescheduled while still bound to the current CPU, only | * could be rescheduled while still bound to the current CPU, only | ||||
* to unpin itself immediately upon resuming execution. | * to unpin itself immediately upon resuming execution. | ||||
Show All 13 Lines | |||||
{ | { | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
pt2_entry_t *pte2p; | pt2_entry_t *pte2p; | ||||
/* Check page attributes. */ | /* Check page attributes. */ | ||||
if (m->md.pat_mode != pt_memattr) | if (m->md.pat_mode != pt_memattr) | ||||
pmap_page_set_memattr(m, pt_memattr); | pmap_page_set_memattr(m, pt_memattr); | ||||
/* Zero page and init wire counts. */ | /* Sync page and init wire counts. */ | ||||
pa = pmap_pt2pg_zero(m); | pa = pmap_pt2pg_sync(m); | ||||
pt2_wirecount_init(m); | pt2_wirecount_init(m); | ||||
/* | /* | ||||
* Map page to PT2MAP address space for given pmap. | * Map page to PT2MAP address space for given pmap. | ||||
* Note that PT2MAP space is shared with all pmaps. | * Note that PT2MAP space is shared with all pmaps. | ||||
*/ | */ | ||||
if (pmap == kernel_pmap) | if (pmap == kernel_pmap) | ||||
pmap_kenter_pt2tab(va, PTE2_KPT(pa)); | pmap_kenter_pt2tab(va, PTE2_KPT(pa)); | ||||
▲ Show 20 Lines • Show All 2,006 Lines • ▼ Show 20 Lines | if ((opte1 & PTE1_A) == 0 || (m = pmap_pt2_page(pmap, va)) == NULL) { | ||||
/* | /* | ||||
* 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 || (m = vm_page_alloc(NULL, | ||||
pte1_index(va) & ~PT2PG_MASK, VM_ALLOC_NOOBJ | | pte1_index(va) & ~PT2PG_MASK, VM_ALLOC_NOOBJ | | ||||
VM_ALLOC_NORMAL | VM_ALLOC_WIRED)) == NULL) { | VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == | ||||
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); | ||||
} | } | ||||
if (va < VM_MAXUSER_ADDRESS) | if (va < VM_MAXUSER_ADDRESS) | ||||
▲ Show 20 Lines • Show All 3,231 Lines • Show Last 20 Lines |