Implement stack growth for system calls and add stack pointer tracking to thread

This commit is contained in:
EDiasAlberto
2024-11-27 19:21:43 +00:00
parent c670c29e47
commit c74a8c55aa
2 changed files with 31 additions and 3 deletions

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')