Added arch framework for handling page faults
authorAndrew Waterman <waterman@ros-dev.(none)>
Fri, 26 Mar 2010 05:36:14 +0000 (22:36 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:37 +0000 (17:35 -0700)
Both ports call into a handle_page_fault routine accordingly

kern/arch/i686/trap.c
kern/arch/sparc/fpu.c
kern/arch/sparc/trap.c
kern/arch/sparc/trap.h
kern/arch/sparc/trap_table.S
kern/include/mm.h
kern/src/elf.c
kern/src/mm.c

index 667a4da..b0fb60e 100644 (file)
@@ -15,6 +15,7 @@
 #include <trap.h>
 #include <monitor.h>
 #include <process.h>
+#include <mm.h>
 #include <stdio.h>
 #include <slab.h>
 #include <syscall.h>
@@ -338,12 +339,16 @@ page_fault_handler(trapframe_t *tf)
 
        // LAB 4: Your code here.
 
-       // Destroy the environment that caused the fault.
-       cprintf("[%08x] user fault va %08x ip %08x from core %d\n",
-               current->pid, fault_va, tf->tf_eip, core_id());
-       print_trapframe(tf);
-       proc_incref(current, 1);
-       proc_destroy(current);
+       // TODO: compute correct access type
+       if(handle_page_fault(current,fault_va,PROT_READ))
+       {
+               // Destroy the environment that caused the fault.
+               cprintf("[%08x] user fault va %08x ip %08x from core %d\n",
+                       current->pid, fault_va, tf->tf_eip, core_id());
+               print_trapframe(tf);
+               proc_incref(current, 1);
+               proc_destroy(current);
+       }
 }
 
 void sysenter_init(void)
index 3d43108..cd95876 100644 (file)
@@ -17,7 +17,7 @@ void fp_access_exception(trapframe_t* state, void* addr)
 {
        state->fault_status = 1;
        state->fault_addr = (uint32_t)addr;
-       access_exception(state);
+       data_access_exception(state);
 }
 
 static inline uint32_t fp_load_word(trapframe_t* state, uint32_t* addr)
index d7e19e6..77725fb 100644 (file)
@@ -9,6 +9,8 @@
 #include <stdio.h>
 #include <smp.h>
 #include <slab.h>
+#include <mm.h>
+#include <ros/mman.h>
 
 #ifdef __SHARC__
 #pragma nosharc
@@ -209,9 +211,24 @@ address_unaligned(trapframe_t* state)
 }
 
 void
-access_exception(trapframe_t* state)
+instruction_access_exception(trapframe_t* state)
 {
-       unhandled_trap(state);
+       if(handle_page_fault(current,state->fault_addr,PROT_EXEC))
+               unhandled_trap(state);
+       else
+               env_pop_tf(state);
+}
+
+void
+data_access_exception(trapframe_t* state)
+{
+       int store = ((state->fault_status >> 5) & 7) > 4;
+       int prot = store ? PROT_WRITE : PROT_READ;
+
+       if(handle_page_fault(current,state->fault_addr,prot))
+               unhandled_trap(state);
+       else
+               env_pop_tf(state);
 }
 
 void
index 9575151..776599b 100644 (file)
@@ -30,7 +30,7 @@ typedef struct
        uint32_t fsr;
 } ancillary_state_t;
 
-void access_exception(trapframe_t* state);
+void data_access_exception(trapframe_t* state);
 void real_fp_exception(trapframe_t* state, ancillary_state_t* astate);
 void address_unaligned(trapframe_t* state);
 void illegal_instruction(trapframe_t* state);
index ce191a8..120f311 100644 (file)
@@ -6,7 +6,7 @@
 trap_table:
 
        UNHANDLED_TRAP                          ! 0x00
-       TRAP_TABLE_ENTRY(access_exception)      ! 0x01
+       TRAP_TABLE_ENTRY(instruction_access_exception)  ! 0x01
        TRAP_TABLE_ENTRY(illegal_instruction)   ! 0x02
        UNHANDLED_TRAP                          ! 0x03
        TRAP_TABLE_ENTRY(fp_disabled)           ! 0x04
@@ -17,7 +17,7 @@ trap_table:
 
        TRAP_TABLE_ENTRY(address_unaligned)     ! 0x07
        JMP(fast_fp_exception)                  ! 0x08
-       TRAP_TABLE_ENTRY(access_exception)      ! 0x09
+       TRAP_TABLE_ENTRY(data_access_exception) ! 0x09
        UNHANDLED_TRAP                          ! 0x0A
        UNHANDLED_TRAP                          ! 0x0B
        UNHANDLED_TRAP                          ! 0x0C
index fe0af2c..4043a19 100644 (file)
@@ -80,4 +80,6 @@ error_t open_file(struct proc* p, const char* fn, int flag, int mode);
 error_t close_file(struct proc* p, int fd);
 error_t read_page(struct proc* p, int fd, physaddr_t pa, int pgoff);
 
+int handle_page_fault(struct proc* p, uintptr_t va, int prot);
+
 #endif // !ROS_KERN_MM_H
index e2d33f7..8cfe5e2 100644 (file)
@@ -1,4 +1,5 @@
 #include <mm.h>
+#include <frontend.h>
 #include <string.h>
 #include <ros/mman.h>
 #include <kmalloc.h>
index e496e85..eab9b5e 100644 (file)
@@ -5,6 +5,7 @@
  *
  */
 
+#include <frontend.h>
 #include <ros/common.h>
 #include <ros/mman.h>
 #include <pmap.h>
@@ -108,12 +109,14 @@ int mprotect(struct proc* p, void* addr, size_t len, int prot)
 
        // overflow of end is handled in the for loop's parameters
        char* end = ROUNDUP((char*)addr+len,PGSIZE);
-       if(addr >= (void*)UTOP || end >= (char*)UTOP)
+       if(addr >= (void*)UTOP || end > (char*)UTOP)
        {
                set_errno(current_tf, (prot & PROT_UNMAP) ? EINVAL : ENOMEM);
                return -1;
        }
 
+       spin_lock_irqsave(&p->proc_lock);
+
        int newperm = (prot & PROT_WRITE) ? PTE_USER_RW :
                      (prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : 0;
 
@@ -139,6 +142,8 @@ int mprotect(struct proc* p, void* addr, size_t len, int prot)
                }
        }
 
+       spin_unlock_irqsave(&p->proc_lock);
+
        //TODO: TLB shootdown - needs to be process wide
        tlbflush();
        return 0;
@@ -148,3 +153,17 @@ int munmap(struct proc* p, void* addr, size_t len)
 {
        return mprotect(p, addr, len, PROT_UNMAP);
 }
+
+int handle_page_fault(struct proc* p, uintptr_t va, int prot)
+{
+       int ret = -1;
+       va = ROUNDDOWN(va,PGSIZE);
+
+       spin_lock_irqsave(&p->proc_lock);
+
+
+out:
+       spin_unlock_irqsave(&p->proc_lock);
+       return ret;
+}
+