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 | |
parent | 863e01b99095626a447d61f8f67fb4f1e6ba5355 (diff) | |
download | pk-8fc3a35ba546209532c5ee79db52f4f706bf6beb.zip pk-8fc3a35ba546209532c5ee79db52f4f706bf6beb.tar.gz pk-8fc3a35ba546209532c5ee79db52f4f706bf6beb.tar.bz2 |
Allow mmap to map new segments larger than 1 page on top of existing mappings and add mprotect syscall
-rw-r--r-- | pk/syscall.c | 11 | ||||
-rw-r--r-- | pk/syscall.h | 1 | ||||
-rw-r--r-- | pk/vm.c | 37 | ||||
-rw-r--r-- | pk/vm.h | 1 |
4 files changed, 44 insertions, 6 deletions
diff --git a/pk/syscall.c b/pk/syscall.c index e25b883..0c73a83 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -75,7 +75,6 @@ ssize_t sys_write(int fd, const char* buf, size_t n) int sys_open(const char* name, int flags, int mode) { - printk("OPEN(%s)\n",name); file_t* file = file_open(name, flags, mode); if (IS_ERR_VALUE(file)) return PTR_ERR(file); @@ -110,7 +109,6 @@ int sys_openat(int dirfd, const char* name, int flags, int mode) int sys_close(int fd) { - //printk("CLOSE(%ld)\n",fd); int ret = fd_close(fd); if (ret < 0) return -EBADF; @@ -119,7 +117,6 @@ int sys_close(int fd) int sys_fstat(int fd, void* st) { - printk("FSTAT(%ld)\n",fd); int r = -EBADF; file_t* f = file_get(fd); @@ -275,9 +272,7 @@ int sys_getuid() uintptr_t sys_mmap(uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset) { - printk("MMAP(ad:%ld,len:%ld,prot:%ld,flags:%ld,fd:%ld,off:%ld\n",addr,length,prot,flags,fd,offset); uintptr_t ret = do_mmap(addr, length, prot, flags, fd, offset); - //printk("MMAP DONE\n"); return ret; } @@ -291,6 +286,11 @@ uintptr_t sys_mremap(uintptr_t addr, size_t old_size, size_t new_size, int flags return do_mremap(addr, old_size, new_size, flags); } +uintptr_t sys_mprotect(uintptr_t addr, size_t length, int prot) +{ + return do_mprotect(addr, length, prot); +} + int sys_rt_sigaction(int sig, const void* act, void* oact, size_t sssz) { if (oact) @@ -390,6 +390,7 @@ long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long n) [SYS_mmap] = sys_mmap, [SYS_munmap] = sys_munmap, [SYS_mremap] = sys_mremap, + [SYS_mprotect] = sys_mprotect, [SYS_rt_sigaction] = sys_rt_sigaction, [SYS_time] = sys_time, [SYS_gettimeofday] = sys_gettimeofday, diff --git a/pk/syscall.h b/pk/syscall.h index e3a88ce..5d6bbf0 100644 --- a/pk/syscall.h +++ b/pk/syscall.h @@ -35,6 +35,7 @@ #define SYS_mmap 222 #define SYS_munmap 215 #define SYS_mremap 216 +#define SYS_mprotect 226 #define SYS_time 1062 #define SYS_getmainvars 2011 #define SYS_rt_sigaction 134 @@ -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); @@ -24,6 +24,7 @@ uintptr_t __do_mmap(uintptr_t addr, size_t length, int prot, int flags, file_t* uintptr_t do_mmap(uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset); int do_munmap(uintptr_t addr, size_t length); uintptr_t do_mremap(uintptr_t addr, size_t old_size, size_t new_size, int flags); +uintptr_t do_mprotect(uintptr_t addr, size_t length, int prot); uintptr_t do_brk(uintptr_t addr); #endif |