summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-10-09 16:50:13 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-10-09 16:50:13 -0400
commit5ab3b18865eb813d433a6c0687dfa1f62a1b6055 (patch)
tree8272e561d7d7a83780fc05e16722f29f58b18a28 /sys
parentcc23ea5a4b38807e79aceb23e6f43e965926618f (diff)
downloadjove-kernel-5ab3b18865eb813d433a6c0687dfa1f62a1b6055.tar.gz
jove-kernel-5ab3b18865eb813d433a6c0687dfa1f62a1b6055.tar.bz2
jove-kernel-5ab3b18865eb813d433a6c0687dfa1f62a1b6055.zip
add ipc send/recv mechanism for kernel objects.
Diffstat (limited to 'sys')
-rw-r--r--sys/objdir.c7
-rw-r--r--sys/objdir.h1
-rw-r--r--sys/syscall_pcb.c74
3 files changed, 82 insertions, 0 deletions
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"
@@ -19,6 +21,66 @@ s_syscall_pcb_yield(jove_owned_obj_t *pcb_obj,
}
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)
{
switch(ctx->header->callid) {
@@ -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;
}