#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; } }