From e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 21 Jun 2012 16:47:23 +0200 Subject: initial implementation of memory mapped files --- userprog/syscall.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'userprog/syscall.c') diff --git a/userprog/syscall.c b/userprog/syscall.c index 7f8c397..14cbaab 100644 --- a/userprog/syscall.c +++ b/userprog/syscall.c @@ -14,7 +14,8 @@ #include "userprog/pagedir.h" #include "userprog/process.h" #include "userprog/syscall.h" -#include "lib/user/syscall.h" +#include "vm/mmap.h" +#include "vm/page.h" #define STACK_SLOT_SIZE sizeof(int) @@ -226,8 +227,8 @@ syscall_handler (struct intr_frame *f) goto fail; } syscall_sp = sp; - result = fp (sp, &segfault); - if (segfault) + result = fp (sp, &segfault); + if (segfault) goto fail; f->eax = result; return; @@ -574,11 +575,64 @@ syscall_close (void *sp, bool *segfault) static int syscall_mmap (void *sp, bool *segfault) { - return 0; + int fd; + void *addr, *offset; + struct file *file, *file2; + off_t len; + + /* get arguments */ + if (! copy_from_user (&fd, STACK_ADDR (sp,1)) || + ! copy_from_user (&addr, STACK_ADDR (sp, 2))) { + *segfault = true; + return -1; + } + + /* address must be valid and page-aligned */ + if (addr == NULL || pg_ofs (addr)) + return -1; + + /* file descriptors 0 and 1 are reserved */ + if (fd == 0 || fd == 1) + return -1; + + /* get file */ + file = process_get_file (fd); + if (file == NULL) + return -1; + + /* file length must be positiv */ + len = file_length (file); + if (len <= 0) + return -1; + + /* check if the pages don't overlap any existing pages */ + offset = addr; + while(offset < addr + len) + { + if (page_table_fetch (&thread_current ()->page_table, offset)) + return -1; + offset += PGSIZE; + } + + process_lock_filesys (); + file2 = file_reopen (file); + process_unlock_filesys (); + + return (file2 == NULL) ? -1 : + mmap_table_insert (&process_current()->mmap_table, addr, file2, len); } static int syscall_munmap (void *sp, bool *segfault) { + mapid_t mapping; + + /* get arguments */ + if (! copy_from_user (&mapping, STACK_ADDR (sp,1))) { + *segfault = true; + return 0; + } + + mmap_table_remove (&process_current()->mmap_table, mapping); return 0; } -- cgit v1.2.3