diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/lock.c | 25 | ||||
| -rw-r--r-- | sys/lock.h | 11 | ||||
| -rw-r--r-- | sys/syscall.c | 1 | ||||
| -rw-r--r-- | sys/syscall.h | 1 | ||||
| -rw-r--r-- | sys/syscall_region.c | 68 |
5 files changed, 106 insertions, 0 deletions
diff --git a/sys/lock.c b/sys/lock.c new file mode 100644 index 0000000..095a08e --- /dev/null +++ b/sys/lock.c @@ -0,0 +1,25 @@ +#include "lock.h" + +extern int _kernel_panic_unlock; + +void +take_mutex(atomic_flag *lock) +{ + if(_kernel_panic_unlock) return; + while(atomic_flag_test_and_set(lock)) { + __builtin_ia32_pause(); + } +} + +int +try_take_mutex(atomic_flag *lock) +{ + if(_kernel_panic_unlock) return 0; + return atomic_flag_test_and_set(lock); +} + +void +release_mutex(atomic_flag *lock) +{ + atomic_flag_clear(lock); +} diff --git a/sys/lock.h b/sys/lock.h new file mode 100644 index 0000000..3592ea1 --- /dev/null +++ b/sys/lock.h @@ -0,0 +1,11 @@ +#ifndef _JOVE_x86_64_LOCK_H +#define _JOVE_x86_64_LOCK_H 1 + +#include <stdatomic.h> + +void take_mutex(atomic_flag *lock); +int try_take_mutex(atomic_flag *lock); + +void release_mutex(atomic_flag *lock); + +#endif diff --git a/sys/syscall.c b/sys/syscall.c index 54d5468..05eeb58 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -37,6 +37,7 @@ static const syscall_handle_t s_syscall_handles[128] = { [JOVE_OBJ_OBJDIR] = _syscall_handle_objdir, [JOVE_OBJ_PAGEDIR] = _syscall_handle_pagedir, [JOVE_OBJ_PROCESSOR] = _syscall_handle_generic, + [JOVE_OBJ_REGION] = _syscall_handle_region, [JOVE_OBJ_SHMEMORY] = _syscall_handle_generic, [JOVE_OBJ_PCB] = _syscall_handle_pcb, [JOVE_OBJ_INT_HANDLE] = _syscall_handle_generic, diff --git a/sys/syscall.h b/sys/syscall.h index 082fe29..6387d79 100644 --- a/sys/syscall.h +++ b/sys/syscall.h @@ -57,6 +57,7 @@ int _syscall_handle_vtt(syscall_context_t *ctx); int _syscall_handle_objdir(syscall_context_t *ctx); int _syscall_handle_untyped(syscall_context_t *ctx); int _syscall_handle_pagedir(syscall_context_t *ctx); +int _syscall_handle_region(syscall_context_t *ctx); int _syscall_handle_pcb(syscall_context_t *ctx); int _syscall_handle_initrd_file(syscall_context_t *ctx); int _syscall_handle_message(syscall_context_t *ctx); diff --git a/sys/syscall_region.c b/sys/syscall_region.c new file mode 100644 index 0000000..959d615 --- /dev/null +++ b/sys/syscall_region.c @@ -0,0 +1,68 @@ +#include "api/error.h" +#include "api/syscall.h" +#include "hal/memory.h" +#include "lib/printf.h" +#include "jove.h" +#include "syscall.h" + +static int +s_syscall_region_alloc(jove_owned_obj_t *region_obj, + jove_owned_obj_t *objdir_obj, + lockstack_t *lockstack, + size_t bytes_left, + void *payload_data) +{ + size_t bytes_needed = sizeof(struct syscall_region_alloc); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); + + struct syscall_region_alloc *payload = payload_data; + bytes_needed += payload->dest_pathlen * sizeof(objpath_part_t); + + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for subject path"); + + jove_perm_obj_t subject = link_try_traverse_objdir( + objdir_obj, lockstack, payload->dest_pathlen, payload->dest_path); + CHECK_OBJEXISTS(subject.obj, "Destination path is bad."); + CHECK_OBJPERM(subject, SYSCALL_PERM_REGION_ALLOC_TGT, "Destination path does not have correct permissions."); + CHECK_OBJTYPE(subject.obj, JOVE_OBJ_NONE, "Destination object is not JOVE_OBJ_NONE"); + + int sysret = 0; + if(payload->alloc_pages == 1) { + sysret = region_alloc(region_obj, subject.obj); + }else{ + sysret = region_alloc_contig(region_obj, subject.obj, payload->alloc_pages); + } + if(sysret < 0) { + klogf("Region alloc failed with reason: %s\n", errstr(-sysret)); + } + return sysret; +} + +int +_syscall_handle_region(syscall_context_t *ctx) +{ + switch(ctx->header->callid) { + case SYSCALL_REGION_ADDRESS: + if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS) + return region_base(ctx->target.obj); + return -EPERM; + + case SYSCALL_REGION_TOTAL_PAGES: + if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS) + return region_pages(ctx->target.obj); + return -EPERM; + + case SYSCALL_REGION_FREE_PAGES: + if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS) + return region_freepages(ctx->target.obj); + return -EPERM; + + case SYSCALL_REGION_ALLOC: + if(ctx->target.permissions & SYSCALL_PERM_REGION_ALLOC) + return s_syscall_region_alloc(ctx->target.obj, ctx->objdir, &ctx->lockstack, ctx->bytes_left, ctx->payload); + return -EPERM; + + default: + return -EBADCALL; + } +} |
