Added simple exception handler that prints stuff
This commit is contained in:
parent
ec591bbb54
commit
5f9ce34445
@ -17,6 +17,7 @@
|
||||
|
||||
#include <aos/solution.h>
|
||||
|
||||
#define VADDR_LOWEST_NON_NULL (64 * 1024)
|
||||
#define VADDR_OFFSET ((lvaddr_t)512UL*1024*1024*1024) // 1GB
|
||||
#define VADDR_SIZE (1UL << 48)
|
||||
#define VREGION_FLAGS_READ 0x01 // Reading allowed
|
||||
|
||||
@ -21,8 +21,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static struct paging_state current;
|
||||
|
||||
#define PT_PT_SLAB_MIN_SPACE 18
|
||||
#define PT_CHILDREN_SLAB_MIN_SPACE 12
|
||||
|
||||
@ -30,6 +28,62 @@ static struct paging_state current;
|
||||
#define PT_PT_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_PT_SLAB_MIN_SPACE, PT_META_MAX_SIZE)
|
||||
#define PT_CHILDREN_SLAB_INITIAL_SPACE SLAB_STATIC_SIZE(PT_CHILDREN_SLAB_MIN_SPACE, PT_CHILD_ARRAY_SIZE)
|
||||
|
||||
#define PT_STATIC_EXCEPTION_STACK_SIZE (4 * BASE_PAGE_SIZE)
|
||||
|
||||
static struct paging_state current;
|
||||
// initial page fault handler stack space
|
||||
static char pt_static_exception_stack[PT_STATIC_EXCEPTION_STACK_SIZE];
|
||||
|
||||
static char *pt_exception_type_to_string(enum exception_type type, int subtype)
|
||||
{
|
||||
switch(type) {
|
||||
case EXCEPT_NULL:
|
||||
return "EXCEPT_NULL";
|
||||
case EXCEPT_PAGEFAULT:
|
||||
switch(subtype) {
|
||||
case PAGEFLT_NULL:
|
||||
return "EXCEPT_PAGEFAULT(Not mapped)";
|
||||
case PAGEFLT_READ:
|
||||
return "EXCEPT_PAGEFAULT(READ)";
|
||||
case PAGEFLT_WRITE:
|
||||
return "EXCEPT_PAGEFAULT(WRITE)";
|
||||
case PAGEFLT_EXEC:
|
||||
return "EXCEPT_PAGEFAULT(EXEC)";
|
||||
default:
|
||||
USER_PANIC("EXCEPT_PAGEFAULT has invalid subtype")
|
||||
}
|
||||
case EXCEPT_BREAKPOINT:
|
||||
return "EXCEPT_BREAKPOINT";
|
||||
case EXCEPT_SINGLESTEP:
|
||||
return "EXCEPT_SINGLESTEP";
|
||||
case EXCEPT_OTHER:
|
||||
return "EXCEPT_OTHER";
|
||||
default:
|
||||
USER_PANIC("Got invalid page fault type")
|
||||
}
|
||||
}
|
||||
|
||||
static void pt_exception_handler(enum exception_type type, int subtype,
|
||||
void *addr, arch_registers_state_t *regs)
|
||||
{
|
||||
lvaddr_t ip = registers_get_ip(regs);
|
||||
|
||||
debug_printf("Page Fault: type=%s, addr=%p, ip=%p\n",
|
||||
pt_exception_type_to_string(type, subtype),
|
||||
addr,
|
||||
ip
|
||||
);
|
||||
// debug_print_save_area(regs);
|
||||
// debug_dump(regs);
|
||||
|
||||
// abort on NULL pointer dereference
|
||||
if(addr < (void *) VADDR_LOWEST_NON_NULL) {
|
||||
USER_PANIC("[ERROR] NULL pointer dereference");
|
||||
}
|
||||
|
||||
USER_PANIC("[ERROR] Page fault handling not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function that allocates a slot and
|
||||
* creates a aarch64 page table capability for a certain level
|
||||
@ -330,7 +384,7 @@ errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr
|
||||
errval_t paging_init_params(struct spawn_domain_params *params)
|
||||
{
|
||||
errval_t err;
|
||||
// debug_printf("paging_init\n");
|
||||
debug_printf("paging_init\n");
|
||||
// (M2): Call paging_init_state for ¤t
|
||||
// TODO (M4): initialize self-paging handler
|
||||
// TIP: use thread_set_exception_handler() to setup a page fault handler
|
||||
@ -355,6 +409,12 @@ errval_t paging_init_params(struct spawn_domain_params *params)
|
||||
// pt_print_state(¤t);
|
||||
}
|
||||
|
||||
// TODO rueegges: not sure this is sufficient?
|
||||
err = thread_set_exception_handler(pt_exception_handler, NULL, (void*) pt_static_exception_stack, (void*) pt_static_exception_stack + PT_STATIC_EXCEPTION_STACK_SIZE, NULL, NULL);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_VREGION_PAGEFAULT_HANDLER);
|
||||
}
|
||||
|
||||
set_current_paging_state(¤t);
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
@ -381,7 +441,26 @@ errval_t paging_init_onthread(struct thread *t)
|
||||
{
|
||||
// TODO (M4):
|
||||
// - setup exception handler for thread `t'.
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
errval_t err;
|
||||
|
||||
debug_printf("paging_init_onthread thread id: %lx\n", t->id);
|
||||
|
||||
// TODO rueegges: Is this how we are supposed to get the exception handler stack?
|
||||
size_t stack_size = PT_STATIC_EXCEPTION_STACK_SIZE;
|
||||
struct capref frame;
|
||||
err = frame_alloc(&frame, stack_size, &stack_size);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_FRAME_ALLOC);
|
||||
}
|
||||
|
||||
void *stack_base;
|
||||
paging_map_frame(get_current_paging_state(), &stack_base, stack_size, frame);
|
||||
|
||||
t->exception_handler = pt_exception_handler;
|
||||
t->exception_stack = stack_base;
|
||||
t->exception_stack_top = stack_base + stack_size;
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1110,6 +1110,10 @@ static int bootstrap_thread(struct spawn_domain_params *params)
|
||||
// Until we have self-paging, we cannot use the paging-region based thread
|
||||
// control block slab allocator, so just run main thread directly
|
||||
#ifndef SELF_PAGING_WORKS
|
||||
// TODO rueegges: remove this when SELF_PAGING_WORKS.
|
||||
// this is required to create threads for testing before we have self paging
|
||||
size_t blocksize = sizeof(struct thread) + tls_block_total_len + THREAD_ALIGNMENT;
|
||||
slab_init(&thread_slabs, blocksize, slab_default_refill);
|
||||
// we aren't prepared to run real threads yet
|
||||
main_thread(params);
|
||||
#else
|
||||
|
||||
@ -461,7 +461,7 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
||||
struct paging_state _child_paging_state;
|
||||
struct paging_state *child_paging_state = &_child_paging_state;
|
||||
// 64 * 1024 is enough to catch null pointers and also enough to not conflict with child starting paging_alloc at VADDR_OFFSET
|
||||
err = paging_init_state_foreign(child_paging_state, 64 * 1024, si->vspace_cap_l0_pagetable, get_default_slot_allocator());
|
||||
err = paging_init_state_foreign(child_paging_state, VADDR_LOWEST_NON_NULL, si->vspace_cap_l0_pagetable, get_default_slot_allocator());
|
||||
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_PAGING_INIT);
|
||||
|
||||
// - Load the ELF binary
|
||||
|
||||
@ -26,10 +26,21 @@
|
||||
|
||||
#define HELLO_CMDLINE_READ_LEN 100
|
||||
|
||||
static int null_dereference(void *ignored) {
|
||||
debug_printf("[null_dereference] Oh no! :O\n");
|
||||
// cause a page fault (slight offset from null simulates NULL struct field access)
|
||||
*((volatile char *)(NULL + 7));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
errval_t err;
|
||||
printf("Hello, world!\n");
|
||||
|
||||
// test page fault handling by doing a null dereference on a different thread
|
||||
thread_create(null_dereference, NULL);
|
||||
barrelfish_usleep(10000000);
|
||||
|
||||
printf("argv:\n");
|
||||
for(int i = 0; i < argc; ++i) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user