summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/lock.c25
-rw-r--r--sys/lock.h11
-rw-r--r--sys/syscall.c1
-rw-r--r--sys/syscall.h1
-rw-r--r--sys/syscall_region.c68
5 files changed, 106 insertions, 0 deletions
diff --git a/sys/lock.c b/sys/lock.c
new file mode 100644
index 0000000..095a08e
--- /dev/null
+++ b/sys/lock.c
@@ -0,0 +1,25 @@
+#include "lock.h"
+
+extern int _kernel_panic_unlock;
+
+void
+take_mutex(atomic_flag *lock)
+{
+ if(_kernel_panic_unlock) return;
+ while(atomic_flag_test_and_set(lock)) {
+ __builtin_ia32_pause();
+ }
+}
+
+int
+try_take_mutex(atomic_flag *lock)
+{
+ if(_kernel_panic_unlock) return 0;
+ return atomic_flag_test_and_set(lock);
+}
+
+void
+release_mutex(atomic_flag *lock)
+{
+ atomic_flag_clear(lock);
+}
diff --git a/sys/lock.h b/sys/lock.h
new file mode 100644
index 0000000..3592ea1
--- /dev/null
+++ b/sys/lock.h
@@ -0,0 +1,11 @@
+#ifndef _JOVE_x86_64_LOCK_H
+#define _JOVE_x86_64_LOCK_H 1
+
+#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/sys/syscall.c b/sys/syscall.c
index 54d5468..05eeb58 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -37,6 +37,7 @@ static const syscall_handle_t s_syscall_handles[128] = {
[JOVE_OBJ_OBJDIR] = _syscall_handle_objdir,
[JOVE_OBJ_PAGEDIR] = _syscall_handle_pagedir,
[JOVE_OBJ_PROCESSOR] = _syscall_handle_generic,
+ [JOVE_OBJ_REGION] = _syscall_handle_region,
[JOVE_OBJ_SHMEMORY] = _syscall_handle_generic,
[JOVE_OBJ_PCB] = _syscall_handle_pcb,
[JOVE_OBJ_INT_HANDLE] = _syscall_handle_generic,
diff --git a/sys/syscall.h b/sys/syscall.h
index 082fe29..6387d79 100644
--- a/sys/syscall.h
+++ b/sys/syscall.h
@@ -57,6 +57,7 @@ int _syscall_handle_vtt(syscall_context_t *ctx);
int _syscall_handle_objdir(syscall_context_t *ctx);
int _syscall_handle_untyped(syscall_context_t *ctx);
int _syscall_handle_pagedir(syscall_context_t *ctx);
+int _syscall_handle_region(syscall_context_t *ctx);
int _syscall_handle_pcb(syscall_context_t *ctx);
int _syscall_handle_initrd_file(syscall_context_t *ctx);
int _syscall_handle_message(syscall_context_t *ctx);
diff --git a/sys/syscall_region.c b/sys/syscall_region.c
new file mode 100644
index 0000000..959d615
--- /dev/null
+++ b/sys/syscall_region.c
@@ -0,0 +1,68 @@
+#include "api/error.h"
+#include "api/syscall.h"
+#include "hal/memory.h"
+#include "lib/printf.h"
+#include "jove.h"
+#include "syscall.h"
+
+static int
+s_syscall_region_alloc(jove_owned_obj_t *region_obj,
+ jove_owned_obj_t *objdir_obj,
+ lockstack_t *lockstack,
+ size_t bytes_left,
+ void *payload_data)
+{
+ size_t bytes_needed = sizeof(struct syscall_region_alloc);
+ CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload");
+
+ struct syscall_region_alloc *payload = payload_data;
+ bytes_needed += payload->dest_pathlen * sizeof(objpath_part_t);
+
+ CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for subject path");
+
+ jove_perm_obj_t subject = link_try_traverse_objdir(
+ objdir_obj, lockstack, payload->dest_pathlen, payload->dest_path);
+ CHECK_OBJEXISTS(subject.obj, "Destination path is bad.");
+ CHECK_OBJPERM(subject, SYSCALL_PERM_REGION_ALLOC_TGT, "Destination path does not have correct permissions.");
+ CHECK_OBJTYPE(subject.obj, JOVE_OBJ_NONE, "Destination object is not JOVE_OBJ_NONE");
+
+ int sysret = 0;
+ if(payload->alloc_pages == 1) {
+ sysret = region_alloc(region_obj, subject.obj);
+ }else{
+ sysret = region_alloc_contig(region_obj, subject.obj, payload->alloc_pages);
+ }
+ if(sysret < 0) {
+ klogf("Region alloc failed with reason: %s\n", errstr(-sysret));
+ }
+ return sysret;
+}
+
+int
+_syscall_handle_region(syscall_context_t *ctx)
+{
+ switch(ctx->header->callid) {
+ case SYSCALL_REGION_ADDRESS:
+ if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS)
+ return region_base(ctx->target.obj);
+ return -EPERM;
+
+ case SYSCALL_REGION_TOTAL_PAGES:
+ if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS)
+ return region_pages(ctx->target.obj);
+ return -EPERM;
+
+ case SYSCALL_REGION_FREE_PAGES:
+ if(ctx->target.permissions & SYSCALL_PERM_REGION_GETTERS)
+ return region_freepages(ctx->target.obj);
+ return -EPERM;
+
+ case SYSCALL_REGION_ALLOC:
+ if(ctx->target.permissions & SYSCALL_PERM_REGION_ALLOC)
+ return s_syscall_region_alloc(ctx->target.obj, ctx->objdir, &ctx->lockstack, ctx->bytes_left, ctx->payload);
+ return -EPERM;
+
+ default:
+ return -EBADCALL;
+ }
+}