From 8fc3a35ba546209532c5ee79db52f4f706bf6beb Mon Sep 17 00:00:00 2001 From: Colin Schmidt Date: Tue, 27 May 2014 10:27:43 -0700 Subject: Allow mmap to map new segments larger than 1 page on top of existing mappings and add mprotect syscall --- pk/vm.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'pk/vm.c') diff --git a/pk/vm.c b/pk/vm.c index 8ab466e..783153c 100644 --- a/pk/vm.c +++ b/pk/vm.c @@ -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); -- cgit v1.1