diff options
Diffstat (limited to 'sys/syscall_region.c')
| -rw-r--r-- | sys/syscall_region.c | 68 |
1 files changed, 68 insertions, 0 deletions
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; + } +} |
