From: Matthias Kruk Date: Tue, 10 Dec 2019 08:46:37 +0000 (+0900) Subject: Print the affected page directory and page table entries, when a page fault occurs... X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=59b9539c95343f6676e88a8a433be7a7bb242472;p=corax Print the affected page directory and page table entries, when a page fault occurs; make sure PAGE_ATTR_WRITABLE is set on the page table, if it contains writable pages --- diff --git a/kernel/arch/heap.c b/kernel/arch/heap.c index 0a85534..8a248ae 100644 --- a/kernel/arch/heap.c +++ b/kernel/arch/heap.c @@ -30,7 +30,7 @@ struct heap_node { u32_t hn_flags; }; -static struct { +struct { void *h_base; u32_t h_size; u32_t h_free; diff --git a/kernel/arch/interrupt.c b/kernel/arch/interrupt.c index 728c4ce..1ad7d04 100644 --- a/kernel/arch/interrupt.c +++ b/kernel/arch/interrupt.c @@ -25,6 +25,8 @@ #include "cpu.h" #include "defs.h" +extern void pg_fault_debug(pg_dir_t*, void*); + void sched_tick(void); extern int sys_cxnet(long, long, long, long, long, long, long); extern int sys_cxipc(long, long, long); @@ -139,9 +141,14 @@ void _exc_handle(stack_frame_t ctx) if(ctx.intn == EXC_PAGEFAULT) { u32_t cr2; + pg_dir_t *pd; asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2)); dbg_printf("Page fault address: 0x%08x\n", cr2); + + if(process_get_pagedir(cproc, &pd) == 0) { + pg_fault_debug(pd, (void*)cr2); + } } PANIC("Unhandled exception"); diff --git a/kernel/arch/paging.c b/kernel/arch/paging.c index 978cf54..fd64607 100644 --- a/kernel/arch/paging.c +++ b/kernel/arch/paging.c @@ -887,6 +887,10 @@ int _clone_kernel_region(pg_dir_t *kdir, region_t *reg, void *data) dir = (pg_dir_t*)data; switch(reg->reg_type) { + case REGION_DATA: + ret_val = pg_dir_clone_region(dir, kdir, reg); + break; + case REGION_TEXT: case REGION_RODATA: case REGION_HEAP: @@ -895,7 +899,6 @@ int _clone_kernel_region(pg_dir_t *kdir, region_t *reg, void *data) * directory since they cannot be modified or removed anyways. */ case REGION_BSS: - case REGION_DATA: /* * The way the interrupt handling is currently implemented, accesses to the * _cpu structure and _kernel_cr3 are made within the context (i.e. using @@ -1090,6 +1093,11 @@ static int _pg_dir_map_legacy(page_table_t *pd, u32_t paddr, u32_t vaddr, pd->pt_entries[pde] |= PAGE_ATTR_USER; } + /* also make sure the page table is writable, if necessary */ + if(flags & PAGE_ATTR_WRITABLE) { + pd->pt_entries[pde] |= PAGE_ATTR_WRITABLE; + } + if(pt->pt_entries[pte] & PAGE_ATTR_PRESENT) { ret_val = -EALREADY; break; @@ -1098,7 +1106,6 @@ static int _pg_dir_map_legacy(page_table_t *pd, u32_t paddr, u32_t vaddr, /* allocate new frames if caller didn't specify a physical address */ if(!paddr) { pt->pt_entries[pte] = (u32_t)pg_frame_alloc_end(); - dbg_printf("Allocating page: %04u - 0x%08x\n", pte, pt->pt_entries[pte]); } else { pt->pt_entries[pte] = paddr; paddr += PAGE_SIZE; @@ -1309,7 +1316,7 @@ int pg_dir_clone_region(pg_dir_t *dpd, pg_dir_t *spd, region_t *reg) /* attempt to map the region */ ret_val = pg_dir_map(dpd, NULL, reg->reg_base, - reg->reg_size, reg->reg_attrs); + reg->reg_size, reg->reg_attrs | PAGE_ATTR_USER); if(ret_val < 0) { goto gtfo; @@ -1323,7 +1330,7 @@ int pg_dir_clone_region(pg_dir_t *dpd, pg_dir_t *spd, region_t *reg) if(ret_val >= 0) { /* also keep track of the region */ ret_val = _pg_dir_add_region(dpd, reg->reg_base, reg->reg_size, - reg->reg_type, reg->reg_attrs, reg->reg_flags); + reg->reg_type, reg->reg_attrs, reg->reg_flags | PAGE_ATTR_USER); } if(ret_val < 0) { @@ -1509,3 +1516,37 @@ void* pg_dir_sbrk(pg_dir_t *pd, i32_t increment) return(ret_val); } + +void pg_fault_debug(pg_dir_t *pdir, void *addr) +{ + u64_t pde; + u64_t pte; + u32_t pdi; + u32_t pti; + + switch(_pg_flags & PG_MODE_MASK) { + case PG_MODE_LEGACY: + pdi = ((u32_t)addr & 0xffc00000) >> 22; + pti = ((u32_t)addr & 0x003ff000) >> 12; + + pde = ((page_table_t*)pdir->pd_base)->pt_entries[pdi]; + + dbg_printf("pdir[%03u] = 0x%08x\n", pdi, (u32_t)pde); + + if(!(pde & PAGE_ATTR_SIZE)) { + pte = ((page_table_t*)(pde & 0xfffff000))->pt_entries[pti]; + dbg_printf("pdir[%03u][%03u] = 0x%08x\n", pdi, pti, (u32_t)pte); + } + + break; + + case PG_MODE_PAE: + break; + + default: + /* not handled yet */ + break; + } + + return; +}