Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/pmap.c
Show First 20 Lines • Show All 4,220 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) | pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) | ||||
{ | { | ||||
m->md.pv_memattr = ma; | m->md.pv_memattr = ma; | ||||
} | } | ||||
/* | /* | ||||
* perform the pmap work for mincore | * Perform the pmap work for mincore(2). If the page is not both referenced and | ||||
* modified by this pmap, returns its physical address so that the caller can | |||||
* find other mappings. | |||||
*/ | */ | ||||
int | int | ||||
pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa) | pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap) | ||||
{ | { | ||||
pt_entry_t *l2, *l3, tpte; | pt_entry_t *l2, *l3, tpte; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
int val; | int val; | ||||
bool managed; | bool managed; | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
retry: | |||||
managed = false; | |||||
val = 0; | |||||
l2 = pmap_l2(pmap, addr); | l2 = pmap_l2(pmap, addr); | ||||
if (l2 != NULL && ((tpte = pmap_load(l2)) & PTE_V) != 0) { | if (l2 != NULL && ((tpte = pmap_load(l2)) & PTE_V) != 0) { | ||||
if ((tpte & PTE_RWX) != 0) { | if ((tpte & PTE_RWX) != 0) { | ||||
pa = PTE_TO_PHYS(tpte) | (addr & L2_OFFSET); | pa = PTE_TO_PHYS(tpte) | (addr & L2_OFFSET); | ||||
val = MINCORE_INCORE | MINCORE_SUPER; | val = MINCORE_INCORE | MINCORE_SUPER; | ||||
} else { | } else { | ||||
l3 = pmap_l2_to_l3(l2, addr); | l3 = pmap_l2_to_l3(l2, addr); | ||||
tpte = pmap_load(l3); | tpte = pmap_load(l3); | ||||
if ((tpte & PTE_V) == 0) | if ((tpte & PTE_V) == 0) { | ||||
goto done; | PMAP_UNLOCK(pmap); | ||||
return (0); | |||||
} | |||||
pa = PTE_TO_PHYS(tpte) | (addr & L3_OFFSET); | pa = PTE_TO_PHYS(tpte) | (addr & L3_OFFSET); | ||||
val = MINCORE_INCORE; | val = MINCORE_INCORE; | ||||
} | } | ||||
if ((tpte & PTE_D) != 0) | if ((tpte & PTE_D) != 0) | ||||
val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; | val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; | ||||
if ((tpte & PTE_A) != 0) | if ((tpte & PTE_A) != 0) | ||||
val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER; | val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER; | ||||
managed = (tpte & PTE_SW_MANAGED) == PTE_SW_MANAGED; | managed = (tpte & PTE_SW_MANAGED) == PTE_SW_MANAGED; | ||||
} else { | |||||
managed = false; | |||||
val = 0; | |||||
} | } | ||||
done: | |||||
if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) != | if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) != | ||||
(MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && managed) { | (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && managed) { | ||||
/* Ensure that "PHYS_TO_VM_PAGE(pa)->object" doesn't change. */ | *pap = pa; | ||||
if (vm_page_pa_tryrelock(pmap, pa, locked_pa)) | } | ||||
goto retry; | |||||
} else | |||||
PA_UNLOCK_COND(*locked_pa); | |||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
return (val); | return (val); | ||||
} | } | ||||
void | void | ||||
pmap_activate_sw(struct thread *td) | pmap_activate_sw(struct thread *td) | ||||
{ | { | ||||
pmap_t oldpmap, pmap; | pmap_t oldpmap, pmap; | ||||
▲ Show 20 Lines • Show All 209 Lines • Show Last 20 Lines |