user program (still many #PF)

This commit is contained in:
2026-04-02 17:05:51 +02:00
parent 11a9dd4adb
commit aa30d9c6b5
11 changed files with 107 additions and 16 deletions
+19 -3
View File
@@ -99,30 +99,46 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
uint64_t *pdpt, *pd, *pt;
// Any parent entry on a userspace mapping must also carry PTE_USER,
// otherwise CPL3 accesses fault even if the final PTE is user.
uint64_t parent_flags = PTE_PRESENT | PTE_WRITABLE;
if (flags & PTE_USER) {
parent_flags |= PTE_USER;
}
// PML4
// If the entry at index is not present, allocate enough space for it
// then populate the entry with correct addr + flags
if (!(root_table[pml4_i] & PTE_PRESENT)) {
pdpt = alloc_page_table();
root_table[pml4_i] = VIRT_TO_PHYS(pdpt) | PTE_PRESENT | PTE_WRITABLE;
root_table[pml4_i] = VIRT_TO_PHYS(pdpt) | parent_flags;
} else {
pdpt = (uint64_t *)PHYS_TO_VIRT(root_table[pml4_i] & PTE_ADDR_MASK);
if (flags & PTE_USER) {
root_table[pml4_i] |= PTE_USER;
}
}
// PDPT: same here
if (!(pdpt[pdpt_i] & PTE_PRESENT)) {
pd = alloc_page_table();
pdpt[pdpt_i] = VIRT_TO_PHYS(pd) | PTE_PRESENT | PTE_WRITABLE;
pdpt[pdpt_i] = VIRT_TO_PHYS(pd) | parent_flags;
} else {
pd = (uint64_t *)PHYS_TO_VIRT(pdpt[pdpt_i] & PTE_ADDR_MASK);
if (flags & PTE_USER) {
pdpt[pdpt_i] |= PTE_USER;
}
}
// PD: and here
if (!(pd[pd_i] & PTE_PRESENT)) {
pt = alloc_page_table();
pd[pd_i] = VIRT_TO_PHYS(pt) | PTE_PRESENT | PTE_WRITABLE;
pd[pd_i] = VIRT_TO_PHYS(pt) | parent_flags;
} else {
pt = (uint64_t *)PHYS_TO_VIRT(pd[pd_i] & PTE_ADDR_MASK);
if (flags & PTE_USER) {
pd[pd_i] |= PTE_USER;
}
}
// PT: finally, populate the page table entry
+11
View File
@@ -250,6 +250,17 @@ uintptr_t vmm_alloc_user_stack(uint64_t* pml4)
return stack_top;
}
uintptr_t vmm_alloc_user_code(uint64_t* pml4, void* code_addr, uint64_t code_size)
{
uintptr_t code_start = USER_CODE_START;
for (size_t i=code_start; i<code_start+code_size; i+=PAGE_SIZE) {
vmm_map(pml4, i, PTE_PRESENT | PTE_WRITABLE | PTE_USER);
}
return code_start;
}
void vmm_init()
{
// NO U