diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-17 11:11:20 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-17 11:11:20 -0400 |
| commit | 13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8 (patch) | |
| tree | a15e55bc70c60d3faa053db3b7b9a17fe75589bc | |
| parent | a783cc865f1f261c20f6ef55cb37d4839f519865 (diff) | |
| download | jove-kernel-13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8.tar.gz jove-kernel-13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8.tar.bz2 jove-kernel-13adbc58eb9f5eb5d6f0e4454bd005e9adbb47c8.zip | |
make syscall use non-locking mutexes
| -rw-r--r-- | api/error.h | 17 | ||||
| -rw-r--r-- | api/init.h | 21 | ||||
| -rw-r--r-- | arch/x86_64/hal/idt.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/hal/obj.c | 52 | ||||
| -rw-r--r-- | arch/x86_64/hal/obj.h | 4 | ||||
| -rw-r--r-- | arch/x86_64/hal/process.c | 2 | ||||
| -rw-r--r-- | arch/x86_64/hal/process.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/lock.c | 7 | ||||
| -rw-r--r-- | arch/x86_64/lock.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/main.c | 5 | ||||
| -rw-r--r-- | arch/x86_64/sys/init.c | 1 | ||||
| -rw-r--r-- | hal/obj.h | 5 | ||||
| -rw-r--r-- | jove.h | 14 | ||||
| -rw-r--r-- | lib/errstr.c | 24 | ||||
| -rw-r--r-- | lib/printf.h | 2 | ||||
| -rw-r--r-- | sys/syscall.c | 26 |
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 @@ -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; @@ -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 @@ -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 |
