Added simple exception handler that prints stuff

This commit is contained in:
Sparchatus 2022-04-04 13:05:32 +00:00
parent ec591bbb54
commit 5f9ce34445
5 changed files with 100 additions and 5 deletions

View File

@ -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

View File

@ -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 &current
// 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(&current);
}
// 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(&current);
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;
}

View File

@ -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

View File

@ -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

View File

@ -26,11 +26,22 @@
#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) {
printf(" %d -> %s\n", i, argv[i]);