Fix Bug: Grow stack if necessary in case of a page fault in the kernel context
This commit is contained in:
@@ -157,30 +157,33 @@ page_fault (struct intr_frame *f)
|
||||
write = (f->error_code & PF_W) != 0;
|
||||
user = (f->error_code & PF_U) != 0;
|
||||
|
||||
if (!user || !not_present)
|
||||
/* Select the appropriate stack pointer based on the context of the fault. */
|
||||
void *esp = user ? f->esp : thread_current()->curr_esp;
|
||||
|
||||
/* If the fault address is in a user page that is not present, then it might
|
||||
be just that the stack needs to grow or that it needs to be lazily loaded.
|
||||
So we attempt to grow the stack. If this does not work, we check our SPT to
|
||||
see if the page is expected to have data loaded in memory. */
|
||||
void *upage = pg_round_down (fault_addr);
|
||||
if (not_present && is_user_vaddr (upage) && upage != NULL)
|
||||
{
|
||||
if (is_valid_stack_access (fault_addr, esp))
|
||||
if (grow_stack (upage))
|
||||
return;
|
||||
|
||||
if (try_fetch_page (upage, write))
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the page fault occurred in kernel mode, then we intentionally indicate
|
||||
a fault (for get_user() etc). */
|
||||
if (!user)
|
||||
{
|
||||
f->eip = (void *)f->eax;
|
||||
f->eax = 0xffffffff;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the fault address is in a user page that is not present, then it might
|
||||
be just that the stack needs to grow or that it needs to be lazily loaded.
|
||||
So we attempt to grow the stack. If this does not work, we check our SPT to see if the page
|
||||
is expected to have data loaded in memory. */
|
||||
void *upage = pg_round_down (fault_addr);
|
||||
if (not_present && is_user_vaddr (upage) && upage != NULL)
|
||||
{
|
||||
if (is_valid_stack_access (fault_addr, f->esp))
|
||||
{
|
||||
if (grow_stack (upage))
|
||||
return;
|
||||
}
|
||||
|
||||
if (try_fetch_page (upage, write))
|
||||
return;
|
||||
}
|
||||
|
||||
/* To implement virtual memory, delete the rest of the function
|
||||
body, and replace it with code that brings in the page to
|
||||
which fault_addr refers. */
|
||||
|
||||
Reference in New Issue
Block a user