diff options
author | Colin Schmidt <colins@berkeley.edu> | 2014-05-27 10:27:43 -0700 |
---|---|---|
committer | Colin Schmidt <colins@berkeley.edu> | 2014-05-27 10:27:43 -0700 |
commit | 8fc3a35ba546209532c5ee79db52f4f706bf6beb (patch) | |
tree | b7014666ae0f5c25e8666fc4c0384338e30f1219 /pk/vm.c | |
parent | 863e01b99095626a447d61f8f67fb4f1e6ba5355 (diff) | |
download | riscv-pk-8fc3a35ba546209532c5ee79db52f4f706bf6beb.zip riscv-pk-8fc3a35ba546209532c5ee79db52f4f706bf6beb.tar.gz riscv-pk-8fc3a35ba546209532c5ee79db52f4f706bf6beb.tar.bz2 |
Allow mmap to map new segments larger than 1 page on top of existing mappings and add mprotect syscall
Diffstat (limited to 'pk/vm.c')
-rw-r--r-- | pk/vm.c | 37 |
1 files changed, 36 insertions, 1 deletions
@@ -242,7 +242,7 @@ uintptr_t __do_mmap(uintptr_t addr, size_t length, int prot, int flags, file_t* kassert(pte); if (*pte) - __do_munmap(addr, RISCV_PGSIZE); + __do_munmap(a, RISCV_PGSIZE); *pte = (pte_t)v; } @@ -346,6 +346,41 @@ uintptr_t do_mremap(uintptr_t addr, size_t old_size, size_t new_size, int flags) return res; } +uintptr_t do_mprotect(uintptr_t addr, size_t length, int prot) +{ + uintptr_t res = 0; + if ((addr) & (RISCV_PGSIZE-1)) + return -EINVAL; + + spinlock_lock(&vm_lock); + for (uintptr_t a = addr; a < addr + length; a += RISCV_PGSIZE) + { + pte_t* pte = __walk(a); + if (pte == 0 || *pte == 0) + return -ENOMEM; + + if(!(*pte & PTE_V)){ + vmr_t* v = (vmr_t*)*pte; + if((v->prot ^ prot) & ~v->prot){ + //TODO:look at file to find perms + return -EACCES; + } + v->prot = prot; + }else{ + pte_t perms = pte_create(0, 0, prot); + if ((*pte & perms) != perms){ + //TODO:look at file to find perms + return -EACCES; + } + pte_t permset = (*pte & ~(PTE_UR | PTE_UW | PTE_UX)) | perms; + *pte = permset; + } + } + spinlock_unlock(&vm_lock); + + return res; +} + static void __map_kernel_range(uintptr_t paddr, size_t len, int prot) { pte_t perms = pte_create(0, prot, 0); |