diff options
Diffstat (limited to 'arch/x86_64/hal/paging.c')
| -rw-r--r-- | arch/x86_64/hal/paging.c | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c index 9947e9c..2fbf26c 100644 --- a/arch/x86_64/hal/paging.c +++ b/arch/x86_64/hal/paging.c @@ -106,7 +106,7 @@ s_pagedir_get_pml1(page_t *pml4, uintptr_t vptr) } int pagedir_map_frame(page_t *pml4, - uintptr_t pptr, uintptr_t vptr, + uintptr_t pptr, uintptr_t vptr, uintmax_t flg) { page_t *pml1 = s_pagedir_get_pml1(pml4, vptr); @@ -121,41 +121,35 @@ int pagedir_map_frame(page_t *pml4, return 0; } -int pagedir_map_untyped_frame( - jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, - uintptr_t vptr, struct syscall_pagedir_flags flg) +int pagedir_map_shmem(page_t *pml4, + uintptr_t pptr, uintptr_t vptr, + struct syscall_pagedir_flags flg) { - page_t *pml4 = obj_deref(tgt); - uintptr_t frame = obj_getvalue(untyped_obj); - - return pagedir_map_frame(pml4, frame, vptr, - (flg.writeable ? PAGE_WRITEABLE : 0) | - PAGE_USER | - (flg.executable ? PAGE_XD : 0)); + uintmax_t real_flg = PAGE_USER | PAGE_SHMEM; + if(flg.writeable) { + real_flg |= PAGE_WRITEABLE; + } + if(!flg.executable) { + real_flg |= PAGE_XD; + } + return pagedir_map_frame(pml4, pptr, vptr, real_flg); } -int pagedir_unmap_untyped_frame( - jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr) +int pagedir_map_untyped_frame( + jove_owned_obj_t *tgt, jove_perm_obj_t *untyped, + uintptr_t vptr, struct syscall_pagedir_flags flg) { 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; - - uintptr_t untyped_pptr = (pml1[pml1i].paddr << 12); - - obj_settype(dst, JOVE_OBJ_UNTYPED); - obj_setvalue(dst, untyped_pptr); - - jove_untyped_t *untyped_data = obj_deref(dst); - untyped_data->limit = 0x1000; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + if(flg.writeable && (untyped->permissions & JOVE_PERM_WRITE) == 0) { + kprintf("%s: Untyped object flagged for writeable mapping missing write permissions!\n", __func__); + return -EPERM; + } - return 0; + 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)); } int pagedir_map_table(page_t *pml4, @@ -199,14 +193,63 @@ map_table: } int pagedir_map_untyped_table( - jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, uintptr_t vptr) + jove_owned_obj_t *tgt, jove_perm_obj_t *untyped, uintptr_t vptr) { page_t *pml4 = obj_deref(tgt); - uintptr_t frame = obj_getvalue(untyped_obj); + + if((untyped->permissions & JOVE_PERM_WRITE) == 0) { + kprintf("%s: Untyped object flagged for table mapping missing write permissions!\n", __func__); + return -EPERM; + } + uintptr_t frame = obj_getvalue(untyped->obj); return pagedir_map_table(pml4, frame, vptr); } +int pagedir_map_shmem_frame( + jove_owned_obj_t *tgt, jove_perm_obj_t *shmem, uint8_t page_offset, + uintptr_t vptr, struct syscall_pagedir_flags flg) +{ + page_t *pml4 = obj_deref(tgt); + + if(flg.writeable && (shmem->permissions & JOVE_PERM_WRITE) != 0) { + kprintf("%s: Shared memory object flagged for writeable mapping missing write permissions!\n", __func__); + return -EPERM; + } + + uintmax_t value = obj_getvalue(shmem->obj); + 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)); +} + +int pagedir_unmap_untyped_frame( + jove_owned_obj_t *tgt, jove_owned_obj_t *dst, 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; + + uintptr_t untyped_pptr = (pml1[pml1i].paddr << 12); + + obj_settype(dst, JOVE_OBJ_UNTYPED); + obj_setvalue(dst, untyped_pptr); + + jove_untyped_t *untyped_data = obj_deref(dst); + untyped_data->limit = 0x1000; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + + return 0; +} + int pagedir_unmap_untyped_table( jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr) { |
