summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/device/processor.c (renamed from arch/x86_64/processor.c)0
-rw-r--r--arch/x86_64/ivt.s2
-rw-r--r--arch/x86_64/page-mapping.c15
-rw-r--r--arch/x86_64/page_directory.c2
-rw-r--r--arch/x86_64/syscall/invoke-mapping.c (renamed from arch/x86_64/syscall-invoke-mapping.c)126
-rw-r--r--arch/x86_64/syscall/syscall.c (renamed from arch/x86_64/syscall.c)0
-rw-r--r--arch/x86_64/syscall/wrappers.h14
7 files changed, 93 insertions, 66 deletions
diff --git a/arch/x86_64/processor.c b/arch/x86_64/device/processor.c
index f7e5cac..f7e5cac 100644
--- a/arch/x86_64/processor.c
+++ b/arch/x86_64/device/processor.c
diff --git a/arch/x86_64/ivt.s b/arch/x86_64/ivt.s
index 0005686..a64f6b7 100644
--- a/arch/x86_64/ivt.s
+++ b/arch/x86_64/ivt.s
@@ -13,9 +13,9 @@ idt_load:
.type __isr_head @function
__isr_head:
pushall
- movq %rsp, %rdi
cld
+ movq %rsp, %rdi
call isr_handle
popall
diff --git a/arch/x86_64/page-mapping.c b/arch/x86_64/page-mapping.c
new file mode 100644
index 0000000..0de5bfa
--- /dev/null
+++ b/arch/x86_64/page-mapping.c
@@ -0,0 +1,15 @@
+#include "arch/x86_64/page-mapping.h"
+#include "arch/x86_64/page.h"
+#include <stddef.h>
+
+pmle_t*
+page_mapping_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path)
+{
+ uint16_t pathi = path[0];
+
+ pmle_t *pmle = &pml4[pathi];
+ pmle_t *pmle_table = vmem_phys_tovirt(pmle->paddr << 12);
+ if(depth == 0) return pmle;
+ if(!pmle->p) return NULL;
+ return page_mapping_traverse(pmle_table, depth - 1, path + 1);
+}
diff --git a/arch/x86_64/page_directory.c b/arch/x86_64/page_directory.c
index 494cab5..7030b05 100644
--- a/arch/x86_64/page_directory.c
+++ b/arch/x86_64/page_directory.c
@@ -114,6 +114,6 @@ vmem_setup(void)
//Add page mapping object to init directory.
_initDirectory.entries[INIT_OBJECT_PAGEMAP] = (objdir_entry_t) {
.type = KO_MEMORY_MAPPING,
- .data = kernel_pml4_base | 3
+ .data = kernel_pml4_base
};
}
diff --git a/arch/x86_64/syscall-invoke-mapping.c b/arch/x86_64/syscall/invoke-mapping.c
index 5b79239..be401d6 100644
--- a/arch/x86_64/syscall-invoke-mapping.c
+++ b/arch/x86_64/syscall/invoke-mapping.c
@@ -1,4 +1,4 @@
-#include "syscall/handles.h"
+#include "arch/x86_64/syscall/wrappers.h"
#include "arch/x86_64/syscall.h"
#include "arch/x86_64/page.h"
#include <stddef.h>
@@ -9,54 +9,21 @@
#include "print.h"
static int
-s_handle_invoke_mapping_release(
- objdir_t *root_dir,
- objdir_entry_t *target_entry,
- uint8_t *payload,
- size_t payload_at
- )
-{
-#ifdef DBG_SYSCALL
- klogf("release mapping %p\n", target_entry);
-#endif
- target_entry->data = 0;
- target_entry->type = KO_NONE;
- return 0;
-}
-
-static int
-s_handle_invoke_mapping_get(
+s_handle_invoke_mapping_exists(
objdir_t *root_dir,
objdir_entry_t *target_entry,
uint8_t *payload,
size_t payload_at
)
{
- pmli_t pmli;
- SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t);
-
- if(pmli > 511) return KE_OOB;
-
- uint8_t level = target_entry->data & 3;
- pmle_t *target_pml = (pmle_t*)vmem_phys_tovirt(target_entry->data & ~3ULL);
- if(level == 3 && pmli > 255) return KE_OOB;
- if(level < 0) return KE_BADOBJ;
+ pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *target_pml;
+ uint8_t target_depth;
+ SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
+ if(target_pml == NULL || !target_pml->p) return KE_DNE;
- size_t dest_pathw;
- objdir_entry_t *dest_entry;
- SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry);
-
- if(dest_entry->type != KO_NONE) return KE_FULL;
-
- pmle_t pmle = target_pml[pmli];
- if(!pmle.p) return KE_DNE;
-
- *dest_entry = (objdir_entry_t) {
- .type = KO_MEMORY_MAPPING,
- .data = (((uintptr_t)target_pml[pmli].paddr) << 12ULL) | (level - 1)
- };
#ifdef DBG_SYSCALL
- klogf("Get pml%i %p[%i] -> %p\n", level, target_pml, pmli, dest_entry->data & ~3ULL);
+ klogf("pml d%i %p from %p exists\n", target_depth, target_pml, pml4);
#endif
return 0;
}
@@ -69,15 +36,11 @@ s_handle_invoke_mapping_map(
size_t payload_at
)
{
- uint8_t level = target_entry->data & 3;
- pmle_t *target_pml = (pmle_t*)vmem_phys_tovirt(target_entry->data & ~3ULL);
-
- pmli_t pmli;
- SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t);
-
- if(pmli > 511) return KE_OOB;
- if(level == 3 && pmli > 255) return KE_OOB;
- if(level < 0) return KE_BADOBJ;
+ pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *target_pml;
+ uint8_t target_depth;
+ SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
+ if(target_pml == NULL) return KE_DNE;
size_t untyped_pathw;
objdir_entry_t *untyped_entry;
@@ -98,32 +61,67 @@ s_handle_invoke_mapping_map(
mtx_release(&untyped_entry->lock);
return KE_BADSIZE;
}
-
- pmle_t pmle = target_pml[pmli];
- if(pmle.p) {
- mtx_release(&untyped_entry->lock);
- return KE_OCCUPIED;
- }
- target_pml[pmli].value = untyped_phys | PAGE_RW | PAGE_US | PAGE_PRESENT;
- if(level != 0) {
+ target_pml->value = untyped_phys | PAGE_RW | PAGE_US | PAGE_PRESENT;
+ __asm__ volatile("invlpg (%0)":: "r"(untyped): "memory");
+
+ if(target_depth != 3) {
memset(untyped, 0, 0x1000);
}
- untyped_entry->type = KO_MEMORY_MAPPING;
- untyped_entry->data |= level - 1;
-
+ untyped_entry->type = KO_NONE;
#ifdef DBG_SYSCALL
- klogf("map %p[%p] to pml%i %p[%i]\n", untyped_entry, untyped_phys, level, target_pml, pmli);
+ klogf("map %p[%i] to %p[%i]\n", untyped_phys, target_depth, target_pml, ((uintptr_t)target_pml & 0xFFF) / 8);
#endif
mtx_release(&untyped_entry->lock);
return 0;
}
+static int
+s_handle_invoke_mapping_unmap(
+ objdir_t *root_dir,
+ objdir_entry_t *target_entry,
+ uint8_t *payload,
+ size_t payload_at
+ )
+{
+ pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *target_pml;
+ uint8_t target_depth;
+ SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
+ if(target_pml == NULL || !target_pml->p) return KE_DNE;
+
+ if(target_depth != 3) {
+ for(pmli_t i = 0; i < 512; i++) {
+ if(target_pml[i].p) return KE_FULL;
+ }
+ }
+
+ target_pml->p = false;
+
+ objdir_entry_t *dest_entry;
+ size_t dest_pathw;
+ SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry);
+
+ if(dest_entry->type != KO_NONE) return KE_FULL;
+ uintptr_t pmle_addr = target_pml->paddr << 12;
+ size_t *untyped = vmem_phys_tovirt(pmle_addr);
+ __asm__ volatile("invlpg (%0)":: "r"(untyped): "memory");
+
+ *untyped = 0x1000;
+ dest_entry->type = KO_MEMORY_UNTYPED;
+ dest_entry->data = pmle_addr;
+
+#ifdef DBG_SYSCALL
+ klogf("unmap %p[%i] to untyped %p\n", target_pml, 3 - target_depth, pmle_addr);
+#endif
+ return 0;
+}
+
static int (*s_invoke_handles[])(objdir_t*, objdir_entry_t*, uint8_t*, size_t) = {
- [INVOKE_MAPPING_RELEASE] = s_handle_invoke_mapping_release,
- [INVOKE_MAPPING_GET] = s_handle_invoke_mapping_get,
+ [INVOKE_MAPPING_EXISTS] = s_handle_invoke_mapping_exists,
[INVOKE_MAPPING_MAP] = s_handle_invoke_mapping_map,
+ [INVOKE_MAPPING_UNMAP] = s_handle_invoke_mapping_unmap
};
static size_t s_invoke_handles_count = sizeof(s_invoke_handles) / sizeof(void*);
diff --git a/arch/x86_64/syscall.c b/arch/x86_64/syscall/syscall.c
index 5582336..5582336 100644
--- a/arch/x86_64/syscall.c
+++ b/arch/x86_64/syscall/syscall.c
diff --git a/arch/x86_64/syscall/wrappers.h b/arch/x86_64/syscall/wrappers.h
new file mode 100644
index 0000000..a6fdf88
--- /dev/null
+++ b/arch/x86_64/syscall/wrappers.h
@@ -0,0 +1,14 @@
+#ifndef _JOVE_ARCH_x86_64_SYSCALL_WRAPPERS_H
+#define _JOVE_ARCH_x86_64_SYSCALL_WRAPPERS_H 1
+
+#include "arch/x86_64/page-mapping.h"
+#include "syscall/handles.h"
+
+#define SYSCALL_PAYLOAD_TAKEPML(payload, at, pml4, depth, pml) \
+ SYSCALL_PAYLOAD_TAKEL(payload, at, depth, uint8_t); \
+ if(((depth + 1) * sizeof(uint16_t)) + at >= KO_MESSAGE_BYTES) return KE_BADMSG; \
+ if(depth == 0 && *(uint16_t*)&payload[at] > 255) return KE_OOB; \
+ pml = page_mapping_traverse(pml4, depth, (uint16_t*)&payload[at]); \
+ at += (depth + 1) * sizeof(uint16_t)
+
+#endif