Fixes bug with mprotect() and munmap()
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 17 Aug 2010 08:14:39 +0000 (01:14 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:52 +0000 (17:35 -0700)
This was hidden by the lack of TLB shootdowns (the old TLB entry was
being used still, so the faulty/extra mprotects weren't taking effect.

kern/arch/i686/trap.c
kern/src/mm.c

index b044469..6103eda 100644 (file)
@@ -305,16 +305,18 @@ void page_fault_handler(struct trapframe *tf)
 {
        uint32_t fault_va = rcr2();
        int prot = tf->tf_err & PF_ERROR_WRITE ? PROT_WRITE : PROT_READ;
+       int err;
 
        /* TODO - handle kernel page faults */
        if ((tf->tf_cs & 3) == 0) {
                print_trapframe(tf);
                panic("Page Fault in the Kernel at 0x%08x!", fault_va);
        }
-       if (handle_page_fault(current, fault_va, prot)) {
+       if ((err = handle_page_fault(current, fault_va, prot))) {
                /* Destroy the faulting process */
-               printk("[%08x] user fault va %08x ip %08x from core %d\n",
-                      current->pid, fault_va, tf->tf_eip, core_id());
+               printk("[%08x] user %s fault va %08x ip %08x on core %d with err %d\n",
+                      current->pid, prot & PROT_READ ? "READ" : "WRITE", fault_va,
+                      tf->tf_eip, core_id(), err);
                print_trapframe(tf);
                kref_get(&current->kref, 1);
                proc_destroy(current);
index 6248797..3e2f63c 100644 (file)
@@ -379,7 +379,7 @@ void *__do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
 
 int mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
 {
-       printd("mprotect(addr %x, len %x, prot %x)\n", addr, len, prot);
+       printd("mprotect: (addr %08p, len %08p, prot %08p)\n", addr, len, prot);
        if (!len)
                return 0;
        if ((addr % PGSIZE) || (addr < MMAP_LOWEST_VA)) {
@@ -410,7 +410,7 @@ int __do_mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
        /* TODO: this is aggressively splitting, when we might not need to if the
         * prots are the same as the previous.  Plus, there are three excessive
         * scans.  Finally, we might be able to merge when we are done. */
-       isolate_vmrs(p, addr, addr + len);
+       isolate_vmrs(p, addr, len);
        vmr = find_first_vmr(p, addr);
        while (vmr && vmr->vm_base < addr + len) {
                if (vmr->vm_prot == prot)
@@ -492,7 +492,7 @@ int __do_munmap(struct proc *p, uintptr_t addr, size_t len)
 
        /* TODO: this will be a bit slow, since we end up doing three linear
         * searches (two in isolate, one in find_first). */
-       isolate_vmrs(p, addr, addr + len);
+       isolate_vmrs(p, addr, len);
        vmr = find_first_vmr(p, addr);
        while (vmr && vmr->vm_base < addr + len) {
                for (uintptr_t va = vmr->vm_base; va < vmr->vm_end; va += PGSIZE) {