summaryrefslogtreecommitdiffstats
path: root/sys/syscall_pagedir.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/syscall_pagedir.c')
-rw-r--r--sys/syscall_pagedir.c81
1 files changed, 77 insertions, 4 deletions
diff --git a/sys/syscall_pagedir.c b/sys/syscall_pagedir.c
index 144a02b..f80da76 100644
--- a/sys/syscall_pagedir.c
+++ b/sys/syscall_pagedir.c
@@ -1,3 +1,4 @@
+#include "api/syscall.h"
#include "hal/memory.h"
#include "jove.h"
#include "lib/printf.h"
@@ -26,10 +27,10 @@ s_syscall_pagedir_map(
"Message too small for untyped path.");
errno = 0;
- jove_owned_obj_t *untyped_obj = objdir_getobj(objdir,
+ jove_owned_obj_t *untyped_obj = objdir_trygetobj(objdir,
payload->untyped_path, payload->untyped_pathlen);
if(errno) {
- kprintf("%s: Untyped path does not point to a valid object.\n", __func__);
+ kprintf("%s: Untyped obj failed for the reason: %s\n", __func__, errstr(errno));
return errno;
}
@@ -53,6 +54,42 @@ s_syscall_pagedir_map(
}
static int
+s_syscall_pagedir_unmap(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data,
+ jove_owned_obj_t **none_ret)
+{
+ size_t bytes_needed = sizeof(struct syscall_pagedir_unmap);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes,
+ "Message too small for payload");
+
+ struct syscall_pagedir_unmap *payload = payload_data;
+ if(payload->virtual_address > 0xFFFF800000000000ULL) {
+ kprintf("%s: Virtual address is above user limit.\n", __func__);
+ return EBADARG;
+ }
+
+ bytes_needed += payload->none_pathlen * 2;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes,
+ "Message too small for none path");
+
+ jove_owned_obj_t *none_obj = objdir_trygetobj(objdir,
+ payload->none_path, payload->none_pathlen);
+ if(errno) {
+ kprintf("%s: None obj retrieval failed for the reason: %s\n",
+ __func__, errstr(errno));
+ return errno;
+ }
+
+ CHECK_OBJTYPE(none_obj, JOVE_OBJ_NONE,
+ "None path does not point to none object.");
+ *none_ret = none_obj;
+ return 0;
+}
+
+static int
s_syscall_pagedir_map_frame(
jove_owned_obj_t *objdir,
jove_owned_obj_t *target_obj,
@@ -66,7 +103,7 @@ s_syscall_pagedir_map_frame(
}
struct syscall_pagedir_map *payload = payload_data;
- sysret = pagedir_map_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
+ sysret = pagedir_map_untyped_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
obj_release(untyped_obj);
return sysret;
}
@@ -85,11 +122,43 @@ s_syscall_pagedir_map_table(
}
struct syscall_pagedir_map *payload = payload_data;
- sysret = pagedir_map_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
+ sysret = pagedir_map_untyped_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
obj_release(untyped_obj);
return sysret;
}
+static int
+s_syscall_pagedir_unmap_frame(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ jove_owned_obj_t *none_obj;
+ int sysret = s_syscall_pagedir_unmap(objdir, target_obj, payload_bytes, payload_data, &none_obj);
+
+ if(!sysret) return sysret;
+ struct syscall_pagedir_unmap *payload = payload_data;
+
+ return pagedir_unmap_untyped_frame(target_obj, none_obj, payload->virtual_address);
+}
+
+static int
+s_syscall_pagedir_unmap_table(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ jove_owned_obj_t *none_obj;
+ int sysret = s_syscall_pagedir_unmap(objdir, target_obj, payload_bytes, payload_data, &none_obj);
+
+ if(!sysret) return sysret;
+ struct syscall_pagedir_unmap *payload = payload_data;
+
+ return pagedir_unmap_untyped_table(target_obj, none_obj, payload->virtual_address);
+}
+
int
_syscall_handle_pagedir(
jove_owned_obj_t *pcb_obj,
@@ -105,6 +174,10 @@ _syscall_handle_pagedir(
return s_syscall_pagedir_map_frame(objdir, target_obj, bytes_left, payload);
case SYSCALL_PAGEDIR_MAP_TABLE:
return s_syscall_pagedir_map_table(objdir, target_obj, bytes_left, payload);
+ case SYSCALL_PAGEDIR_UNMAP_FRAME:
+ return s_syscall_pagedir_unmap_frame(objdir, target_obj, bytes_left, payload);
+ case SYSCALL_PAGEDIR_UNMAP_TABLE:
+ return s_syscall_pagedir_unmap_table(objdir, target_obj, bytes_left, payload);
default:
kprintf("syscall_handle_pagedir: Pagedir does not support syscall %i\n", header->callid);
return EBADARG;