summaryrefslogtreecommitdiffstats
path: root/sys/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/syscall.c')
-rw-r--r--sys/syscall.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/sys/syscall.c b/sys/syscall.c
index 05eeb58..0c40418 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -87,6 +87,7 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
ctx.pcb = process_current();
pcb_t *pcb = obj_deref(ctx.pcb);
+
ctx.objdir = lockstack_push(&ctx.lockstack, obj_take(pcb_getrootdir(pcb)));
ctx.message = link_try_traverse_objdir(
@@ -113,8 +114,8 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
goto release_return;
}
- uintptr_t message_vptr = message_unmap(ctx.message.obj,
- (jove_owned_obj_t*)pcb_getpagedir(pcb));
+ jove_owned_obj_t *pagedir = lockstack_push(&ctx.lockstack, pcb_getpagedir(ctx.objdir));
+ uintptr_t message_vptr = message_unmap(ctx.message.obj, pagedir);
size_t messagelen = 0x1000;
void *messagedata = (void*)message_getdata(ctx.message.obj);
@@ -135,27 +136,31 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
ctx.target = link_try_traverse_objdir(
ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path);
- if(ctx.target.obj != 0) {
- sysret = _syscall_handle_switch(&ctx);
- }else{
- //Check if we're trying to reference the PCB. If we are, we should set it as the target
- //regardless of lock.
- if(ctx.header->pathlen == 1 &&
- objdir_peeklocal(ctx.objdir, ctx.header->path[0]).data == ctx.pcb->locked.data)
- {
- ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb };
- sysret = _syscall_handle_switch(&ctx);
-
+ if(ctx.target.obj == 0) {
+ //Check if we're trying to reference objects we've already locked in this function.
+ //If we are, we should set it as the target regardless of lock,
+ //since we're the ones with the lock already.
+ if(ctx.header->pathlen == 1) {
+ if(ctx.header->path[0] == PCB_ROOTDIR_SELF_I)
+ ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb };
+ else if(ctx.header->path[0] == PCB_ROOTDIR_PAGEDIR_I)
+ ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = pagedir };
+ else
+ goto fail_target_busy;
}else{
+fail_target_busy:
//Could not find payload target in pcb rootdir.
klogf("Process %i tried to call syscall with bad target path %P : %s\n",
pcb_getpid(pcb), header->path, header->pathlen, errstr(errno));
sysret = -errno;
+ goto remap_return;
}
}
+ sysret = _syscall_handle_switch(&ctx);
+
remap_return:
- message_remap(ctx.message.obj, (jove_owned_obj_t*)pcb_getpagedir(pcb), message_vptr);
+ message_remap(ctx.message.obj, pagedir, message_vptr);
release_return:
lockstack_popall(&ctx.lockstack);