summaryrefslogtreecommitdiffstats
path: root/usr
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2024-03-19 13:03:52 -0400
committerJon Santmyer <jon@jonsantmyer.com>2024-03-19 13:03:52 -0400
commitf004c1ade8d617a82cea2fe249434cccb47a2358 (patch)
tree34571e76039cf2ee2fee93c3f1bdb1bc6d2de5f6 /usr
parentdd5d9e1d48396cbc226ff14fe557a55613c91fcb (diff)
downloadjove-kernel-f004c1ade8d617a82cea2fe249434cccb47a2358.tar.gz
jove-kernel-f004c1ade8d617a82cea2fe249434cccb47a2358.tar.bz2
jove-kernel-f004c1ade8d617a82cea2fe249434cccb47a2358.zip
rename abi to sys. better memory allocation
Diffstat (limited to 'usr')
-rw-r--r--usr/syscall.c86
-rw-r--r--usr/syscall.h2
-rw-r--r--usr/tasking.c7
-rw-r--r--usr/tasking.h28
-rw-r--r--usr/umode.c10
5 files changed, 126 insertions, 7 deletions
diff --git a/usr/syscall.c b/usr/syscall.c
index 8680845..fbc5fe7 100644
--- a/usr/syscall.c
+++ b/usr/syscall.c
@@ -1,11 +1,28 @@
#include "syscall.h"
-#include "tsk/tasking.h"
+#include "sys/errno.h"
+#include "sys/permission.h"
+#include "usr/tasking.h"
#include "mem/memory.h"
#include "io/log.h"
+#define ENSURE_ADDR(ptr) \
+ if(!mem_check_ptr(ptr)) { klogf("User passed bad address %#016X\n", ptr); return -EFAULT; }
+
+#define ENSURE_PERM(p) \
+ if(!(task_current->perm & p)) return -ENOPERM
+
+#define PD_FOR_LINEAR_ADDRESS(addr) current_page_directory; \
+ if(addr.tid == -1) addr.tid = task_current->id; \
+ if(addr.tid != task_current->id) { \
+ ENSURE_PERM(PERM_MEM_VIRT_PD); \
+ struct Task *task = task_get(addr.tid); \
+ if(task == NULL) return -EFAULT; \
+ pd = task->pd; \
+ }
+
int _syscall_handler_log(struct syscall_log *req)
{
- if(!mem_check_ptr(req->message)) return -1;
+ ENSURE_ADDR(req->message);
klogf("%s", req->message);
return 0;
}
@@ -15,14 +32,73 @@ intmax_t _syscall_handler_tid(syscall_t *req)
return task_current->id;
}
+int _syscall_handler_mem_phys_resv(struct syscall_mem_phys_range_op *req)
+{
+ ENSURE_PERM(PERM_MEM_PHYS_RESV);
+ mem_phys_reserve(req->base, req->limit);
+ return 0;
+}
+
+int _syscall_handler_mem_phys_free(struct syscall_mem_phys_range_op *req)
+{
+ ENSURE_PERM(PERM_MEM_PHYS_FREE);
+ mem_phys_release(req->base, req->limit);
+ return 0;
+}
+
+int _syscall_handler_mem_phys_alloc(struct syscall_mem_phys_alloc *req)
+{
+ ENSURE_ADDR(req->result);
+ ENSURE_PERM(PERM_MEM_PHYS_ALLOC);
+ *req->result = mem_phys_alloc(req->npages);
+ return 0;
+}
+
+int _syscall_handler_mem_virt_mapping(struct syscall_mem_virt_mapping *req)
+{
+ ENSURE_ADDR(req->result);
+ ENSURE_PERM(PERM_MEM_VIRT_MAP);
+ page_directory_t *pd = PD_FOR_LINEAR_ADDRESS(req->addr);
+ *req->result = mem_get_mapping_as(pd, req->addr.addr);
+ return 0;
+}
+
+int _syscall_handler_mem_virt_map(struct syscall_mem_virt_map *req)
+{
+ ENSURE_PERM(PERM_MEM_VIRT_MAP);
+ page_directory_t *pd = PD_FOR_LINEAR_ADDRESS(req->addr);
+ mem_set_mapping_as(pd, req->map, req->addr.addr);
+ return 0;
+}
+
+int _syscall_handler_mem_virt_alloc(struct syscall_mem_virt_alloc *req)
+{
+ ENSURE_PERM(PERM_MEM_VIRT_MAP);
+ ENSURE_PERM(PERM_MEM_PHYS_ALLOC);
+ page_directory_t *pd = PD_FOR_LINEAR_ADDRESS(req->from);
+ mem_ensure_range_as(pd, req->from.addr, req->to, req->flg);
+ return 0;
+}
+
void *_syscall_handlers[SYSCALL_COUNT] = {
- _syscall_handler_log
+ _syscall_handler_log,
+ _syscall_handler_tid,
+
+ _syscall_handler_mem_phys_resv,
+ _syscall_handler_mem_phys_free,
+ _syscall_handler_mem_phys_alloc,
+
+ _syscall_handler_mem_virt_mapping,
+ _syscall_handler_mem_virt_map,
+ _syscall_handler_mem_virt_alloc,
};
int
syscall_handler(syscall_t *req)
{
- if(!mem_check_ptr(req)) return -1;
- if(req->id >= SYSCALL_COUNT) return -1;
+ ENSURE_ADDR(req);
+ if(req->id >= SYSCALL_COUNT) return -ENOSYS;
+
+ ENSURE_ADDR(_syscall_handlers[req->id]);
return ((syscall_handler_t)(_syscall_handlers[req->id]))(req);
}
diff --git a/usr/syscall.h b/usr/syscall.h
index fe7843c..5cc82b8 100644
--- a/usr/syscall.h
+++ b/usr/syscall.h
@@ -1,7 +1,7 @@
#ifndef JOVE_USER_SYSCALL_H
#define JOVE_USER_SYSCALL_H 1
-#include "abi/syscall.h"
+#include "sys/syscall.h"
typedef int (*syscall_handler_t)(syscall_t*);
diff --git a/usr/tasking.c b/usr/tasking.c
new file mode 100644
index 0000000..cb4df25
--- /dev/null
+++ b/usr/tasking.c
@@ -0,0 +1,7 @@
+#include "tasking.h"
+
+void
+task_perm_release(struct Task *task, size_t mask)
+{
+ task->perm &= ~mask;
+}
diff --git a/usr/tasking.h b/usr/tasking.h
new file mode 100644
index 0000000..4b11999
--- /dev/null
+++ b/usr/tasking.h
@@ -0,0 +1,28 @@
+#ifndef JOVE_TASKING_H
+#define JOVE_TASKING_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+#include "sys/types.h"
+#include "mem/memory.h"
+
+struct Task
+{
+ struct Task *next;
+ tid_t id;
+ uintptr_t kbp;
+ size_t perm;
+
+ page_directory_t *pd;
+};
+
+extern struct Task *task_current;
+
+void tasking_setup(void);
+
+struct Task *task_new(struct Task *parent);
+struct Task *task_get(tid_t id);
+
+void task_perm_release(struct Task *task, size_t mask);
+
+#endif
diff --git a/usr/umode.c b/usr/umode.c
index 4ef5306..1105d9e 100644
--- a/usr/umode.c
+++ b/usr/umode.c
@@ -24,7 +24,15 @@ umode_setup(void)
kpanic("Init file %s is incorrectly formatted (want ELF64)\n", init_path);
void *user_stack = (void*)(0x00007FFFFFFFFFFF);
- mem_ensure_range((uintptr_t)user_stack & ~0xFFF, (uintptr_t)user_stack, true, true);
+ mem_ensure_range(
+ (uintptr_t)user_stack & ~0xFFF,
+ (uintptr_t)user_stack,
+ (page_flags_t) {
+ .present = true,
+ .writeable = true,
+ .useraccess = true,
+ .executable = false
+ });
klogf("User entry point %#016X\n", entry_point);
umode_enter(entry_point, user_stack);