Added mprotect; made mmap work (dumbly) for files
authorAndrew Waterman <waterman@parcad.millennium.berkeley.edu>
Sat, 6 Feb 2010 23:38:06 +0000 (15:38 -0800)
committerAndrew Waterman <waterman@parcad.millennium.berkeley.edu>
Sat, 6 Feb 2010 23:38:06 +0000 (15:38 -0800)
Had to add sys_pread to accomplish this

12 files changed:
kern/arch/sparc/console.c
kern/arch/sparc/frontend.c
kern/arch/sparc/frontend.h
kern/arch/sparc/process.c
kern/arch/sparc/syscalls.c
kern/include/ros/mman.h
kern/include/ros/syscall.h
kern/include/syscall.h
kern/src/env.c
kern/src/mm.c
kern/src/page_alloc.c
kern/src/syscall.c

index d2ca4c2..c2afb6c 100644 (file)
@@ -12,7 +12,7 @@ void
 cputbuf(const char*COUNT(len) buf, int len)
 {
        int32_t errno;
-       frontend_syscall(0,RAMP_SYSCALL_write,1,PADDR((int32_t)buf),len,&errno);
+       frontend_syscall(0,RAMP_SYSCALL_write,1,PADDR((int32_t)buf),len,0,&errno);
 }
 
 // Low-level console I/O
@@ -44,7 +44,7 @@ cons_getc()
 {
        char ch;
        int32_t errno;
-       int32_t ret = frontend_syscall(0,RAMP_SYSCALL_read,0,PADDR((int32_t)&ch),1,&errno);
+       int32_t ret = frontend_syscall(0,RAMP_SYSCALL_read,0,PADDR((int32_t)&ch),1,0,&errno);
        if(ch == 0x7F)
                ch = '\b';
        return ret <= 0 ? 0 : ch;
index d91f1e1..1e17b6b 100644 (file)
@@ -37,14 +37,14 @@ int32_t frontend_syscall_from_user(env_t* p, int32_t syscall_num, uint32_t arg0,
        }
 
        int32_t errno;
-       int32_t ret = frontend_syscall(p->pid,syscall_num,arg[0],arg[1],arg[2],&errno);
+       int32_t ret = frontend_syscall(p->pid,syscall_num,arg[0],arg[1],arg[2],0,&errno);
        set_errno(current_tf,errno);
 
        spin_unlock_irqsave(&lock);
        return ret;
 }
 
-int32_t frontend_syscall(pid_t pid, int32_t syscall_num, uint32_t arg0, uint32_t arg1, uint32_t arg2, int32_t* errno)
+int32_t frontend_syscall(pid_t pid, int32_t syscall_num, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, int32_t* errno)
 {
        static spinlock_t lock = SPINLOCK_INITIALIZER;
        int32_t ret;
@@ -60,6 +60,7 @@ int32_t frontend_syscall(pid_t pid, int32_t syscall_num, uint32_t arg0, uint32_t
        magic_mem[2] = arg0;
        magic_mem[3] = arg1;
        magic_mem[4] = arg2;
+       magic_mem[5] = arg3;
        magic_mem[6] = pid;
        magic_mem[0] = 0x80;
 
@@ -110,7 +111,7 @@ int32_t sys_nbgetch()
 void __diediedie(trapframe_t* tf, uint32_t srcid, uint32_t code, uint32_t a1, uint32_t a2)
 {
        int32_t errno;
-       frontend_syscall(0,RAMP_SYSCALL_exit,(int)code,0,0,&errno);
+       frontend_syscall(0,RAMP_SYSCALL_exit,(int)code,0,0,0,&errno);
        while(1);
 }
 
index 7fa31c9..ed3f315 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <env.h>
 int32_t frontend_syscall_from_user(env_t* p, int32_t syscall_num, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t translate_args);
-int32_t frontend_syscall(pid_t pid, int32_t syscall_num, uint32_t arg0, uint32_t arg1, uint32_t arg2, int32_t* errno);
+int32_t frontend_syscall(pid_t pid, int32_t syscall_num, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, int32_t* errno);
 
 int32_t sys_nbgetch();
 int32_t sys_nbputch(char ch);
@@ -43,6 +43,8 @@ int32_t sys_nbputch(char ch);
 #define RAMP_SYSCALL_proc_free         96
 #define RAMP_SYSCALL_proc_init         97
 #define RAMP_SYSCALL_time              98
+#define RAMP_SYSCALL_pread             173
+#define RAMP_SYSCALL_pwrite            174
 #define RAMP_SYSCALL_getcwd            229
 
 #endif /* !ROS_ARCH_FRONTEND_H */
index 519619f..0fd5656 100644 (file)
@@ -19,7 +19,7 @@ proc_init_arch(struct proc *SAFE p)
 {
        pid_t parent_id = p->ppid, id = p->pid;
        int32_t errno;
-       if(frontend_syscall(parent_id,RAMP_SYSCALL_proc_init,id,0,0,&errno))
+       if(frontend_syscall(parent_id,RAMP_SYSCALL_proc_init,id,0,0,0,&errno))
                panic("Front-end server couldn't initialize new process!");
 }
 
@@ -28,7 +28,7 @@ void
 proc_free_arch(struct proc *SAFE p)
 {
        int32_t errno;
-       if(frontend_syscall(0,RAMP_SYSCALL_proc_free,p->pid,0,0,&errno))
+       if(frontend_syscall(0,RAMP_SYSCALL_proc_free,p->pid,0,0,0,&errno))
                panic("Front-end server couldn't free process!");
 }
 
index 4ee76e7..5419fdb 100644 (file)
@@ -8,6 +8,9 @@
 
 void* user_memdup(struct proc* p, const void* va, int len)
 {
+       if(!p)
+               return (void*)va;
+
        void* kva = NULL;
        if(len < 0 || (kva = kmalloc(len,0)) == NULL)
                return ERR_PTR(-ENOMEM);
@@ -31,8 +34,17 @@ static void* user_memdup_errno(struct proc* p, const void* va, int len)
        return kva;
 }
 
+static void user_memdup_free(struct proc* p, void* va)
+{
+       if(p)
+               kfree(va);
+}
+
 char* user_strdup(struct proc* p, const char* va0, int max)
 {
+       if(!p)
+               return (char*)va0;
+
        max++;
        char* kbuf = (char*)kmalloc(PGSIZE,0);
        if(kbuf == NULL)
@@ -76,7 +88,9 @@ static char* user_strdup_errno(struct proc* p, const char* va, int max)
 static int memcpy_to_user_errno(struct proc* p, void* dst, const void* src,
                                 int len)
 {
-       if(memcpy_to_user(p,dst,src,len))
+       if(!p)
+               memcpy(dst,src,len);
+       else if(memcpy_to_user(p,dst,src,len))
        {
                set_errno(current_tf,EINVAL);
                return -1;
@@ -92,36 +106,58 @@ static void* kmalloc_errno(int len)
        return kva;
 }
 
-int user_frontend_syscall_errno(struct proc* p, int n, int a0, int a1, int a2)
+int user_frontend_syscall_errno(struct proc* p, int n, int a0, int a1, int a2, int a3)
 {
-       int errno, ret = frontend_syscall(p->pid,n,a0,a1,a2,&errno);
-       if(errno)
+       int errno, ret = frontend_syscall(p?p->pid:0,n,a0,a1,a2,a3,&errno);
+       if(errno && p)
                set_errno(current_tf,errno);
        return ret;
 }
-#define fe(which,a0,a1,a2) \
+#define fe(which,a0,a1,a2,a3) \
        user_frontend_syscall_errno(p,RAMP_SYSCALL_##which,\
-                                    (int)(a0),(int)(a1),(int)(a2))
+                          (int)(a0),(int)(a1),(int)(a2),(int)(a3))
 
 intreg_t sys_write(struct proc* p, int fd, const void* buf, int len)
 {
        void* kbuf = user_memdup_errno(p,buf,len);
        if(kbuf == NULL)
                return -1;
-       int ret = fe(write,fd,PADDR(kbuf),len);
-       kfree(kbuf);
+       int ret = fe(write,fd,PADDR(kbuf),len,0);
+       user_memdup_free(p,kbuf);
        return ret;
 }
 
 intreg_t sys_read(struct proc* p, int fd, void* buf, int len)
 {
-       void* kbuf = kmalloc_errno(len);
+       void* kbuf = p ? kmalloc_errno(len) : buf;
        if(kbuf == NULL)
                return -1;
-       int ret = fe(read,fd,PADDR(kbuf),len);
-       if(ret != -1 && memcpy_to_user_errno(p,buf,kbuf,len))
+       int ret = fe(read,fd,PADDR(kbuf),len,0);
+       if(ret != -1 && p && memcpy_to_user_errno(p,buf,kbuf,len))
                ret = -1;
-       kfree(kbuf);
+       user_memdup_free(p,kbuf);
+       return ret;
+}
+
+intreg_t sys_pwrite(struct proc* p, int fd, const void* buf, int len, int offset)
+{
+       void* kbuf = user_memdup_errno(p,buf,len);
+       if(kbuf == NULL)
+               return -1;
+       int ret = fe(pwrite,fd,PADDR(kbuf),len,offset);
+       user_memdup_free(p,kbuf);
+       return ret;
+}
+
+intreg_t sys_pread(struct proc* p, int fd, void* buf, int len, int offset)
+{
+       void* kbuf = p ? kmalloc_errno(len) : buf;
+       if(kbuf == NULL)
+               return -1;
+       int ret = fe(pread,fd,PADDR(kbuf),len,offset);
+       if(ret != -1 && p && memcpy_to_user_errno(p,buf,kbuf,len))
+               ret = -1;
+       user_memdup_free(p,kbuf);
        return ret;
 }
 
@@ -130,20 +166,20 @@ intreg_t sys_open(struct proc* p, const char* path, int oflag, int mode)
        char* fn = user_strdup_errno(p,path,PGSIZE);
        if(fn == NULL)
                return -1;
-       int ret = fe(open,PADDR(fn),oflag,mode);
-       kfree(fn);
+       int ret = fe(open,PADDR(fn),oflag,mode,0);
+       user_memdup_free(p,fn);
        return ret;
 }
 intreg_t sys_close(struct proc* p, int fd)
 {
-       return fe(close,fd,0,0);
+       return fe(close,fd,0,0,0);
 }
 
 #define NEWLIB_STAT_SIZE 64
 intreg_t sys_fstat(struct proc* p, int fd, void* buf)
 {
        int kbuf[NEWLIB_STAT_SIZE/sizeof(int)];
-       int ret = fe(fstat,fd,PADDR(kbuf),0);
+       int ret = fe(fstat,fd,PADDR(kbuf),0,0);
        if(ret != -1 && memcpy_to_user_errno(p,buf,kbuf,NEWLIB_STAT_SIZE))
                ret = -1;
        return ret;
@@ -156,11 +192,11 @@ intreg_t sys_stat(struct proc* p, const char* path, void* buf)
        if(fn == NULL)
                return -1;
 
-       int ret = fe(stat,PADDR(fn),PADDR(kbuf),0);
+       int ret = fe(stat,PADDR(fn),PADDR(kbuf),0,0);
        if(ret != -1 && memcpy_to_user_errno(p,buf,kbuf,NEWLIB_STAT_SIZE))
                ret = -1;
 
-       kfree(fn);
+       user_memdup_free(p,fn);
        return ret;
 }
 
@@ -171,17 +207,17 @@ intreg_t sys_lstat(struct proc* p, const char* path, void* buf)
        if(fn == NULL)
                return -1;
 
-       int ret = fe(lstat,PADDR(fn),PADDR(kbuf),0);
+       int ret = fe(lstat,PADDR(fn),PADDR(kbuf),0,0);
        if(ret != -1 && memcpy_to_user_errno(p,buf,kbuf,NEWLIB_STAT_SIZE))
                ret = -1;
 
-       kfree(fn);
+       user_memdup_free(p,fn);
        return ret;
 }
 
 intreg_t sys_fcntl(struct proc* p, int fd, int cmd, int arg)
 {
-       return fe(fcntl,fd,cmd,arg);
+       return fe(fcntl,fd,cmd,arg,0);
 }
 
 intreg_t sys_access(struct proc* p, const char* path, int type)
@@ -189,14 +225,14 @@ intreg_t sys_access(struct proc* p, const char* path, int type)
        char* fn = user_strdup_errno(p,path,PGSIZE);
        if(fn == NULL)
                return -1;
-       int ret = fe(access,PADDR(fn),type,0);
-       kfree(fn);
+       int ret = fe(access,PADDR(fn),type,0,0);
+       user_memdup_free(p,fn);
        return ret;
 }
 
 intreg_t sys_umask(struct proc* p, int mask)
 {
-       return fe(umask,mask,0,0);
+       return fe(umask,mask,0,0,0);
 }
 
 intreg_t sys_chmod(struct proc* p, const char* path, int mode)
@@ -204,14 +240,14 @@ intreg_t sys_chmod(struct proc* p, const char* path, int mode)
        char* fn = user_strdup_errno(p,path,PGSIZE);
        if(fn == NULL)
                return -1;
-       int ret = fe(chmod,PADDR(fn),mode,0);
-       kfree(fn);
+       int ret = fe(chmod,PADDR(fn),mode,0,0);
+       user_memdup_free(p,fn);
        return ret;
 }
 
 intreg_t sys_lseek(struct proc* p, int fd, int offset, int whence)
 {
-       return fe(lseek,fd,offset,whence);
+       return fe(lseek,fd,offset,whence,0);
 }
 
 intreg_t sys_link(struct proc* p, const char* _old, const char* _new)
@@ -223,13 +259,13 @@ intreg_t sys_link(struct proc* p, const char* _old, const char* _new)
        char* newpath = user_strdup_errno(p,_new,PGSIZE);
        if(newpath == NULL)
        {
-               kfree(oldpath);
+               user_memdup_free(p,oldpath);
                return -1;
        }
 
-       int ret = fe(link,PADDR(oldpath),PADDR(newpath),0);
-       kfree(oldpath);
-       kfree(newpath);
+       int ret = fe(link,PADDR(oldpath),PADDR(newpath),0,0);
+       user_memdup_free(p,oldpath);
+       user_memdup_free(p,newpath);
        return ret;
 }
 
@@ -238,8 +274,8 @@ intreg_t sys_unlink(struct proc* p, const char* path)
        char* fn = user_strdup_errno(p,path,PGSIZE);
        if(fn == NULL)
                return -1;
-       int ret = fe(unlink,PADDR(fn),0,0);
-       kfree(fn);
+       int ret = fe(unlink,PADDR(fn),0,0,0);
+       user_memdup_free(p,fn);
        return ret;
 }
 
@@ -248,20 +284,20 @@ intreg_t sys_chdir(struct proc* p, const char* path)
        char* fn = user_strdup_errno(p,path,PGSIZE);
        if(fn == NULL)
                return -1;
-       int ret = fe(chdir,PADDR(fn),0,0);
-       kfree(fn);
+       int ret = fe(chdir,PADDR(fn),0,0,0);
+       user_memdup_free(p,fn);
        return ret;
 }
 
 intreg_t sys_getcwd(struct proc* p, char* pwd, int size)
 {
-       void* kbuf = kmalloc_errno(size);
+       void* kbuf = p ? kmalloc_errno(size) : pwd;
        if(kbuf == NULL)
                return -1;
-       int ret = fe(read,PADDR(kbuf),size,0);
-       if(ret != -1 && memcpy_to_user_errno(p,pwd,kbuf,strnlen(kbuf,size)))
+       int ret = fe(read,PADDR(kbuf),size,0,0);
+       if(ret != -1 && p && memcpy_to_user_errno(p,pwd,kbuf,strnlen(kbuf,size)))
                ret = -1;
-       kfree(kbuf);
+       user_memdup_free(p,kbuf);
        return ret;
 }
 
@@ -272,7 +308,7 @@ intreg_t sys_gettimeofday(struct proc* p, int* buf)
 
        spin_lock(&gtod_lock);
        if(t0 == 0)
-               t0 = fe(time,0,0,0);
+               t0 = fe(time,0,0,0,0);
        spin_unlock(&gtod_lock);
 
        long long dt = read_tsc();
index 4bc9130..59edef5 100644 (file)
 #define ROS_INCLUDE_MMAN_H
 
 /* Memory protection states (what you're allowed to do */
-#define PROT_NONE              0x1
-#define PROT_EXEC              0x2
 #define PROT_READ              0x4
-#define PROT_WRITE             0x8
+#define PROT_WRITE             0x2
+#define PROT_EXEC              0x1
+#define PROT_NONE              0x0
+#define PROT_UNMAP             0x100
 
 /* mmap flags, only anonymous is supported now, feel free to pass others */
-#define MAP_SHARED             0x001
-#define MAP_PRIVATE            0x002
-#define MAP_ANONYMOUS  0x004
-#define MAP_FIXED              0x008
-#define MAP_GROWSDOWN  0x010
-#define MAP_STACK              0x020
-#define MAP_POPULATE   0x040
-#define MAP_NONBLOCK   0x080
-#define MAP_NORESERVE  0x100
+#define MAP_SHARED             0x010
+#define MAP_PRIVATE            0x000
+#define MAP_ANONYMOUS  0x002
+#define MAP_FIXED              0x100
+//#define MAP_GROWSDOWN        0x010
+//#define MAP_STACK            0x020
+//#define MAP_POPULATE 0x040
+//#define MAP_NONBLOCK 0x080
+//#define MAP_NORESERVE        0x100
 
 /* Other mmap flags, which we probably won't support
 #define MAP_32BIT
index 220a087..29bfbad 100644 (file)
@@ -24,8 +24,6 @@
 #define SYS_shared_page_alloc          20
 #define SYS_shared_page_free           21
 /*
-#define SYS_mprotect
-#define SYS_mremap
 #define SYS_mincore // can read page tables instead
 #define SYS_madvise
 #define SYS_mlock
@@ -38,6 +36,8 @@
 #define SYS_eth_read                           25
 #define SYS_eth_write                          26
 #define SYS_frontend                           27
+#define SYS_mprotect                           28
+#define SYS_munmap                                     29
 
 #define SYS_read                               100
 #define SYS_write                              101
index 8bba761..1b7c1e5 100644 (file)
@@ -19,6 +19,8 @@ intreg_t process_generic_syscalls(env_t* e, size_t max);
 
 intreg_t sys_read(struct proc* p, int fd, void* buf, int len);
 intreg_t sys_write(struct proc* p, int fd, const void* buf, int len);
+intreg_t sys_pread(struct proc* p, int fd, void* buf, int len, int offset);
+intreg_t sys_pwrite(struct proc* p, int fd, const void* buf, int len, int offset);
 intreg_t sys_open(struct proc* p, const char* path, int oflag, int mode);
 intreg_t sys_close(struct proc* p, int fd);
 intreg_t sys_fstat(struct proc* p, int fd, void* buf);
@@ -34,5 +36,7 @@ intreg_t sys_unlink(struct proc* p, const char* path);
 intreg_t sys_chdir(struct proc* p, const char* path);
 intreg_t sys_getcwd(struct proc* p, char* pwd, int size);
 intreg_t sys_gettimeofday(struct proc* p, int* buf);
+intreg_t sys_mprotect(struct proc* p, void* addr, size_t len, int prot);
+intreg_t sys_munmap(struct proc* p, void* addr, size_t len);
 
 #endif /* !ROS_KERN_SYSCALL_H */
index b01eb24..4fb2f07 100644 (file)
@@ -85,7 +85,7 @@ WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_procdata)
                goto env_setup_vm_error_d;
        for (int i = 0; i < PROCINFO_NUM_PAGES; i++) {
                if (page_insert(e->env_pgdir, kva2page((void*)e->env_procinfo + i *
-                               PGSIZE), (void*SNT)(UINFO + i*PGSIZE), PTE_USER_RO) < 0)
+                               PGSIZE), (void*SNT)(UINFO + i*PGSIZE), PTE_USER_RW) < 0)
                        goto env_setup_vm_error;
        }
        for (int i = 0; i < PROCDATA_NUM_PAGES; i++) {
index cbda5b6..f5c0fb3 100644 (file)
 #include <mm.h>
 #include <process.h>
 #include <stdio.h>
+#include <syscall.h>
 
-/* mmap2() semantics on the offset (num pages, not bytes) */
 void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
            int fd, size_t offset)
 {
-       if (fd || offset) {
+       printd("mmap(addr %x, len %x, prot %x, flags %x, fd %x, off %x)\n",addr,len,prot,flags,fd,offset);
+       if (flags & MAP_SHARED) {
+               printk("[kernel] mmap() for files requires !MAP_SHARED.\n");
+               return (void*)-1;
+       }
+
+       /*if (fd || offset) {
                printk("[kernel] mmap() does not support files yet.\n");
                return (void*SAFE)TC(-1);
-       }
+       }*/
        /* TODO: make this work, instead of a ghetto hack
         * Find a valid range, make sure it doesn't run into the kernel
         * make sure there's enough memory (not exceeding quotas)
@@ -27,13 +33,16 @@ void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
         * return appropriate pointer
         * Right now, all we can do is give them the range they ask for.
         */
-       if (!addr)
+       if (!(flags & MAP_FIXED))
+       {
+               addr = MIN(addr,UMMAP_START);
                addr = (uintptr_t)get_free_va_range(p->env_pgdir,UMMAP_START,len);
-       // brief sanity check.  must be page aligned and not reaching too high
-       if (PGOFF(addr)) {
+       }
+       else if(PGOFF(addr)) { // MAP_FIXED with unaligned address
                printk("[kernel] mmap() page align your addr.\n");
                return (void*SAFE)TC(-1);
        }
+
        int num_pages = ROUNDUP(len, PGSIZE) / PGSIZE;
        pte_t *a_pte;
        // TODO: grab the appropriate mm_lock
@@ -42,8 +51,8 @@ void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
        // TODO: can probably do this better with vm_regions.
        // can also consider not mapping to 0x00000000
        for (int i = 0; i < num_pages; i++) {
-               a_pte = pgdir_walk(p->env_pgdir, (void*SNT)addr, 0);
-               if (a_pte && *a_pte & PTE_P)
+               a_pte = pgdir_walk(p->env_pgdir, (void*SNT)(addr + i*PGSIZE), 0);
+               if (!(flags & MAP_FIXED) && a_pte && *a_pte & PTE_P)
                        goto mmap_abort;
                if (addr + i*PGSIZE >= USTACKBOT)
                        goto mmap_abort;
@@ -52,13 +61,24 @@ void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
        for (int i = 0; i < num_pages; i++) {
                if (upage_alloc(p, &a_page, 1))
                        goto mmap_abort;
-               // TODO: give them the permissions they actually want
-               if (page_insert(p->env_pgdir, a_page, (void*SNT)addr + i*PGSIZE,
-                               PTE_USER_RW)) {
+               // TODO: TLB shootdown if replacing an old mapping
+               if (page_insert(p->env_pgdir, a_page, (void*SNT)(addr + i*PGSIZE),
+                               1||(prot & PROT_WRITE) ? PTE_USER_RW : PTE_USER_RO)) {
                        page_free(a_page);
                        goto mmap_abort;
                }
        }
+
+       // This is dumb--should not read until faulted in.
+       // This is just to get it correct at first
+       if(fd >= 0)
+       {
+               char buf[PGSIZE];
+               int ret = sys_pread(p,fd,(void*)addr,len,offset);
+               if(ret == -1)
+                       goto mmap_abort;
+       }
+
        // TODO: release the appropriate mm_lock
        spin_unlock_irqsave(&p->proc_lock);
        return (void*SAFE)TC(addr);
@@ -70,7 +90,57 @@ void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
                // TODO: release the appropriate mm_lock
                spin_unlock_irqsave(&p->proc_lock);
                // not a kernel problem, like if they ask to mmap a mapped location.
-               printd("[kernel] mmap() aborted!\n");
+               printk("[kernel] mmap() aborted!\n");
                // mmap's semantics.  we need a better error propagation system
                return (void*SAFE)TC(-1); // this is also ridiculous
 }
+
+intreg_t sys_mprotect(struct proc* p, void* addr, size_t len, int prot)
+{
+       printd("mprotect(addr %x, len %x, prot %x)\n",addr,len,prot);
+       if((intptr_t)addr % PGSIZE || (len == 0 && (prot & PROT_UNMAP)))
+       {
+               set_errno(current_tf,EINVAL);
+               return -1;
+       }
+
+       char* end = ROUNDUP((char*)addr+len,PGSIZE);
+       if(addr >= (void*)UTOP || end >= (char*)UTOP)
+       {
+               set_errno(current_tf, (prot & PROT_UNMAP) ? EINVAL : ENOMEM);
+               return -1;
+       }
+
+       int newperm = (prot & PROT_WRITE) ? PTE_USER_RW :
+                     (prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : 0;
+
+       for(char* a = (char*)addr; a < end; a += PGSIZE)
+       {
+               pte_t* pte = pgdir_walk(p->env_pgdir,a,0);
+               if(pte && *pte & PTE_P)
+               {
+                       if(prot & PROT_UNMAP)
+                       {
+                               page_t* page = ppn2page(PTE2PPN(*pte));
+                               *pte = 0;
+                               page_decref(page);
+                       }
+                       else
+                               *pte = (*pte & ~PTE_PERM) | newperm;
+               }
+               else
+               {
+                       set_errno(current_tf,ENOMEM);
+                       return -1;
+               }
+       }
+
+       //TODO: TLB shootdown
+       tlbflush();
+       return 0;
+}
+
+intreg_t sys_munmap(struct proc* p, void* addr, size_t len)
+{
+       return sys_mprotect(p,addr,len,PROT_UNMAP);
+}
index ca4306c..f529474 100644 (file)
@@ -33,7 +33,7 @@ void colored_page_alloc_init()
        global_cache_colors_map = 
               kmalloc(BYTES_FOR_BITMASK(llc_cache->num_colors), 0);
        CLR_BITMASK(global_cache_colors_map, llc_cache->num_colors);
-       for(int i = 0; i < llc_cache->num_colors/2; i++)
+       for(int i = 0; i < llc_cache->num_colors/8; i++)
                cache_color_alloc(llc_cache, global_cache_colors_map);
 }
 
index b1cdeaa..dc68230 100644 (file)
@@ -664,6 +664,8 @@ intreg_t syscall(struct proc *p, uintreg_t syscallno, uintreg_t a1,
                [SYS_exec] = (syscall_t)sys_exec,
                [SYS_trywait] = (syscall_t)sys_trywait,
                [SYS_mmap] = (syscall_t)sys_mmap,
+               [SYS_munmap] = (syscall_t)sys_munmap,
+               [SYS_mprotect] = (syscall_t)sys_mprotect,
                [SYS_brk] = (syscall_t)sys_brk,
                [SYS_shared_page_alloc] = (syscall_t)sys_shared_page_alloc,
                [SYS_shared_page_free] = (syscall_t)sys_shared_page_free,