sp1/amd64+vm: Fork VFR on boot
Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
@@ -11,6 +11,25 @@
|
|||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#include <mu/mmu.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
|
void
|
||||||
mu_mmu_readvfr(struct mmu_vfr *res)
|
mu_mmu_readvfr(struct mmu_vfr *res)
|
||||||
@@ -41,3 +60,32 @@ mu_mmu_writevfr(struct mmu_vfr *vfr)
|
|||||||
: "memory"
|
: "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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <lib/printf.h>
|
#include <lib/printf.h>
|
||||||
#include <mu/cpu.h>
|
#include <mu/cpu.h>
|
||||||
#include <mm/physmem.h>
|
#include <mm/physmem.h>
|
||||||
|
#include <mm/vm.h>
|
||||||
|
|
||||||
#define KERNEL_VERSION "0.0.1"
|
#define KERNEL_VERSION "0.0.1"
|
||||||
|
|
||||||
@@ -52,6 +53,9 @@ main(void)
|
|||||||
/* Initialize physical memory management */
|
/* Initialize physical memory management */
|
||||||
mm_physmem_init();
|
mm_physmem_init();
|
||||||
|
|
||||||
|
/* Initialize virtual memory management */
|
||||||
|
mm_vm_init();
|
||||||
|
|
||||||
printf("[*] sp1 is pre-alpha\n");
|
printf("[*] sp1 is pre-alpha\n");
|
||||||
printf("[*] knotting kernel...\n");
|
printf("[*] knotting kernel...\n");
|
||||||
knot("end of kernel reached - halting\n");
|
knot("end of kernel reached - halting\n");
|
||||||
|
|||||||
@@ -24,4 +24,9 @@
|
|||||||
#define vma_to_pma(vma) \
|
#define vma_to_pma(vma) \
|
||||||
(uintptr_t)PTR_NOFFSET(vma, bpt_kload_base())
|
(uintptr_t)PTR_NOFFSET(vma, bpt_kload_base())
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the virtual memory management
|
||||||
|
*/
|
||||||
|
void mm_vm_init(void);
|
||||||
|
|
||||||
#endif /* !_MM_VM_H_ */
|
#endif /* !_MM_VM_H_ */
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#ifndef _MU_MMU_H_
|
#ifndef _MU_MMU_H_
|
||||||
#define _MU_MMU_H_ 1
|
#define _MU_MMU_H_ 1
|
||||||
|
|
||||||
|
#include <sys/status.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each running SP1 process is to have a virtual fuck region
|
* Each running SP1 process is to have a virtual fuck region
|
||||||
* which logically isolates their address space with the help
|
* 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);
|
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_ */
|
#endif /* !_MU_MMU_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user