From 5ab3b18865eb813d433a6c0687dfa1f62a1b6055 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Fri, 9 Oct 2026 16:50:13 -0400 Subject: add ipc send/recv mechanism for kernel objects. --- sys/objdir.c | 7 ++++++ sys/objdir.h | 1 + sys/syscall_pcb.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) (limited to 'sys') diff --git a/sys/objdir.c b/sys/objdir.c index c448e85..eab935f 100644 --- a/sys/objdir.c +++ b/sys/objdir.c @@ -112,3 +112,10 @@ objdir_trygetobj( } } +void +objdir_swapobj(jove_owned_obj_t *a, jove_owned_obj_t *b) +{ + jove_owned_obj_t buffer_obj = *a; + *a = *b; + *b = buffer_obj; +} diff --git a/sys/objdir.h b/sys/objdir.h index 54e9618..e2ae7ef 100644 --- a/sys/objdir.h +++ b/sys/objdir.h @@ -23,5 +23,6 @@ jove_owned_obj_t *objdir_getobj(jove_owned_obj_t *objdir_obj, const uint16_t *pa /*Same as objdir_getobj but does not block if child objects are locked.*/ jove_owned_obj_t *objdir_trygetobj(jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len); +void objdir_swapobj(jove_owned_obj_t *a, jove_owned_obj_t *b); #endif diff --git a/sys/syscall_pcb.c b/sys/syscall_pcb.c index a37e4bb..4fe557b 100644 --- a/sys/syscall_pcb.c +++ b/sys/syscall_pcb.c @@ -1,4 +1,6 @@ #include "api/error.h" +#include "api/obj.h" +#include "api/syscall.h" #include "jove.h" #include "lib/printf.h" #include "proc/process.h" @@ -18,6 +20,66 @@ s_syscall_pcb_yield(jove_owned_obj_t *pcb_obj, return scheduler_yield(subject_pid); } +int +s_syscall_pcb_send(jove_owned_obj_t *pcb_obj, + lockstack_t *lockstack, + jove_owned_obj_t *objdir_obj, + size_t bytes_left, + void *payload_data) +{ + size_t bytes_needed = sizeof(struct syscall_pcb_send); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); + + struct syscall_pcb_send *payload = payload_data; + bytes_needed += payload->send_path_length; + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for subject path"); + + jove_perm_obj_t subject_objdir = link_try_traverse_objdir( + objdir_obj, lockstack, payload->send_path_length - 1, payload->send_path); + if(errno) { + klogf("Unable to get subject %P objdir : %s\n", + payload->send_path, payload->send_path_length, errstr(errno)); + return -errno; + } + CHECK_OBJPERM(subject_objdir, SYSCALL_PERM_PCB_SEND_OBJDIR, "Subject objdir does not permit send"); + + jove_owned_obj_t *subject = objdir_trygetlocal(subject_objdir.obj, + payload->send_path[payload->send_path_length-1]); + if(subject == 0) { + klogf("Unable to get subject %P object : %s\n", + payload->send_path, payload->send_path_length, errstr(errno)); + return -errno; + } + + return pcb_send(obj_deref(pcb_obj), payload->send_target, subject, payload->send_timeout); +} + +int +s_syscall_pcb_recv(jove_owned_obj_t *pcb_obj, + lockstack_t *lockstack, + jove_owned_obj_t *objdir_obj, + size_t bytes_left, + void *payload_data) +{ + size_t bytes_needed = sizeof(struct syscall_pcb_recv); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); + + struct syscall_pcb_recv *payload = payload_data; + bytes_needed += payload->recv_path_length * sizeof(objpath_part_t); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for destination path"); + + jove_perm_obj_t destination = link_try_traverse_objdir( + objdir_obj, lockstack, payload->recv_path_length, payload->recv_path); + if(errno) { + klogf("Unable to get destination %P : %s\n", + payload->recv_path, payload->recv_path_length, errstr(errno)); + return -errno; + } + CHECK_OBJPERM(destination, SYSCALL_PERM_PCB_RECV_DST, "Destination object does not permit recv."); + + return pcb_recv(obj_deref(pcb_obj), payload->recv_target, destination.obj, payload->recv_timeout); +} + int _syscall_handle_pcb(syscall_context_t *ctx) { @@ -27,6 +89,18 @@ _syscall_handle_pcb(syscall_context_t *ctx) return s_syscall_pcb_yield(ctx->target.obj, ctx->bytes_left, ctx->payload); return -EPERM; + case SYSCALL_PCB_SEND: + if(ctx->target.permissions & SYSCALL_PERM_PCB_SEND) + return s_syscall_pcb_send( + ctx->target.obj, &ctx->lockstack, ctx->objdir, ctx->bytes_left, ctx->payload); + return -EPERM; + + case SYSCALL_PCB_RECV: + if(ctx->target.permissions & SYSCALL_PERM_PCB_RECV) + return s_syscall_pcb_recv( + ctx->target.obj, &ctx->lockstack, ctx->objdir, ctx->bytes_left, ctx->payload); + return -EPERM; + default: return -EBADCALL; } -- cgit v1.2.3