summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-09-17 11:11:20 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-09-17 11:11:20 -0400
commit13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8 (patch)
treea15e55bc70c60d3faa053db3b7b9a17fe75589bc
parenta783cc865f1f261c20f6ef55cb37d4839f519865 (diff)
downloadjove-kernel-13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8.tar.gz
jove-kernel-13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8.tar.bz2
jove-kernel-13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8.zip
make syscall use non-locking mutexes
-rw-r--r--api/error.h17
-rw-r--r--api/init.h21
-rw-r--r--arch/x86_64/hal/idt.h2
-rw-r--r--arch/x86_64/hal/obj.c52
-rw-r--r--arch/x86_64/hal/obj.h4
-rw-r--r--arch/x86_64/hal/process.c2
-rw-r--r--arch/x86_64/hal/process.h2
-rw-r--r--arch/x86_64/lock.c7
-rw-r--r--arch/x86_64/lock.h2
-rw-r--r--arch/x86_64/main.c5
-rw-r--r--arch/x86_64/sys/init.c1
-rw-r--r--hal/obj.h5
-rw-r--r--jove.h14
-rw-r--r--lib/errstr.c24
-rw-r--r--lib/printf.h2
-rw-r--r--sys/syscall.c26
16 files changed, 146 insertions, 40 deletions
diff --git a/api/error.h b/api/error.h
new file mode 100644
index 0000000..229c6c8
--- /dev/null
+++ b/api/error.h
@@ -0,0 +1,17 @@
+#ifndef _JOVE_API_ERROR_H
+#define _JOVE_API_ERROR_H 1
+
+#define EBADOBJ 1
+#define EOOB 2
+#define EBADPATH 3
+#define EBADARG 4
+#define ETOOSMALL 5
+#define ETOOBIG 6
+#define EBADSIZE 7
+#define ENOMAP 8
+#define EHASMAP 9
+#define EALIGN 10
+#define EEXIST 11
+#define EBUSY 12
+
+#endif
diff --git a/api/init.h b/api/init.h
index a7de43f..d23327f 100644
--- a/api/init.h
+++ b/api/init.h
@@ -1,15 +1,18 @@
#ifndef _JOVE_API_INIT_H
#define _JOVE_API_INIT_H 1
-#define ROOTDIR_PROCESSORS_I 0x0
-#define ROOTDIR_PAGEDIR_I 0x01
-#define ROOTDIR_UNTYPED_I 0x02
-#define ROOTDIR_PCB_I 0x03
-#define ROOTDIR_IOPB_I 0x04
-#define ROOTDIR_ACPI_I 0x05
-#define ROOTDIR_INTERRUPTS_I 0x06
-#define ROOTDIR_INITRD_I 0x07
-#define ROOTDIR_MESSAGE_I 0x08
+enum {
+ ROOTDIR_DIR_I = 0,
+ ROOTDIR_PROCESSORS_I,
+ ROOTDIR_PAGEDIR_I,
+ ROOTDIR_UNTYPED_I,
+ ROOTDIR_PCB_I,
+ ROOTDIR_IOPB_I,
+ ROOTDIR_ACPI_I,
+ ROOTDIR_INTERRUPTS_I,
+ ROOTDIR_INITRD_I,
+ ROOTDIR_MESSAGE_I,
+};
#define ROOTDIR_SERIAL_COM_I 0x80
#define ROOTDIR_FRAMEBUFFER_I 0x81
diff --git a/arch/x86_64/hal/idt.h b/arch/x86_64/hal/idt.h
index 2aa759b..19c9e4c 100644
--- a/arch/x86_64/hal/idt.h
+++ b/arch/x86_64/hal/idt.h
@@ -66,7 +66,7 @@ struct int_stackframe
struct int_user_handle
{
uintmax_t pid;
- void *handle;
+ int (*handle)(struct int_stackframe*);
};
extern struct int_user_handle __int_user_handles[IDT_ENTRIES];
diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c
index af0491a..cb0e13d 100644
--- a/arch/x86_64/hal/obj.c
+++ b/arch/x86_64/hal/obj.c
@@ -16,6 +16,18 @@ obj_take(jove_obj_t *obj)
return (jove_owned_obj_t*)obj;
}
+jove_owned_obj_t*
+obj_trytake(jove_obj_t *obj)
+{
+ if((uintptr_t)obj < IDENT_VIRT_BASE) {
+ reterr(EBADOBJ);
+ }
+ if(try_take_mutex(&obj->lock)) {
+ reterr(EBUSY);
+ }
+ return (jove_owned_obj_t*)obj;
+}
+
jove_obj_t*
obj_release(jove_owned_obj_t *obj)
{
@@ -97,16 +109,32 @@ objdir_getlocal(
}
jove_owned_obj_t*
+objdir_trygetlocal(
+ jove_owned_obj_t *objdir_obj,
+ uint16_t entry)
+{
+ if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ reterr(EBADOBJ);
+ }
+ if(entry >= JOVE_OBJDIR_ENTRIES) {
+ reterr(EBADPATH);
+ }
+
+ jove_objdir_t *objtab = obj_deref_linked(objdir_obj);
+ return obj_trytake(&objtab->entries[entry]);
+}
+
+jove_owned_obj_t*
objdir_getobj(
jove_owned_obj_t *objdir_obj,
const uint16_t *path,
size_t path_len)
{
+ errno = 0;
if(path_len == 0) {
return objdir_obj;
}
{
- errno = 0;
jove_owned_obj_t *child_objdir = objdir_getlocal(objdir_obj, path[0]);
if(child_objdir == 0) {
reterr(EBADPATH);
@@ -118,3 +146,25 @@ objdir_getobj(
}
}
+jove_owned_obj_t*
+objdir_trygetobj(
+ jove_owned_obj_t *objdir_obj,
+ const uint16_t *path,
+ size_t path_len)
+{
+ errno = 0;
+ if(path_len == 0) {
+ return objdir_obj;
+ }
+ {
+ jove_owned_obj_t *child_objdir = objdir_trygetlocal(objdir_obj, path[0]);
+ if(child_objdir == 0) {
+ return 0;
+ }
+
+ jove_owned_obj_t *target_obj = objdir_trygetobj(child_objdir, path + 1, path_len - 1);
+ obj_release(child_objdir);
+ return target_obj;
+ }
+}
+
diff --git a/arch/x86_64/hal/obj.h b/arch/x86_64/hal/obj.h
index deea2be..4364348 100644
--- a/arch/x86_64/hal/obj.h
+++ b/arch/x86_64/hal/obj.h
@@ -17,7 +17,7 @@ typedef union jove_obj
struct {
uint8_t type;
atomic_flag lock;
- /*Raw value or pointer to a data-structure located in kernel memory.*/
+ /*Raw value or pointer to a data-structure located in identity memory.*/
uint64_t value : 48;
};
uintmax_t data;
@@ -32,7 +32,7 @@ typedef struct jove_locked_obj
} jove_owned_obj_t;
/*Object directories are always 1 page wide. Since an object inside the directory
- * is a pointer width, on x86_64 that is 512 entries per directory.*/
+ * in this arch is a pointer width, that is 512 entries per directory.*/
#define JOVE_OBJDIR_SIZE 0x1000
#define JOVE_OBJDIR_ENTRIES (JOVE_OBJDIR_SIZE / sizeof(jove_obj_t))
diff --git a/arch/x86_64/hal/process.c b/arch/x86_64/hal/process.c
index 0155919..f30d703 100644
--- a/arch/x86_64/hal/process.c
+++ b/arch/x86_64/hal/process.c
@@ -37,7 +37,7 @@ pcb_pid(pcb_t *pcb)
jove_owned_obj_t*
pcb_rootdir(pcb_t *pcb)
{
- return pcb->rootdir;
+ return obj_take(pcb->rootdir);
}
void
diff --git a/arch/x86_64/hal/process.h b/arch/x86_64/hal/process.h
index c3530bf..f903153 100644
--- a/arch/x86_64/hal/process.h
+++ b/arch/x86_64/hal/process.h
@@ -7,7 +7,7 @@
typedef struct process_control_block
{
pid_t pid;
- jove_owned_obj_t *rootdir;
+ jove_obj_t *rootdir;
jove_owned_obj_t *iopb;
uintptr_t pml4;
diff --git a/arch/x86_64/lock.c b/arch/x86_64/lock.c
index b010ee6..a34cee6 100644
--- a/arch/x86_64/lock.c
+++ b/arch/x86_64/lock.c
@@ -11,6 +11,13 @@ take_mutex(atomic_flag *lock)
}
}
+int
+try_take_mutex(atomic_flag *lock)
+{
+ if(_kernel_panic_unlock) return 1;
+ return atomic_flag_test_and_set(lock);
+}
+
void
release_mutex(atomic_flag *lock)
{
diff --git a/arch/x86_64/lock.h b/arch/x86_64/lock.h
index 609ea39..3592ea1 100644
--- a/arch/x86_64/lock.h
+++ b/arch/x86_64/lock.h
@@ -4,6 +4,8 @@
#include <stdatomic.h>
void take_mutex(atomic_flag *lock);
+int try_take_mutex(atomic_flag *lock);
+
void release_mutex(atomic_flag *lock);
#endif
diff --git a/arch/x86_64/main.c b/arch/x86_64/main.c
index 7266155..a35a465 100644
--- a/arch/x86_64/main.c
+++ b/arch/x86_64/main.c
@@ -1,3 +1,4 @@
+#include "api/init.h"
#include "jove.h"
#include "init.h"
#include "lib/string.h"
@@ -19,9 +20,7 @@
int errno = 0;
PAGEALIGN jove_objdir_t _rootdir;
-
-jove_owned_obj_t s_rootdir_obj;
-void *_rootdir_obj = &s_rootdir_obj;
+void *_rootdir_obj = &_rootdir.entries[ROOTDIR_DIR_I];
static void kernel_process_entry(void);
diff --git a/arch/x86_64/sys/init.c b/arch/x86_64/sys/init.c
index 8823df2..c55eabe 100644
--- a/arch/x86_64/sys/init.c
+++ b/arch/x86_64/sys/init.c
@@ -171,6 +171,7 @@ init_setup(void)
pcb_t *pcb = obj_deref(pcb_obj);
obj_release(pcb_obj);
+ obj_release(_rootdir_obj);
uintptr_t usp = 0x00007FFFFFFFFFF8;
uintptr_t uip = init_ehdr->e_entry;
diff --git a/hal/obj.h b/hal/obj.h
index 151f4eb..68f4bdc 100644
--- a/hal/obj.h
+++ b/hal/obj.h
@@ -16,6 +16,7 @@ typedef struct jove_objdir
/*Locks the mutex of the kernel object provided. Returns the locked version. */
jove_owned_obj_t *obj_take(jove_obj_t *obj);
+jove_owned_obj_t *obj_trytake(jove_obj_t *obj);
/*Unlocks the mutex of the kernel object provided. Returns the unlocked version. */
jove_obj_t *obj_release(jove_owned_obj_t *obj);
@@ -35,6 +36,8 @@ void obj_setvalue(jove_owned_obj_t *obj, uintmax_t value);
* If the passed object is not an objdir, returns NULL and sets errno to EBADOBJ.
* If the passed entry index is out of bounds, returns NULL and sets errno to EOOB.*/
jove_owned_obj_t *objdir_getlocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
+/*Same as objdir_getlocal except does not block if entry obj is taken.*/
+jove_owned_obj_t *objdir_trygetlocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
jove_obj_t objdir_peeklocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
/*Recursively seeks through an object directory for an object following the passed
@@ -45,5 +48,7 @@ jove_obj_t objdir_peeklocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
* returns NULL and sets errno to EBADOBJ.
* If any entry in the path is out of bounds, returns NULL and sets errno to EBADOBJ.*/
jove_owned_obj_t *objdir_getobj(jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len);
+/*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);
#endif
diff --git a/jove.h b/jove.h
index 28e3388..7e84da8 100644
--- a/jove.h
+++ b/jove.h
@@ -14,16 +14,8 @@ extern int errno;
errno = e; \
return 0
-#define EBADOBJ -1
-#define EOOB -2
-#define EBADPATH -3
-#define EBADARG -4
-#define ETOOSMALL -5
-#define ETOOBIG -6
-#define EBADSIZE -7
-#define ENOMAP -8
-#define EHASMAP -9
-#define EALIGN -10
-#define EEXIST -11
+#include "api/error.h"
+
+const char *errstr(int errno);
#endif
diff --git a/lib/errstr.c b/lib/errstr.c
new file mode 100644
index 0000000..6c4425d
--- /dev/null
+++ b/lib/errstr.c
@@ -0,0 +1,24 @@
+#include "jove.h"
+
+const char*
+errstr(int err)
+{
+ static const char *errstrs[] = {
+ [0] = "OKAY",
+ [EBADOBJ] = "BAD OBJECT",
+ [EOOB] = "OUT OF BOUNDS",
+ [EBADPATH] = "BAD PATH",
+ [ETOOSMALL] = "TOO SMALL",
+ [ETOOBIG] = "TOO BIG",
+ [EBADSIZE] = "BAD SIZE",
+ [ENOMAP] = "NO MAP",
+ [EHASMAP] = "HAS MAP",
+ [EALIGN] = "ALIGNMENT ERROR",
+ [EEXIST] = "ALREADY EXISTS",
+ [EBUSY] = "RESOURCE BUSY"
+ };
+ if(err >= sizeof(errstrs) / sizeof(const char*)) {
+ return "UNKNOWN ERROR";
+ }
+ return errstrs[err];
+}
diff --git a/lib/printf.h b/lib/printf.h
index a132b39..bcee770 100644
--- a/lib/printf.h
+++ b/lib/printf.h
@@ -4,6 +4,8 @@
#include <stdarg.h>
#include <stddef.h>
+#define klogf(fmt, ...) kprintf("%s: " fmt, __func__, __VA_ARGS__)
+
int kprintf(const char *fmt, ...);
int kvprintf(const char *fmt, va_list ap);
diff --git a/sys/syscall.c b/sys/syscall.c
index 0351c95..5670bbb 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -34,7 +34,7 @@ _syscall_handle_generic(
void *payload)
{
pcb_t *pcb = obj_deref(pcb_obj);
- kprintf("syscall: Process %i encountered stub syscall on object %P\n", pcb_pid(pcb), header->path, header->pathlen);
+ klogf("Process %i encountered stub syscall on object %P\n", pcb_pid(pcb), header->path, header->pathlen);
return EBADOBJ;
}
@@ -65,16 +65,20 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
jove_owned_obj_t *pcb_obj = process_current();
pcb_t *pcb = obj_deref(pcb_obj);
jove_owned_obj_t *objdir = pcb_rootdir(pcb);
- jove_owned_obj_t *message_obj = objdir_getobj(objdir, message_path, message_pathlen);
+ jove_owned_obj_t *message_obj = objdir_trygetobj(objdir, message_path, message_pathlen);
- int sysret = 0;
- if(message_obj == 0) {
- sysret = errno;
+ if(message_obj == NULL) {
+ klogf("Process %i tried to call syscall with bad message %P : %s\n",
+ pcb_pid(pcb), message_path, message_pathlen, errstr(errno));
goto release_premsg;
+ return errno;
}
+ int sysret = 0;
+
if(obj_gettype_linked(message_obj) != JOVE_OBJ_MESSAGE) {
- kprintf("syscall: Process %i tried to call syscall with invalid object: %P\n", pcb_pid(pcb), message_path, message_pathlen);
+ klogf("Process %i tried to call syscall with invalid object %P\n",
+ pcb_pid(pcb), message_path, message_pathlen);
sysret = EBADOBJ;
goto release_return;
}
@@ -86,15 +90,15 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
size_t bytes_needed = sizeof(struct syscall_header) + header->pathlen * 2;
if(bytes_needed > messagelen) {
//Target path exceeds message length.
- kprintf("syscall: Process %i tried to call syscall with target path too big for message.\n", pcb_pid(pcb));
+ klogf("Process %i tried to call syscall with target path too big for message.\n", pcb_pid(pcb));
sysret = ETOOSMALL;
goto release_return;
}
- jove_owned_obj_t *target = objdir_getobj(objdir, header->path, header->pathlen);
+ jove_owned_obj_t *target = objdir_trygetobj(objdir, header->path, header->pathlen);
if(target == 0) {
//Could not find payload target in pcb rootdir.
- kprintf("syscall: Process %i tried to call syscall with bad target path %P\n",
- pcb_pid(pcb), header->path, header->pathlen);
+ klogf("Process %i tried to call syscall with bad target path %P : %s\n",
+ pcb_pid(pcb), header->path, header->pathlen, errstr(errno));
sysret = errno;
goto release_return;
}
@@ -108,7 +112,7 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
}else{
syscall_handle_t call_handle = s_syscall_handles[obj_gettype(target)];
if(call_handle == NULL) {
- kprintf("syscall: Process %i tried to call syscall on object %P which doesn't support syscalls!\n",
+ klogf("Process %i tried to call syscall on object %P which doesn't support syscalls!\n",
pcb_pid(pcb), header->path, header->pathlen);
sysret = EBADOBJ;
}else