summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/amd64/pmap.c39
-rw-r--r--sys/include/vm/pmap.h4
2 files changed, 43 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c
index a952b41..8a21f63 100644
--- a/sys/arch/amd64/amd64/pmap.c
+++ b/sys/arch/amd64/amd64/pmap.c
@@ -29,9 +29,11 @@
#include <vm/pmap.h>
#include <vm/vm.h>
+#include <vm/physseg.h>
#include <sys/cdefs.h>
#include <machine/tlb.h>
#include <assert.h>
+#include <string.h>
/*
* Page-Table Entry (PTE) flags
@@ -159,6 +161,43 @@ pmap_unmap(struct vm_ctx *ctx, vaddr_t va)
}
struct vas
+pmap_create_vas(struct vm_ctx *ctx)
+{
+ struct vas current_vas = pmap_read_vas();
+ struct vas new_vas = {0};
+ uint64_t *src, *dest;
+
+ /*
+ * We want to allocate a zeroed pageframe
+ * and copy the higher half to it. The lower
+ * half can remain zero for userland.
+ */
+ new_vas.top_level = vm_alloc_pageframe(1);
+
+ if (new_vas.top_level == 0) {
+ /* Top level may remain zero to denote failure */
+ return new_vas;
+ }
+
+ src = PHYS_TO_VIRT(current_vas.top_level);
+ dest = PHYS_TO_VIRT(new_vas.top_level);
+
+ /*
+ * Copy the top half and zero the bottom
+ * half.
+ */
+ for (size_t i = 0; i < 512; ++i) {
+ if (i < 256) {
+ dest[i] = 0;
+ continue;
+ }
+ dest[i] = src[i];
+ }
+
+ return new_vas;
+}
+
+struct vas
pmap_read_vas(void)
{
struct vas vas;
diff --git a/sys/include/vm/pmap.h b/sys/include/vm/pmap.h
index fcef35d..6e37a00 100644
--- a/sys/include/vm/pmap.h
+++ b/sys/include/vm/pmap.h
@@ -53,6 +53,8 @@
#define PMAP_WRITABLE __BIT(0) /* Writable */
#define PMAP_EXEC __BIT(1) /* Executable */
+#define is_vas_valid(vas) (vas.top_level != 0)
+
/*
* vm_ctx - Per core virtual memory context
*/
@@ -63,6 +65,8 @@ struct vm_ctx {
struct spinlock dynalloc_lock;
};
+struct vas pmap_create_vas(struct vm_ctx *);
+
/*
* Read virtual address space descriptor
* and return it.