aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Schmidt <colins@berkeley.edu>2014-05-27 10:27:43 -0700
committerColin Schmidt <colins@berkeley.edu>2014-05-27 10:27:43 -0700
commit8fc3a35ba546209532c5ee79db52f4f706bf6beb (patch)
treeb7014666ae0f5c25e8666fc4c0384338e30f1219
parent863e01b99095626a447d61f8f67fb4f1e6ba5355 (diff)
downloadpk-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.c11
-rw-r--r--pk/syscall.h1
-rw-r--r--pk/vm.c37
-rw-r--r--pk/vm.h1
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
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);
diff --git a/pk/vm.h b/pk/vm.h
index cdd4f77..d46abec 100644
--- a/pk/vm.h
+++ b/pk/vm.h
@@ -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