From 458d2f4c8308602ad669047b77e575635ce9bee2 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 19 Apr 2026 21:02:42 -0400 Subject: [PATCH] sp1/amd64+vm: Fork VFR on boot Signed-off-by: Ian Moffett --- usr/src/sp1/amd64/cpu/cpu_mmu.c | 48 +++++++++++++++++++++++++++++++++ usr/src/sp1/common/mm/vm_init.c | 36 +++++++++++++++++++++++++ usr/src/sp1/common/os/main.c | 4 +++ usr/src/sp1/head/mm/vm.h | 5 ++++ usr/src/sp1/head/mu/mmu.h | 10 +++++++ 5 files changed, 103 insertions(+) create mode 100644 usr/src/sp1/common/mm/vm_init.c diff --git a/usr/src/sp1/amd64/cpu/cpu_mmu.c b/usr/src/sp1/amd64/cpu/cpu_mmu.c index 4cab90c..80176d4 100644 --- a/usr/src/sp1/amd64/cpu/cpu_mmu.c +++ b/usr/src/sp1/amd64/cpu/cpu_mmu.c @@ -11,6 +11,25 @@ #include #include +#include +#include + +/* + * Page-Table Entry (PTE) flags + * + * See Intel SDM Vol 3A, Section 4.5, Table 4-19 + */ +#define PTE_ADDR_MASK 0x000FFFFFFFFFF000 +#define PTE_P BIT(0) /* Present */ +#define PTE_RW BIT(1) /* Writable */ +#define PTE_US BIT(2) /* User r/w allowed */ +#define PTE_PWT BIT(3) /* Page-level write-through */ +#define PTE_PCD BIT(4) /* Page-level cache disable */ +#define PTE_ACC BIT(5) /* Accessed */ +#define PTE_DIRTY BIT(6) /* Dirty (written-to page) */ +#define PTE_PS BIT(7) /* Page size */ +#define PTE_GLOBAL BIT(8) /* Global; sticky */ +#define PTE_NX BIT(63) /* Execute-disable */ void mu_mmu_readvfr(struct mmu_vfr *res) @@ -41,3 +60,32 @@ mu_mmu_writevfr(struct mmu_vfr *vfr) : "memory" ); } + +status_t +mu_mmu_forkvfr(struct mmu_vfr *vfr, struct mmu_vfr *res) +{ + uintptr_t dest; + uintptr_t *dest_p, *src_p; + + if (vfr == NULL || res == NULL) { + return STATUS_INVALID_PARAM; + } + + if ((dest = mm_physmem_alloc(1)) == 0) { + return STATUS_NO_MEMORY; + } + + src_p = pma_to_vma((vfr->cr3 & PTE_ADDR_MASK)); + dest_p = pma_to_vma(dest); + + for (int i = 0; i < 512; ++i) { + if (i < 256) { + dest_p[i] = 0; + } else { + dest_p[i] = src_p[i]; + } + } + + res->cr3 = dest; + return STATUS_SUCCESS; +} diff --git a/usr/src/sp1/common/mm/vm_init.c b/usr/src/sp1/common/mm/vm_init.c new file mode 100644 index 0000000..0e392ee --- /dev/null +++ b/usr/src/sp1/common/mm/vm_init.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2026, Mirocom Laboratories + * All rights reserved. + * + * The following sources are CONFIDENTIAL and PROPRIETARY + * property of Mirocom Laboratories. Unauthorized copying, + * use, distribution or modification of this file, in whole + * and in part, is strictly prohibited without the prior written + * consent from Mirocom Laboratories. + */ + +#include +#include +#include + +#define pr_trace(fmt, ...) \ + printf("vm: " fmt, ##__VA_ARGS__) + +/* Kernel virtual fuck region */ +static struct mmu_vfr kvfr; + +void +mm_vm_init(void) +{ + struct mmu_vfr vfr; + + pr_trace("forking vfr\n"); + mu_mmu_readvfr(&vfr); + if (mu_mmu_forkvfr(&vfr, &kvfr) != STATUS_SUCCESS) { + knot("insufficient memory resources\n"); + } + + /* Update the current VFR */ + mu_mmu_writevfr(&kvfr); + pr_trace("... OK\n"); +} diff --git a/usr/src/sp1/common/os/main.c b/usr/src/sp1/common/os/main.c index 4f02b72..a3b3c3c 100644 --- a/usr/src/sp1/common/os/main.c +++ b/usr/src/sp1/common/os/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #define KERNEL_VERSION "0.0.1" @@ -52,6 +53,9 @@ main(void) /* Initialize physical memory management */ mm_physmem_init(); + /* Initialize virtual memory management */ + mm_vm_init(); + printf("[*] sp1 is pre-alpha\n"); printf("[*] knotting kernel...\n"); knot("end of kernel reached - halting\n"); diff --git a/usr/src/sp1/head/mm/vm.h b/usr/src/sp1/head/mm/vm.h index 348197d..8baaa06 100644 --- a/usr/src/sp1/head/mm/vm.h +++ b/usr/src/sp1/head/mm/vm.h @@ -24,4 +24,9 @@ #define vma_to_pma(vma) \ (uintptr_t)PTR_NOFFSET(vma, bpt_kload_base()) +/* + * Initialize the virtual memory management + */ +void mm_vm_init(void); + #endif /* !_MM_VM_H_ */ diff --git a/usr/src/sp1/head/mu/mmu.h b/usr/src/sp1/head/mu/mmu.h index 3443e23..aee9c5f 100644 --- a/usr/src/sp1/head/mu/mmu.h +++ b/usr/src/sp1/head/mu/mmu.h @@ -12,6 +12,8 @@ #ifndef _MU_MMU_H_ #define _MU_MMU_H_ 1 +#include + /* * Each running SP1 process is to have a virtual fuck region * which logically isolates their address space with the help @@ -33,4 +35,12 @@ void mu_mmu_readvfr(struct mmu_vfr *res); */ void mu_mmu_writevfr(struct mmu_vfr *vfr); +/* + * Fork a VFR and clear out the lower half + * + * @vfr: Virtual fuck region to fork + * @res: Virtual fuck region result written here + */ +status_t mu_mmu_forkvfr(struct mmu_vfr *vfr, struct mmu_vfr *res); + #endif /* !_MU_MMU_H_ */