From f004c1ade8d617a82cea2fe249434cccb47a2358 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Tue, 19 Mar 2024 13:03:52 -0400 Subject: rename abi to sys. better memory allocation --- usr/syscall.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- usr/syscall.h | 2 +- usr/tasking.c | 7 +++++ usr/tasking.h | 28 +++++++++++++++++++ usr/umode.c | 10 ++++++- 5 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 usr/tasking.c create mode 100644 usr/tasking.h (limited to 'usr') diff --git a/usr/syscall.c b/usr/syscall.c index 8680845..fbc5fe7 100644 --- a/usr/syscall.c +++ b/usr/syscall.c @@ -1,11 +1,28 @@ #include "syscall.h" -#include "tsk/tasking.h" +#include "sys/errno.h" +#include "sys/permission.h" +#include "usr/tasking.h" #include "mem/memory.h" #include "io/log.h" +#define ENSURE_ADDR(ptr) \ + if(!mem_check_ptr(ptr)) { klogf("User passed bad address %#016X\n", ptr); return -EFAULT; } + +#define ENSURE_PERM(p) \ + if(!(task_current->perm & p)) return -ENOPERM + +#define PD_FOR_LINEAR_ADDRESS(addr) current_page_directory; \ + if(addr.tid == -1) addr.tid = task_current->id; \ + if(addr.tid != task_current->id) { \ + ENSURE_PERM(PERM_MEM_VIRT_PD); \ + struct Task *task = task_get(addr.tid); \ + if(task == NULL) return -EFAULT; \ + pd = task->pd; \ + } + int _syscall_handler_log(struct syscall_log *req) { - if(!mem_check_ptr(req->message)) return -1; + ENSURE_ADDR(req->message); klogf("%s", req->message); return 0; } @@ -15,14 +32,73 @@ intmax_t _syscall_handler_tid(syscall_t *req) return task_current->id; } +int _syscall_handler_mem_phys_resv(struct syscall_mem_phys_range_op *req) +{ + ENSURE_PERM(PERM_MEM_PHYS_RESV); + mem_phys_reserve(req->base, req->limit); + return 0; +} + +int _syscall_handler_mem_phys_free(struct syscall_mem_phys_range_op *req) +{ + ENSURE_PERM(PERM_MEM_PHYS_FREE); + mem_phys_release(req->base, req->limit); + return 0; +} + +int _syscall_handler_mem_phys_alloc(struct syscall_mem_phys_alloc *req) +{ + ENSURE_ADDR(req->result); + ENSURE_PERM(PERM_MEM_PHYS_ALLOC); + *req->result = mem_phys_alloc(req->npages); + return 0; +} + +int _syscall_handler_mem_virt_mapping(struct syscall_mem_virt_mapping *req) +{ + ENSURE_ADDR(req->result); + ENSURE_PERM(PERM_MEM_VIRT_MAP); + page_directory_t *pd = PD_FOR_LINEAR_ADDRESS(req->addr); + *req->result = mem_get_mapping_as(pd, req->addr.addr); + return 0; +} + +int _syscall_handler_mem_virt_map(struct syscall_mem_virt_map *req) +{ + ENSURE_PERM(PERM_MEM_VIRT_MAP); + page_directory_t *pd = PD_FOR_LINEAR_ADDRESS(req->addr); + mem_set_mapping_as(pd, req->map, req->addr.addr); + return 0; +} + +int _syscall_handler_mem_virt_alloc(struct syscall_mem_virt_alloc *req) +{ + ENSURE_PERM(PERM_MEM_VIRT_MAP); + ENSURE_PERM(PERM_MEM_PHYS_ALLOC); + page_directory_t *pd = PD_FOR_LINEAR_ADDRESS(req->from); + mem_ensure_range_as(pd, req->from.addr, req->to, req->flg); + return 0; +} + void *_syscall_handlers[SYSCALL_COUNT] = { - _syscall_handler_log + _syscall_handler_log, + _syscall_handler_tid, + + _syscall_handler_mem_phys_resv, + _syscall_handler_mem_phys_free, + _syscall_handler_mem_phys_alloc, + + _syscall_handler_mem_virt_mapping, + _syscall_handler_mem_virt_map, + _syscall_handler_mem_virt_alloc, }; int syscall_handler(syscall_t *req) { - if(!mem_check_ptr(req)) return -1; - if(req->id >= SYSCALL_COUNT) return -1; + ENSURE_ADDR(req); + if(req->id >= SYSCALL_COUNT) return -ENOSYS; + + ENSURE_ADDR(_syscall_handlers[req->id]); return ((syscall_handler_t)(_syscall_handlers[req->id]))(req); } diff --git a/usr/syscall.h b/usr/syscall.h index fe7843c..5cc82b8 100644 --- a/usr/syscall.h +++ b/usr/syscall.h @@ -1,7 +1,7 @@ #ifndef JOVE_USER_SYSCALL_H #define JOVE_USER_SYSCALL_H 1 -#include "abi/syscall.h" +#include "sys/syscall.h" typedef int (*syscall_handler_t)(syscall_t*); diff --git a/usr/tasking.c b/usr/tasking.c new file mode 100644 index 0000000..cb4df25 --- /dev/null +++ b/usr/tasking.c @@ -0,0 +1,7 @@ +#include "tasking.h" + +void +task_perm_release(struct Task *task, size_t mask) +{ + task->perm &= ~mask; +} diff --git a/usr/tasking.h b/usr/tasking.h new file mode 100644 index 0000000..4b11999 --- /dev/null +++ b/usr/tasking.h @@ -0,0 +1,28 @@ +#ifndef JOVE_TASKING_H +#define JOVE_TASKING_H 1 + +#include +#include +#include "sys/types.h" +#include "mem/memory.h" + +struct Task +{ + struct Task *next; + tid_t id; + uintptr_t kbp; + size_t perm; + + page_directory_t *pd; +}; + +extern struct Task *task_current; + +void tasking_setup(void); + +struct Task *task_new(struct Task *parent); +struct Task *task_get(tid_t id); + +void task_perm_release(struct Task *task, size_t mask); + +#endif diff --git a/usr/umode.c b/usr/umode.c index 4ef5306..1105d9e 100644 --- a/usr/umode.c +++ b/usr/umode.c @@ -24,7 +24,15 @@ umode_setup(void) kpanic("Init file %s is incorrectly formatted (want ELF64)\n", init_path); void *user_stack = (void*)(0x00007FFFFFFFFFFF); - mem_ensure_range((uintptr_t)user_stack & ~0xFFF, (uintptr_t)user_stack, true, true); + mem_ensure_range( + (uintptr_t)user_stack & ~0xFFF, + (uintptr_t)user_stack, + (page_flags_t) { + .present = true, + .writeable = true, + .useraccess = true, + .executable = false + }); klogf("User entry point %#016X\n", entry_point); umode_enter(entry_point, user_stack); -- cgit v1.2.1