632,6 → 632,29 |
interrupts_restore(ipl); |
} |
|
/** Check access mode for address space area. |
* |
* The address space area must be locked prior to this call. |
* |
* @param area Address space area. |
* @param access Access mode. |
* |
* @return False if access violates area's permissions, true otherwise. |
*/ |
bool as_area_check_access(as_area_t *area, pf_access_t access) |
{ |
int flagmap[] = { |
[PF_ACCESS_READ] = AS_AREA_READ, |
[PF_ACCESS_WRITE] = AS_AREA_WRITE, |
[PF_ACCESS_EXEC] = AS_AREA_EXEC |
}; |
|
if (!(area->flags & flagmap[access])) |
return false; |
|
return true; |
} |
|
/** Handle page fault within the current address space. |
* |
* This is the high-level page fault handler. It decides |
698,10 → 721,14 |
*/ |
if ((pte = page_mapping_find(AS, page))) { |
if (PTE_PRESENT(pte)) { |
page_table_unlock(AS, false); |
mutex_unlock(&area->lock); |
mutex_unlock(&AS->lock); |
return AS_PF_OK; |
if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) || |
(access == PF_ACCESS_WRITE && PTE_WRITABLE(pte)) || |
(access == PF_ACCESS_EXEC && PTE_EXECUTABLE(pte))) { |
page_table_unlock(AS, false); |
mutex_unlock(&area->lock); |
mutex_unlock(&AS->lock); |
return AS_PF_OK; |
} |
} |
} |
|
1495,6 → 1522,9 |
{ |
__address frame; |
|
if (!as_area_check_access(area, access)) |
return AS_PF_FAULT; |
|
if (area->sh_info) { |
btree_node_t *leaf; |
|