//kernel/trunk/generic/include/mm/page.h |
---|
60,6 → 60,14 |
#define PAGE_GLOBAL (1<<PAGE_GLOBAL_SHIFT) |
/** Page fault access type. */ |
enum pf_access { |
PF_ACCESS_READ, |
PF_ACCESS_WRITE, |
PF_ACCESS_EXEC |
}; |
typedef enum pf_access pf_access_t; |
/** Operations to manipulate page mappings. */ |
struct page_mapping_operations { |
void (* mapping_insert)(as_t *as, __address page, __address frame, int flags); |
//kernel/trunk/generic/include/mm/as.h |
---|
127,7 → 127,7 |
/** Address space area backend structure. */ |
struct mem_backend { |
int (* backend_page_fault)(as_area_t *area, __address addr); |
int (* backend_page_fault)(as_area_t *area, __address addr, pf_access_t access); |
void (* backend_frame_free)(as_area_t *area, __address page, __address frame); |
}; |
145,7 → 145,7 |
extern int as_area_destroy(as_t *as, __address address); |
extern int as_area_get_flags(as_area_t *area); |
extern void as_set_mapping(as_t *as, __address page, __address frame); |
extern int as_page_fault(__address page, istate_t *istate); |
extern int as_page_fault(__address page, pf_access_t access, istate_t *istate); |
extern void as_switch(as_t *old, as_t *new); |
extern void as_free(as_t *as); |
extern int as_area_steal(task_t *src_task, __address src_base, size_t acc_size, __address dst_base); |
//kernel/trunk/generic/src/lib/elf.c |
---|
56,7 → 56,7 |
static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as); |
static int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as); |
static int elf_page_fault(as_area_t *area, __address addr); |
static int elf_page_fault(as_area_t *area, __address addr, pf_access_t access); |
static void elf_frame_free(as_area_t *area, __address page, __address frame); |
mem_backend_t elf_backend = { |
225,10 → 225,11 |
* |
* @param area Pointer to the address space area. |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced). |
*/ |
int elf_page_fault(as_area_t *area, __address addr) |
int elf_page_fault(as_area_t *area, __address addr, pf_access_t access) |
{ |
elf_header_t *elf = (elf_header_t *) area->backend_data[0]; |
elf_segment_header_t *entry = (elf_segment_header_t *) area->backend_data[1]; |
//kernel/trunk/generic/src/mm/as.c |
---|
375,6 → 375,7 |
as_area_t *area; |
__address base; |
ipl_t ipl; |
bool cond; |
ipl = interrupts_disable(); |
mutex_lock(&as->lock); |
387,16 → 388,8 |
} |
base = area->base; |
if (!(area->flags & AS_AREA_DEVICE)) { |
bool cond; |
/* |
* Releasing physical memory. |
* Areas mapping memory-mapped devices are treated differently than |
* areas backing frame_alloc()'ed memory. |
*/ |
/* |
* Visit only the pages mapped by used_space B+tree. |
* Note that we must be very careful when walking the tree |
* leaf list and removing used space as the leaf list changes |
429,7 → 422,6 |
panic("Could not remove used space.\n"); |
} |
} |
} |
btree_destroy(&area->used_space); |
/* |
623,12 → 615,13 |
* Interrupts are assumed disabled. |
* |
* @param page Faulting page. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* @param istate Pointer to interrupted state. |
* |
* @return AS_PF_FAULT on page fault, AS_PF_OK on success or AS_PF_DEFER if the |
* fault was caused by copy_to_uspace() or copy_from_uspace(). |
*/ |
int as_page_fault(__address page, istate_t *istate) |
int as_page_fault(__address page, pf_access_t access, istate_t *istate) |
{ |
pte_t *pte; |
as_area_t *area; |
688,7 → 681,7 |
/* |
* Resort to the backend page fault handler. |
*/ |
if (area->backend->backend_page_fault(area, page) != AS_PF_OK) { |
if (area->backend->backend_page_fault(area, page, access) != AS_PF_OK) { |
page_table_unlock(AS, false); |
mutex_unlock(&area->lock); |
mutex_unlock(&AS->lock); |
1450,7 → 1443,7 |
} |
} |
static int anon_page_fault(as_area_t *area, __address addr); |
static int anon_page_fault(as_area_t *area, __address addr, pf_access_t access); |
static void anon_frame_free(as_area_t *area, __address page, __address frame); |
/* |
1467,10 → 1460,11 |
* |
* @param area Pointer to the address space area. |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced). |
*/ |
int anon_page_fault(as_area_t *area, __address addr) |
int anon_page_fault(as_area_t *area, __address addr, pf_access_t access) |
{ |
__address frame; |