Changeset View
Changeset View
Standalone View
Standalone View
sys/mips/mips/pmap.c
Show First 20 Lines • Show All 789 Lines • ▼ Show 20 Lines | |||||
* 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) | ||||
{ | { | ||||
pt_entry_t pte, *ptep; | pt_entry_t pte, *ptep; | ||||
vm_paddr_t pa, pte_pa; | vm_paddr_t pa; | ||||
vm_page_t m; | vm_page_t m; | ||||
m = NULL; | m = NULL; | ||||
pa = 0; | |||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
retry: | |||||
ptep = pmap_pte(pmap, va); | ptep = pmap_pte(pmap, va); | ||||
if (ptep != NULL) { | if (ptep != NULL) { | ||||
pte = *ptep; | pte = *ptep; | ||||
if (pte_test(&pte, PTE_V) && (!pte_test(&pte, PTE_RO) || | if (pte_test(&pte, PTE_V) && (!pte_test(&pte, PTE_RO) || | ||||
(prot & VM_PROT_WRITE) == 0)) { | (prot & VM_PROT_WRITE) == 0)) { | ||||
pte_pa = TLBLO_PTE_TO_PA(pte); | pa = TLBLO_PTE_TO_PA(pte); | ||||
if (vm_page_pa_tryrelock(pmap, pte_pa, &pa)) | m = PHYS_TO_VM_PAGE(pa); | ||||
goto retry; | if (!vm_page_wire_mapped(m)) | ||||
m = PHYS_TO_VM_PAGE(pte_pa); | m = NULL; | ||||
vm_page_wire(m); | |||||
} | } | ||||
} | } | ||||
PA_UNLOCK_COND(pa); | |||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
return (m); | return (m); | ||||
} | } | ||||
/*************************************************** | /*************************************************** | ||||
* Low level mapping routines..... | * Low level mapping routines..... | ||||
***************************************************/ | ***************************************************/ | ||||
▲ Show 20 Lines • Show All 2,876 Lines • Show Last 20 Lines |