Refactor stack growth #57

Merged
sb3923 merged 17 commits from vm/stack-growth/saleh into vm/virtual-memory/saleh 2024-12-05 00:53:35 +00:00
8 changed files with 62 additions and 189 deletions
Showing only changes of commit 3ef5264b6e - Show all commits

View File

@@ -63,6 +63,7 @@ userprog_SRC += userprog/tss.c # TSS management.
# Virtual memory code. # Virtual memory code.
vm_SRC += devices/swap.c # Swap block manager. vm_SRC += devices/swap.c # Swap block manager.
vm_SRC += vm/stackgrowth.c
#vm_SRC = vm/file.c # Some other file. #vm_SRC = vm/file.c # Some other file.
# Filesystem code. # Filesystem code.

View File

@@ -4,6 +4,7 @@
#include "userprog/gdt.h" #include "userprog/gdt.h"
#include "threads/interrupt.h" #include "threads/interrupt.h"
#include "threads/thread.h" #include "threads/thread.h"
#include "vm/stackgrowth.h"
/* Number of page faults processed. */ /* Number of page faults processed. */
static long long page_fault_cnt; static long long page_fault_cnt;
@@ -145,6 +146,12 @@ page_fault (struct intr_frame *f)
write = (f->error_code & PF_W) != 0; write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 0; user = (f->error_code & PF_U) != 0;
if (user && needs_new_page (fault_addr, f->esp))
{
if (grow_stack (fault_addr))
return;
}
/* To implement virtual memory, delete the rest of the function /* To implement virtual memory, delete the rest of the function
body, and replace it with code that brings in the page to body, and replace it with code that brings in the page to
which fault_addr refers. */ which fault_addr refers. */

38
src/vm/stackgrowth.c Normal file
View File

@@ -0,0 +1,38 @@
#include <stdio.h>
#include "stackgrowth.h"
#include "threads/palloc.h"
#include "threads/thread.h"
#include "threads/vaddr.h"
#include "userprog/pagedir.h"
/* Validates a given address for being <=32 bytes away from the stack pointer or
above the stack */
bool needs_new_page (void *addr, void *esp)
{
return (is_user_vaddr (addr) &&
(uint32_t*)addr >= ((uint32_t*)esp - 32) &&
((PHYS_BASE - pg_round_down (addr))
<= MAX_STACK_SIZE));
}
/* Extends the stack by the necessary number of pages */
bool grow_stack (void *addr)
{
struct thread *t = thread_current ();
void *last_page = pg_round_down (addr);
uint8_t *new_page = palloc_get_page (PAL_USER | PAL_ZERO);
if ( new_page == NULL)
return false;
bool added_page = pagedir_get_page (t->pagedir, last_page) == NULL
&& pagedir_set_page (t->pagedir, last_page, new_page, true);
if (!added_page) {
palloc_free_page (new_page);
return false;
}
return true;
}

11
src/vm/stackgrowth.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef GROWSTACK_H
#define GROWSTACK_H
#include <stdio.h>
#define MAX_STACK_SIZE 8388608 // (8MB)
bool needs_new_page (void *addr, void *esp);
bool grow_stack (void *addr);
#endif //GROWSTACK_H