Implement VM #63

Merged
td1223 merged 94 commits from vm/merged/themis into master 2024-12-06 05:07:14 +00:00
12 changed files with 101 additions and 356 deletions
Showing only changes of commit c74a8c55aa - Show all commits

View File

@@ -143,6 +143,10 @@ 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. */
};

View File

@@ -10,6 +10,9 @@
#include "threads/synch.h"
#include "userprog/process.h"
#include "userprog/pagedir.h"
#ifdef VM
#include "vm/stackgrowth.h"
#endif
#include <stdio.h>
#include <syscall-nr.h>
@@ -98,6 +101,7 @@ syscall_handler (struct intr_frame *f)
/* First, read the system call number from the stack. */
validate_user_pointer (f->esp, sizeof (uintptr_t));
uintptr_t syscall_number = *(int *) f->esp;
thread_current ()->curr_esp = f->esp;
/* Ensures the number corresponds to a system call that can be handled. */
if (syscall_number >= LOOKUP_SIZE)
@@ -451,6 +455,20 @@ fd_get_file (int fd)
return hash_entry (e, struct open_file, elem);
}
static bool
try_alloc_new_page (const void *ptr)
{
if (needs_new_page (ptr, thread_current()->curr_esp))
{
if (!grow_stack (ptr))
return 0;
else
return 1;
}
else
return 0;
}
/* Validates if a block of memory starting at START and of size SIZE bytes is
fully contained within user virtual memory. Kills the thread (by exiting with
failure) if the memory is invalid. Otherwise, returns (nothing) normally.
@@ -472,7 +490,10 @@ validate_user_pointer (const void *start, size_t size)
memory by the page table. */
for (const void *ptr = pg_round_down (start); ptr <= end; ptr += PGSIZE)
if (pagedir_get_page (thread_current ()->pagedir, ptr) == NULL)
syscall_exit (EXIT_FAILURE);
{
if (!try_alloc_new_page (ptr))
syscall_exit (EXIT_FAILURE);
}
}
/* Validates if a string is fully contained within user virtual memory. Kills
@@ -495,10 +516,13 @@ validate_user_string (const char *str)
/* If we reach addresses that are not mapped to physical memory before the
end of the string, the thread is terminated. */
if (!is_user_vaddr(page) ||
pagedir_get_page (thread_current ()->pagedir, page) == NULL)
if (!is_user_vaddr(page))
syscall_exit (EXIT_FAILURE);
if (pagedir_get_page (thread_current ()->pagedir, page) == NULL)
if (!try_alloc_new_page (str))
syscall_exit (EXIT_FAILURE);
while (offset < PGSIZE)
{
if (*str == '\0')