summaryrefslogtreecommitdiffstats
path: root/userprog/exception.c
diff options
context:
space:
mode:
Diffstat (limited to 'userprog/exception.c')
-rw-r--r--userprog/exception.c80
1 files changed, 51 insertions, 29 deletions
diff --git a/userprog/exception.c b/userprog/exception.c
index 54621fa..debe7f0 100644
--- a/userprog/exception.c
+++ b/userprog/exception.c
@@ -2,6 +2,8 @@
2#include <inttypes.h> 2#include <inttypes.h>
3#include <stdio.h> 3#include <stdio.h>
4#include "userprog/gdt.h" 4#include "userprog/gdt.h"
5#include "userprog/process.h"
6#include "userprog/syscall.h"
5#include "threads/interrupt.h" 7#include "threads/interrupt.h"
6#include "threads/thread.h" 8#include "threads/thread.h"
7#include "threads/vaddr.h" 9#include "threads/vaddr.h"
@@ -128,7 +130,8 @@ page_fault (struct intr_frame *f)
128 bool write; /* True: access was write, false: access was read. */ 130 bool write; /* True: access was write, false: access was read. */
129 bool user; /* True: access by user, false: access by kernel. */ 131 bool user; /* True: access by user, false: access by kernel. */
130 void *fault_addr; /* Fault address. */ 132 void *fault_addr; /* Fault address. */
131 struct page_table_entry *pte; 133 void *sp; /* Stack pointer. */
134 struct page_table_entry *pte; /* Page table entry. */
132 135
133 /* Obtain faulting address, the virtual address that was 136 /* Obtain faulting address, the virtual address that was
134 accessed to cause the fault. It may point to code or to 137 accessed to cause the fault. It may point to code or to
@@ -151,38 +154,57 @@ page_fault (struct intr_frame *f)
151 write = (f->error_code & PF_W) != 0; 154 write = (f->error_code & PF_W) != 0;
152 user = (f->error_code & PF_U) != 0; 155 user = (f->error_code & PF_U) != 0;
153 156
154 /* To implement virtual memory, adapt the rest of the function 157 /* accessing r/o page is always wrong */
155 body, adding code that brings in the page to 158 if (!not_present)
156 which fault_addr refers. */ 159 thread_exit ();
157 if (is_user_vaddr(fault_addr)) { 160
158 pte = page_table_fetch (&thread_current ()->page_table, pg_round_down (fault_addr)); 161 if (is_user_vaddr (fault_addr))
159 if (pte != NULL)
160 page_load (pte);
161 else
162 { 162 {
163 printf ("Page fault %p\n", pte); 163 /* if page fault occurs during syscall, use saved stack pointer */
164 kill (f); 164 sp = (!user) ? syscall_sp : f->esp;
165 } 165
166 /* try to fetch page entry */
167 pte = page_table_fetch (&thread_current ()->page_table,
168 pg_round_down (fault_addr));
169
170 /* we got a page entry so try to load the page */
171 if (pte != NULL)
172 {
173 if (page_load (pte))
174 return;
175 printf ("Unable to load page at %p in %s context.\n",
176 fault_addr, user ? "user" : "kernel");
177 }
178 /* there's no page in our page table but we might still have an valid
179 stack access and need to expand our stack. so just check for that.
180 the maxium offset we consider as a valid access is caused by the PUSHA
181 instruction. it's 32 bytes below the current stack pointer */
182 else if (fault_addr >= (sp - 32) && (PHYS_BASE - fault_addr) <= STACK_SIZE)
183 {
184 if (process_grow_stack (pg_round_down (fault_addr)))
185 return;
186 printf ("Unable to grow stack %p in %s context.\n",
187 fault_addr, user ? "user" : "kernel");
188 }
166 189
167 //TODO
168#if 0
169 if (! user) {
170 /* syscall exception; set eax and eip */ 190 /* syscall exception; set eax and eip */
171 f->eip = (void*)f->eax; 191 if (!user)
172 f->eax = 0xFFFFFFFF; 192 {
173 return; 193 f->eip = (void*)f->eax;
174 } else { 194 f->eax = 0xFFFFFFFF;
195 return;
196 }
197
175 /* user process access violation */ 198 /* user process access violation */
176 thread_exit(); 199 thread_exit ();
200 return;
177 } 201 }
178#endif 202
179 } else { 203 printf ("Page fault at %p: %s error %s page in %s context.\n",
180 printf ("Page fault at %p: %s error %s page in %s context.\n", 204 fault_addr,
181 fault_addr, 205 not_present ? "not present" : "rights violation",
182 not_present ? "not present" : "rights violation", 206 write ? "writing" : "reading",
183 write ? "writing" : "reading", 207 user ? "user" : "kernel");
184 user ? "user" : "kernel"); 208 kill (f);
185 kill (f);
186 }
187} 209}
188 210