diff --git a/src/userprog/exception.c b/src/userprog/exception.c index 39a8173..0edf38e 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -156,49 +156,42 @@ page_fault (struct intr_frame *f) user = (f->error_code & PF_U) != 0; #ifdef VM - struct thread *t = thread_current (); void *upage = pg_round_down (fault_addr); - - /* If the fault address is in a user page that is not present, then it might - be an executable file page that needs to be lazily loaded. So, we check the - SPT to determine if this is the case, and if so load the page from disk. */ - if (not_present && is_user_vaddr (upage)) + if (not_present && is_user_vaddr(upage)) { + struct thread *t = thread_current (); + void *esp = user ? f->esp : t->curr_esp; + + /* Check if the non-present user page is in the swap partition. + If so, swap it back into main memory, updating the PTE for + the faulted virtual address to point to the newly allocated + frame. */ + if (page_in_swap (t, fault_addr)) + { + size_t swap_slot = page_get_swap (t, fault_addr); + void *kpage = frame_alloc (0, upage, t); + swap_in (kpage, swap_slot); + + bool writeable = pagedir_is_writable (t->pagedir, upage); + if (pagedir_set_page (t->pagedir, upage, kpage, writeable)) return; + } + + /* Handle user page faults that need to be resolved by dynamic + stack growth by checking if this is such a fault and responding + accordingly. */ + if (handle_stack_fault (fault_addr, esp)) return; + + /* Handle user page faults that need to be resolved by lazy loading + of executable files by checking if they contain entries in the + SPT hash map and responding accordingly. */ if (try_fetch_page (upage, write)) return; } - if (user) + /* Allows for page faults within a kernel context to communicate with + user pages for sending error codes. */ + if (!user) { - if (not_present) - { - /* Check if the non-present user page is in the swap partition. - If so, swap it back into main memory, updating the PTE for - the faulted virtual address to point to the newly allocated - frame. */ - if (page_in_swap (t, fault_addr)) - { - size_t swap_slot = page_get_swap (t, fault_addr); - void *kpage = frame_alloc (0, upage, t); - swap_in (kpage, swap_slot); - - bool writeable = pagedir_is_writable (t->pagedir, upage); - if (pagedir_set_page (t->pagedir, upage, kpage, writeable)) return; - } - - /* Handle user page faults that need to be resolved by dynamic - stack growth by checking if this is such a fault and responding - accordingly. */ - if (handle_stack_fault (fault_addr, f->esp)) return; - } - } - else - { - /* Handle kernel page faults that need to be resolved by dynamic stack - growth by checking if this is such a fault and responding - accordingly. */ - if (not_present && handle_stack_fault (fault_addr, t->curr_esp)) return; - f->eip = (void *)f->eax; f->eax = 0xffffffff; return;