diff --git a/src/threads/thread.h b/src/threads/thread.h index 60f91ce..f031981 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -143,9 +143,7 @@ struct thread struct hash open_files; /* Hash Table of FD -> Struct File. */ #endif -#ifdef VM void *curr_esp; -#endif /* Owned by thread.c. */ unsigned magic; /* Detects stack overflow. */ diff --git a/src/userprog/Make.vars b/src/userprog/Make.vars index e4dbb08..23bae3d 100644 --- a/src/userprog/Make.vars +++ b/src/userprog/Make.vars @@ -1,7 +1,7 @@ # -*- makefile -*- -kernel.bin: DEFINES = -DUSERPROG -DFILESYS -KERNEL_SUBDIRS = threads devices lib lib/kernel userprog filesys +kernel.bin: DEFINES = -DUSERPROG -DFILESYS -DVM +KERNEL_SUBDIRS = threads devices lib lib/kernel userprog filesys vm TEST_SUBDIRS = tests/userprog tests/userprog/no-vm tests/filesys/base GRADING_FILE = $(SRCDIR)/tests/userprog/Grading SIMULATOR = --qemu diff --git a/src/userprog/exception.c b/src/userprog/exception.c index 3e3b133..1fcbe61 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -146,19 +146,19 @@ page_fault (struct intr_frame *f) write = (f->error_code & PF_W) != 0; user = (f->error_code & PF_U) != 0; - /* Kernel page fault is further handled by the kernel itself. */ - if (kernel) + if (user && not_present) { - 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; return; - } - - if (user) - { - if (try_alloc_new_page (fault_addr, f->esp)) - return; - } + } /* To implement virtual memory, delete the rest of the function body, and replace it with code that brings in the page to diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index da6d77d..4bc34ca 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -10,9 +10,6 @@ #include "threads/synch.h" #include "userprog/process.h" #include "userprog/pagedir.h" -#ifdef VM -#include "vm/stackgrowth.h" -#endif #include #include #include @@ -465,17 +462,17 @@ validate_user_pointer (const void *ptr, size_t size, bool check_write) valid user virtual memory address. */ void *last = ptr + size - 1; if (!is_user_vaddr (last)) - thread_exit (); + syscall_exit (EXIT_FAILURE); ptr = pg_round_down (ptr); while (ptr <= last) { int result; /* Check read access to pointer. */ if ((result = get_user (ptr)) == -1) - thread_exit (); + syscall_exit (EXIT_FAILURE); /* Check write access to pointer (if required). */ if (check_write && !put_user (ptr, result)) - thread_exit (); + syscall_exit (EXIT_FAILURE); ptr += PGSIZE; } } @@ -485,18 +482,33 @@ validate_user_pointer (const void *ptr, size_t size, bool check_write) static void 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)) - thread_exit (); + syscall_exit (EXIT_FAILURE); int result; if ((result = get_user ((const uint8_t *)ptr)) == -1) - thread_exit (); + syscall_exit (EXIT_FAILURE); if (check_write && !put_user ((uint8_t *)ptr, result)) - thread_exit (); - if (*ptr == '\0') - return; - ptr++; + syscall_exit (EXIT_FAILURE); + + while (offset < PGSIZE) + { + if (*ptr == '\0') + return; /* We reached the end of the string without issues. */ + + ptr++; + offset++; + } + + offset = 0; + } }