sp1/amd64+vm: Fork VFR on boot

Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
2026-04-19 21:02:42 -04:00
parent c5a7b3279c
commit 458d2f4c83
5 changed files with 103 additions and 0 deletions
+48
View File
@@ -11,6 +11,25 @@
#include <sys/cdefs.h>
#include <mu/mmu.h>
#include <mm/vm.h>
#include <mm/physmem.h>
/*
* 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;
}
+36
View File
@@ -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 <os/knot.h>
#include <mu/mmu.h>
#include <lib/printf.h>
#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");
}
+4
View File
@@ -15,6 +15,7 @@
#include <lib/printf.h>
#include <mu/cpu.h>
#include <mm/physmem.h>
#include <mm/vm.h>
#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");
+5
View File
@@ -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_ */
+10
View File
@@ -12,6 +12,8 @@
#ifndef _MU_MMU_H_
#define _MU_MMU_H_ 1
#include <sys/status.h>
/*
* 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_ */