Changeset View
Changeset View
Standalone View
Standalone View
sys/mips/mips/pmap.c
Show First 20 Lines • Show All 3,200 Lines • ▼ Show 20 Lines | #ifndef __mips_n64 | ||||
base = trunc_page(va); | base = trunc_page(va); | ||||
offset = va & PAGE_MASK; | offset = va & PAGE_MASK; | ||||
size = roundup(size + offset, PAGE_SIZE); | size = roundup(size + offset, PAGE_SIZE); | ||||
kva_free(base, size); | kva_free(base, size); | ||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
* 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 *ptep, pte; | pt_entry_t *ptep, pte; | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
vm_page_t m; | vm_page_t m; | ||||
int val; | int val; | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
retry: | |||||
ptep = pmap_pte(pmap, addr); | ptep = pmap_pte(pmap, addr); | ||||
pte = (ptep != NULL) ? *ptep : 0; | pte = (ptep != NULL) ? *ptep : 0; | ||||
if (!pte_test(&pte, PTE_V)) { | if (!pte_test(&pte, PTE_V)) { | ||||
val = 0; | PMAP_UNLOCK(pmap); | ||||
goto out; | return (0); | ||||
} | } | ||||
val = MINCORE_INCORE; | val = MINCORE_INCORE; | ||||
if (pte_test(&pte, PTE_D)) | if (pte_test(&pte, PTE_D)) | ||||
val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; | val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER; | ||||
pa = TLBLO_PTE_TO_PA(pte); | pa = TLBLO_PTE_TO_PA(pte); | ||||
if (pte_test(&pte, PTE_MANAGED)) { | if (pte_test(&pte, PTE_MANAGED)) { | ||||
/* | /* | ||||
* This may falsely report the given address as | * This may falsely report the given address as | ||||
* MINCORE_REFERENCED. Unfortunately, due to the lack of | * MINCORE_REFERENCED. Unfortunately, due to the lack of | ||||
* per-PTE reference information, it is impossible to | * per-PTE reference information, it is impossible to | ||||
* determine if the address is MINCORE_REFERENCED. | * determine if the address is MINCORE_REFERENCED. | ||||
*/ | */ | ||||
m = PHYS_TO_VM_PAGE(pa); | m = PHYS_TO_VM_PAGE(pa); | ||||
if ((m->aflags & PGA_REFERENCED) != 0) | if ((m->aflags & PGA_REFERENCED) != 0) | ||||
val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER; | val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER; | ||||
} | } | ||||
if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) != | if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) != | ||||
(MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && | (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && | ||||
pte_test(&pte, PTE_MANAGED)) { | pte_test(&pte, PTE_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 | |||||
out: | |||||
PA_UNLOCK_COND(*locked_pa); | |||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
return (val); | return (val); | ||||
} | } | ||||
void | void | ||||
pmap_activate(struct thread *td) | pmap_activate(struct thread *td) | ||||
{ | { | ||||
pmap_t pmap, oldpmap; | pmap_t pmap, oldpmap; | ||||
▲ Show 20 Lines • Show All 406 Lines • Show Last 20 Lines |