user program (still many #PF)
This commit is contained in:
+19
-3
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user