Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 1,058 Lines • ▼ Show 20 Lines | |||||
* 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, tpte; | pt_entry_t *pte, tpte; | ||||
vm_offset_t off; | vm_offset_t off; | ||||
vm_paddr_t pa; | |||||
vm_page_t m; | vm_page_t m; | ||||
int lvl; | int lvl; | ||||
pa = 0; | |||||
m = NULL; | m = NULL; | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
retry: | |||||
pte = pmap_pte(pmap, va, &lvl); | pte = pmap_pte(pmap, va, &lvl); | ||||
if (pte != NULL) { | if (pte != NULL) { | ||||
tpte = pmap_load(pte); | tpte = pmap_load(pte); | ||||
KASSERT(lvl > 0 && lvl <= 3, | KASSERT(lvl > 0 && lvl <= 3, | ||||
("pmap_extract_and_hold: Invalid level %d", lvl)); | ("pmap_extract_and_hold: Invalid level %d", lvl)); | ||||
CTASSERT(L1_BLOCK == L2_BLOCK); | CTASSERT(L1_BLOCK == L2_BLOCK); | ||||
KASSERT((lvl == 3 && (tpte & ATTR_DESCR_MASK) == L3_PAGE) || | KASSERT((lvl == 3 && (tpte & ATTR_DESCR_MASK) == L3_PAGE) || | ||||
(lvl < 3 && (tpte & ATTR_DESCR_MASK) == L1_BLOCK), | (lvl < 3 && (tpte & ATTR_DESCR_MASK) == L1_BLOCK), | ||||
("pmap_extract_and_hold: Invalid pte at L%d: %lx", lvl, | ("pmap_extract_and_hold: Invalid pte at L%d: %lx", lvl, | ||||
tpte & ATTR_DESCR_MASK)); | tpte & ATTR_DESCR_MASK)); | ||||
if (((tpte & ATTR_AP_RW_BIT) == ATTR_AP(ATTR_AP_RW)) || | if (((tpte & ATTR_AP_RW_BIT) == ATTR_AP(ATTR_AP_RW)) || | ||||
((prot & VM_PROT_WRITE) == 0)) { | ((prot & VM_PROT_WRITE) == 0)) { | ||||
switch(lvl) { | switch(lvl) { | ||||
case 1: | case 1: | ||||
off = va & L1_OFFSET; | off = va & L1_OFFSET; | ||||
break; | break; | ||||
case 2: | case 2: | ||||
off = va & L2_OFFSET; | off = va & L2_OFFSET; | ||||
break; | break; | ||||
case 3: | case 3: | ||||
default: | default: | ||||
off = 0; | off = 0; | ||||
} | } | ||||
if (vm_page_pa_tryrelock(pmap, | |||||
(tpte & ~ATTR_MASK) | off, &pa)) | |||||
goto retry; | |||||
m = PHYS_TO_VM_PAGE((tpte & ~ATTR_MASK) | off); | m = PHYS_TO_VM_PAGE((tpte & ~ATTR_MASK) | off); | ||||
vm_page_wire(m); | if (!vm_page_wire_mapped(m)) | ||||
m = NULL; | |||||
} | } | ||||
} | } | ||||
PA_UNLOCK_COND(pa); | |||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
return (m); | return (m); | ||||
} | } | ||||
vm_paddr_t | vm_paddr_t | ||||
pmap_kextract(vm_offset_t va) | pmap_kextract(vm_offset_t va) | ||||
{ | { | ||||
pt_entry_t *pte, tpte; | pt_entry_t *pte, tpte; | ||||
▲ Show 20 Lines • Show All 4,304 Lines • Show Last 20 Lines |