Implement dynamic stack growth #54

Merged
td1223 merged 14 commits from ethan-stack-growth into virtual-memory 2024-11-30 23:21:34 +00:00
13 changed files with 185 additions and 415 deletions
Showing only changes of commit 5c661c2e24 - Show all commits

View File

@@ -143,9 +143,7 @@ struct thread
struct hash open_files; /* Hash Table of FD -> Struct File. */ struct hash open_files; /* Hash Table of FD -> Struct File. */
#endif #endif
#ifdef VM
void *curr_esp; void *curr_esp;
#endif
/* Owned by thread.c. */ /* Owned by thread.c. */
unsigned magic; /* Detects stack overflow. */ unsigned magic; /* Detects stack overflow. */

View File

@@ -1,7 +1,7 @@
# -*- makefile -*- # -*- makefile -*-
kernel.bin: DEFINES = -DUSERPROG -DFILESYS kernel.bin: DEFINES = -DUSERPROG -DFILESYS -DVM
KERNEL_SUBDIRS = threads devices lib lib/kernel userprog filesys KERNEL_SUBDIRS = threads devices lib lib/kernel userprog filesys vm
TEST_SUBDIRS = tests/userprog tests/userprog/no-vm tests/filesys/base TEST_SUBDIRS = tests/userprog tests/userprog/no-vm tests/filesys/base
GRADING_FILE = $(SRCDIR)/tests/userprog/Grading GRADING_FILE = $(SRCDIR)/tests/userprog/Grading
SIMULATOR = --qemu SIMULATOR = --qemu

View File

@@ -146,19 +146,19 @@ 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;
/* Kernel page fault is further handled by the kernel itself. */ if (user && not_present)
if (kernel)
{ {
f->eip = (void *)f->eax; if (try_alloc_new_page (fault_addr, f->esp))
return;
}
else
{
if (try_alloc_new_page (fault_addr, thread_current ()->curr_esp))
return;
f->eip = (void *)f->eax;
f->eax = 0xffffffff; f->eax = 0xffffffff;
return; return;
} }
if (user)
{
if (try_alloc_new_page (fault_addr, f->esp))
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

View File

@@ -10,9 +10,6 @@
#include "threads/synch.h" #include "threads/synch.h"
#include "userprog/process.h" #include "userprog/process.h"
#include "userprog/pagedir.h" #include "userprog/pagedir.h"
#ifdef VM
#include "vm/stackgrowth.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <syscall-nr.h> #include <syscall-nr.h>
@@ -465,17 +462,17 @@ validate_user_pointer (const void *ptr, size_t size, bool check_write)
valid user virtual memory address. */ valid user virtual memory address. */
void *last = ptr + size - 1; void *last = ptr + size - 1;
if (!is_user_vaddr (last)) if (!is_user_vaddr (last))
thread_exit (); syscall_exit (EXIT_FAILURE);
ptr = pg_round_down (ptr); ptr = pg_round_down (ptr);
while (ptr <= last) while (ptr <= last)
{ {
int result; int result;
/* Check read access to pointer. */ /* Check read access to pointer. */
if ((result = get_user (ptr)) == -1) if ((result = get_user (ptr)) == -1)
thread_exit (); syscall_exit (EXIT_FAILURE);
/* Check write access to pointer (if required). */ /* Check write access to pointer (if required). */
if (check_write && !put_user (ptr, result)) if (check_write && !put_user (ptr, result))
thread_exit (); syscall_exit (EXIT_FAILURE);
ptr += PGSIZE; ptr += PGSIZE;
} }
} }
@@ -485,18 +482,33 @@ validate_user_pointer (const void *ptr, size_t size, bool check_write)
static void static void
validate_user_string (const char *ptr, bool check_write) validate_user_string (const char *ptr, bool check_write)
{ {
while (true) size_t offset = (uintptr_t) ptr % PGSIZE;
for (;;)
{ {
void *page = pg_round_down (ptr);
if (!is_user_vaddr (page))
syscall_exit (EXIT_FAILURE);
if (!is_user_vaddr (ptr)) if (!is_user_vaddr (ptr))
thread_exit (); syscall_exit (EXIT_FAILURE);
int result; int result;
if ((result = get_user ((const uint8_t *)ptr)) == -1) if ((result = get_user ((const uint8_t *)ptr)) == -1)
thread_exit (); syscall_exit (EXIT_FAILURE);
if (check_write && !put_user ((uint8_t *)ptr, result)) if (check_write && !put_user ((uint8_t *)ptr, result))
thread_exit (); syscall_exit (EXIT_FAILURE);
if (*ptr == '\0')
return; while (offset < PGSIZE)
ptr++; {
if (*ptr == '\0')
return; /* We reached the end of the string without issues. */
ptr++;
offset++;
}
offset = 0;
} }
} }