Provide handle_page_fault_nofile()
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 8 Dec 2015 19:44:58 +0000 (14:44 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 10 Dec 2015 16:26:39 +0000 (11:26 -0500)
This allows us to specify whether we want file operations (page cache,
mostly) when we handle a page fault or not.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/mm.h
kern/src/mm.c

index fd0df2c..ef70f99 100644 (file)
@@ -66,6 +66,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);
 int munmap(struct proc *p, uintptr_t addr, size_t len);
 int handle_page_fault(struct proc *p, uintptr_t va, int prot);
+int handle_page_fault_nofile(struct proc *p, uintptr_t va, int prot);
 unsigned long populate_va(struct proc *p, uintptr_t va, unsigned long nr_pgs);
 
 /* These assume the mm_lock is held already */
index 643e9f1..2ad0f7d 100644 (file)
@@ -934,7 +934,7 @@ static int __hpf_load_page(struct proc *p, struct page_map *pm,
  * shootdown is on its way.  Userspace should have waited for the mprotect to
  * return before trying to write (or whatever), so we don't care and will fault
  * them. */
-int handle_page_fault(struct proc *p, uintptr_t va, int prot)
+static int __hpf(struct proc *p, uintptr_t va, int prot, bool file_ok)
 {
        struct vm_region *vmr;
        struct page *a_page;
@@ -964,6 +964,8 @@ refault:
                        goto out;
                }
        } else {
+               if (!file_ok)
+                       return -EACCES;
                /* If this fails, either something got screwed up with the VMR, or the
                 * permissions changed after mmap/mprotect.  Either way, I want to know
                 * (though it's not critical). */
@@ -1035,6 +1037,16 @@ out:
        return ret;
 }
 
+int handle_page_fault(struct proc *p, uintptr_t va, int prot)
+{
+       return __hpf(p, va, prot, TRUE);
+}
+
+int handle_page_fault_nofile(struct proc *p, uintptr_t va, int prot)
+{
+       return __hpf(p, va, prot, FALSE);
+}
+
 /* Attempts to populate the pages, as if there was a page faults.  Bails on
  * errors, and returns the number of pages populated.  */
 unsigned long populate_va(struct proc *p, uintptr_t va, unsigned long nr_pgs)