Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/pmap-v6.c
Show First 20 Lines • Show All 1,980 Lines • ▼ Show 20 Lines | |||||
* Function: | * Function: | ||||
* Atomically extract and hold the physical page | * Atomically extract and hold the physical page | ||||
* with the given pmap and virtual address pair | * with the given pmap and virtual address pair | ||||
* if that mapping permits the given protection. | * if that mapping permits the given protection. | ||||
*/ | */ | ||||
vm_page_t | vm_page_t | ||||
pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) | pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) | ||||
{ | { | ||||
vm_paddr_t pa, lockpa; | vm_paddr_t pa; | ||||
pt1_entry_t pte1; | pt1_entry_t pte1; | ||||
pt2_entry_t pte2, *pte2p; | pt2_entry_t pte2, *pte2p; | ||||
vm_page_t m; | vm_page_t m; | ||||
lockpa = 0; | |||||
m = NULL; | m = NULL; | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
retry: | |||||
pte1 = pte1_load(pmap_pte1(pmap, va)); | pte1 = pte1_load(pmap_pte1(pmap, va)); | ||||
if (pte1_is_section(pte1)) { | if (pte1_is_section(pte1)) { | ||||
if (!(pte1 & PTE1_RO) || !(prot & VM_PROT_WRITE)) { | if (!(pte1 & PTE1_RO) || !(prot & VM_PROT_WRITE)) { | ||||
pa = pte1_pa(pte1) | (va & PTE1_OFFSET); | pa = pte1_pa(pte1) | (va & PTE1_OFFSET); | ||||
if (vm_page_pa_tryrelock(pmap, pa, &lockpa)) | |||||
goto retry; | |||||
m = PHYS_TO_VM_PAGE(pa); | m = PHYS_TO_VM_PAGE(pa); | ||||
vm_page_wire(m); | if (!vm_page_wire_mapped(m)) | ||||
m = NULL; | |||||
} | } | ||||
} else if (pte1_is_link(pte1)) { | } else if (pte1_is_link(pte1)) { | ||||
pte2p = pmap_pte2(pmap, va); | pte2p = pmap_pte2(pmap, va); | ||||
pte2 = pte2_load(pte2p); | pte2 = pte2_load(pte2p); | ||||
pmap_pte2_release(pte2p); | pmap_pte2_release(pte2p); | ||||
if (pte2_is_valid(pte2) && | if (pte2_is_valid(pte2) && | ||||
(!(pte2 & PTE2_RO) || !(prot & VM_PROT_WRITE))) { | (!(pte2 & PTE2_RO) || !(prot & VM_PROT_WRITE))) { | ||||
pa = pte2_pa(pte2); | pa = pte2_pa(pte2); | ||||
if (vm_page_pa_tryrelock(pmap, pa, &lockpa)) | |||||
goto retry; | |||||
m = PHYS_TO_VM_PAGE(pa); | m = PHYS_TO_VM_PAGE(pa); | ||||
vm_page_wire(m); | if (!vm_page_wire_mapped(m)) | ||||
m = NULL; | |||||
} | } | ||||
} | } | ||||
PA_UNLOCK_COND(lockpa); | |||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
return (m); | return (m); | ||||
} | } | ||||
/* | /* | ||||
* Grow the number of kernel L2 page table entries, if needed. | * Grow the number of kernel L2 page table entries, if needed. | ||||
*/ | */ | ||||
void | void | ||||
▲ Show 20 Lines • Show All 4,953 Lines • Show Last 20 Lines |