diff options
Diffstat (limited to 'arch/x86_64/hal/paging.c')
| -rw-r--r-- | arch/x86_64/hal/paging.c | 112 |
1 files changed, 88 insertions, 24 deletions
diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c index 535d5b2..d5bcee3 100644 --- a/arch/x86_64/hal/paging.c +++ b/arch/x86_64/hal/paging.c @@ -22,6 +22,14 @@ PAGEALIGN page_t _kernel_pml1[512]; PAGEALIGN static page_t ident_pml3[IDENT_MASSIVEPAGES][512]; PAGEALIGN static page_t ident_pml2[IDENT_GIANTPAGES][512]; +virtaddr_t __syscall_stack_guard; +virtaddr_t __syscall_stack; +virtaddr_t __interrupt_stack_guard; +virtaddr_t __interrupt_stack; + +virtaddr_t *__syscall_stack_mapping; +virtaddr_t *__interrupt_stack_mapping; + void* phys_tovirt(uintptr_t phys) { @@ -95,7 +103,7 @@ s_pagedir_get_pml1(page_t *pml4, uintptr_t vptr) return 0; } - #define PML_TBL(tbl, i) (page_t*)(((uintptr_t)tbl[i].paddr << 12) | IDENT_VIRT_BASE) + #define PML_TBL(tbl, i) (page_t*)(((uintptr_t)tbl[i].pfn << 12) | IDENT_VIRT_BASE) page_t *pml3 = PML_TBL(pml4, pml4i); size_t pml3i = PML3I(vptr); @@ -137,18 +145,48 @@ uintptr_t *pagedir_get_mapping(jove_owned_obj_t *pagedir, uintptr_t vptr) return (uintptr_t*)mapping; } -uintptr_t +size_t +pagedir_mapping_get_pfn(virtaddr_t *mapping) +{ + return ((page_t*)mapping)->pfn; +} + +virtaddr_t pagedir_ident_from_mapping(uintptr_t *mapping) { - return (((page_t*)mapping)->paddr << 12) | IDENT_VIRT_BASE; + return (((page_t*)mapping)->pfn << 12) | IDENT_VIRT_BASE; +} + +inline bool pagedir_mapping_is_present(virtaddr_t *mapping) +{ + return ((page_t*)mapping)->p; +} + +inline void pagedir_mapping_set_pfn(virtaddr_t *mapping, size_t pfn) +{ + ((page_t*)mapping)->pfn = pfn; } -void -pagedir_mapping_set_present(uintptr_t *mapping, bool present) +inline void pagedir_mapping_set_present(virtaddr_t *mapping, bool present) { ((page_t*)mapping)->p = present; } +inline void pagedir_mapping_set_writeable(virtaddr_t *mapping, bool rw) +{ + ((page_t*)mapping)->rw = rw; +} + +inline void pagedir_mapping_set_user(virtaddr_t *mapping, bool user) +{ + ((page_t*)mapping)->u = user; +} + +inline void pagedir_mapping_set_type(virtaddr_t *mapping, int type) +{ + ((page_t*)mapping)->mapping_type = type; +} + int pagedir_map_frame(page_t *pml4, uintptr_t pptr, uintptr_t vptr, uintmax_t flg) @@ -165,11 +203,11 @@ int pagedir_map_frame(page_t *pml4, return 0; } -int pagedir_map_shmem(page_t *pml4, +int pagedir_map_frame_type(page_t *pml4, uintptr_t pptr, uintptr_t vptr, - struct syscall_pagedir_flags flg) + struct syscall_pagedir_flags flg, int type) { - uintmax_t real_flg = PAGE_USER | PAGE_SHMEM; + uintmax_t real_flg = PAGE_USER | (type << PAGE_SHL_TYPE); if(flg.writeable) { real_flg |= PAGE_WRITEABLE; } @@ -191,9 +229,7 @@ int pagedir_map_untyped_frame( } uintptr_t frame = obj_getvalue(untyped->obj); - return pagedir_map_frame(pml4, frame, vptr, PAGE_USER | - (flg.writeable ? PAGE_WRITEABLE : 0) | - (flg.executable ? 0 : PAGE_XD)); + return pagedir_map_frame_type(pml4, frame, vptr, flg, JOVE_MAPPING_TYPE_UNTYPED); } int pagedir_map_table(page_t *pml4, @@ -209,7 +245,7 @@ int pagedir_map_table(page_t *pml4, goto map_table; } - page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].paddr << 12) + page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].pfn << 12) | IDENT_VIRT_BASE); size_t pml3i = PML3I(vptr); if(!pml3[pml3i].p) { @@ -217,7 +253,7 @@ int pagedir_map_table(page_t *pml4, goto map_table; } - page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].paddr << 12) + page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].pfn << 12) | IDENT_VIRT_BASE); size_t pml2i = PML2I(vptr); if(!pml2[pml2i].p) { @@ -265,9 +301,7 @@ int pagedir_map_shmem_frame( uintptr_t frame = value & ~0xFF; frame += (uintmax_t)page_offset << 12; - return pagedir_map_frame(pml4, frame, vptr, PAGE_USER | - (flg.writeable ? PAGE_WRITEABLE : 0) | - (flg.executable ? 0 : PAGE_XD)); + return pagedir_map_frame_type(pml4, frame, vptr, flg, JOVE_MAPPING_TYPE_SHMEM); } int pagedir_unmap_untyped_frame( @@ -276,13 +310,14 @@ int pagedir_unmap_untyped_frame( page_t *pml4 = obj_deref(tgt); size_t pml4i = PML4I(vptr); - if(!pml4[pml4i].p) return ENOMAP; + if(!pml4[pml4i].p) return -ENOMAP; page_t *pml1 = s_pagedir_get_pml1(pml4, vptr); size_t pml1i = PML1I(vptr); - if(!pml1[pml1i].p) return ENOMAP; + if(!pml1[pml1i].p) return -ENOMAP; - uintptr_t untyped_pptr = (pml1[pml1i].paddr << 12); + if(pml1[pml1i].mapping_type != JOVE_MAPPING_TYPE_UNTYPED) return -ENOMAP; + uintptr_t untyped_pptr = (pml1[pml1i].pfn << 12); obj_settype(dst, JOVE_OBJ_UNTYPED); obj_setvalue(dst, untyped_pptr); @@ -294,6 +329,26 @@ int pagedir_unmap_untyped_frame( return 0; } +int pagedir_unmap_shmem_frame( + jove_owned_obj_t *tgt, uintptr_t vptr) +{ + page_t *pml4 = obj_deref(tgt); + + size_t pml4i = PML4I(vptr); + if(!pml4[pml4i].p) return -ENOMAP; + + page_t *pml1 = s_pagedir_get_pml1(pml4, vptr); + size_t pml1i = PML1I(vptr); + if(!pml1[pml1i].p) return -ENOMAP; + + if(pml1[pml1i].mapping_type != JOVE_MAPPING_TYPE_UNTYPED) return -ENOMAP; + + pml1[pml1i].p = 0; + pagedir_invlpg(vptr); + + return 0; +} + int pagedir_unmap_untyped_table( jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr) { @@ -304,12 +359,12 @@ int pagedir_unmap_untyped_table( //trying to unmap the entire address space. We don't support this. size_t pml4i = PML4I(vptr); if(!pml4[pml4i].p) { - return ENOMAP; + return -ENOMAP; } target_table = &pml4[pml4i]; //Try to unmap the pml4 entry if the pml3 entry does not exist. - page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].paddr << 12) | IDENT_VIRT_BASE); + page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].pfn << 12) | IDENT_VIRT_BASE); size_t pml3i = PML3I(vptr); if(!pml3[pml3i].p) { goto unmap_table; @@ -317,7 +372,7 @@ int pagedir_unmap_untyped_table( target_table = &pml3[pml3i]; //Try to unmap the pml3 entry if the pml2 entry does not exist. - page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].paddr << 12) | IDENT_VIRT_BASE); + page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].pfn << 12) | IDENT_VIRT_BASE); size_t pml2i = PML2I(vptr); if(!pml2[pml2i].p) { goto unmap_table; @@ -327,13 +382,13 @@ int pagedir_unmap_untyped_table( unmap_table: { - uintptr_t frame = target_table->paddr << 12; + uintptr_t frame = target_table->pfn << 12; page_t *target_vals = (page_t*)(frame | IDENT_VIRT_BASE); //Check that the page table at our target entry is empty. //If it's not, we return an error saying that the entry contains a map. for(size_t i = 0; i < 512; i++) { - if(target_vals[i].p) return EHASMAP; + if(target_vals[i].p) return -EHASMAP; } //Populate the none object with an untyped object at the free'd page frame. @@ -421,6 +476,15 @@ paging_pml4_init(void) | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_GLOBAL | PAGE_XD; } + size_t kernel_stack_off = kernel_data_off + kernel_data_pages; + __syscall_stack_guard = ((kernel_stack_off) << 12) + KERNEL_VIRT_BASE; + __syscall_stack = __syscall_stack_guard + 0x1000; + __interrupt_stack_guard = __syscall_stack + 0x1000; + __interrupt_stack = __interrupt_stack_guard + 0x1000; + + __syscall_stack_mapping = (virtaddr_t*)&_kernel_pml1[kernel_stack_off + 1]; + __interrupt_stack_mapping = (virtaddr_t*)&_kernel_pml1[kernel_stack_off + 3]; + /*Identity pages are mapped as huge pages starting at the 256'th PML3 entry. *We want to support any range of physical memory up to several TiB, so *the mapper has to consider multiple heirarchies of huge pages.*/ |
