diff options
author | sotech117 <michael_foiani@brown.edu> | 2024-05-13 12:10:55 +0000 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2024-05-13 12:10:55 +0000 |
commit | 7585cb5ad84babe9db8c6595de464e33fb878f0c (patch) | |
tree | 3acdd29920420ca341ea7e3f90d60b16c384ce51 | |
parent | f09878f6327426631d9419d825a4e8396e3b9dc4 (diff) |
s5 fixes and issues with weenix
-rw-r--r-- | kernel/api/access.c | 28 | ||||
-rw-r--r-- | kernel/api/syscall.c | 10 | ||||
-rw-r--r-- | kernel/fs/s5fs/s5fs.c | 16 | ||||
-rw-r--r-- | kernel/fs/s5fs/s5fs_subr.c | 6 | ||||
-rw-r--r-- | kernel/main/kmain.c | 2 | ||||
-rw-r--r-- | kernel/proc/kthread.c | 3 | ||||
-rw-r--r-- | kernel/proc/proc.c | 3 | ||||
-rw-r--r-- | kernel/util/debug.c | 2 | ||||
-rw-r--r-- | kernel/vm/mmap.c | 15 | ||||
-rw-r--r-- | kernel/vm/pagefault.c | 6 | ||||
-rw-r--r-- | kernel/vm/vmmap.c | 59 |
11 files changed, 91 insertions, 59 deletions
diff --git a/kernel/api/access.c b/kernel/api/access.c index 9a7bed0..9941971 100644 --- a/kernel/api/access.c +++ b/kernel/api/access.c @@ -118,16 +118,28 @@ long addr_perm(proc_t *p, const void *vaddr, int perm) { // NOT_YET_IMPLEMENTED("VM: addr_perm"); - // loop through the vmareas in the process's vmmap - vmarea_t *vma = vmmap_lookup(p->p_vmmap, ADDR_TO_PN(vaddr)); + // // loop through the vmareas in the process's vmmap + // vmarea_t *vma = vmmap_lookup(p->p_vmmap, ADDR_TO_PN(vaddr)); - // if the vma doesn't exist, return 0 - if (!vma) - { + // // if the vma doesn't exist, return 0 + // if (!vma) + // { + // return 0; + // } + + // return !!(perm & vma->vma_prot); + + // TODO: FIX MEEE + + vmarea_t* area = vmmap_lookup(p->p_vmmap, ADDR_TO_PN(vaddr)); + if (!area) { + return 0; + } + if (perm & area->vma_prot) { + return 1; + } else { return 0; } - - return !!(perm & vma->vma_prot); } /* @@ -145,7 +157,7 @@ long range_perm(proc_t *p, const void *vaddr, size_t len, int perm) // loop through the page numbers in the range size_t vfn = ADDR_TO_PN(vaddr); - size_t end_vfn = ADDR_TO_PN(vaddr + len); + size_t end_vfn = ADDR_TO_PN((uintptr_t)vaddr + len); for (size_t i = vfn; i < end_vfn; i++) { // check the permissions for each page diff --git a/kernel/api/syscall.c b/kernel/api/syscall.c index e077631..467b7d6 100644 --- a/kernel/api/syscall.c +++ b/kernel/api/syscall.c @@ -85,15 +85,15 @@ static long sys_read(read_args_t *args) } // Call do_read() with the buffer and then copy the buffer to the userland args after the system call - ret = do_read(kargs.fd, addr, kargs.nbytes); + ssize_t bytes_read = do_read(kargs.fd, addr, kargs.nbytes); // if ret < 0, free the temporary buffer and return -1 - if (ret < 0) + if (bytes_read < 0) { page_free_n(addr, size_in_pages); - ERROR_OUT_RET(ret); + ERROR_OUT_RET(bytes_read); } // if read nothing, free the temporary buffer and return 0 - if (ret == 0) + if (bytes_read == 0) { page_free_n(addr, size_in_pages); return 0; @@ -110,7 +110,7 @@ static long sys_read(read_args_t *args) // Make sure to free the temporary buffer allocated page_free_n(addr, size_in_pages); - return ret; + return bytes_read; } /* diff --git a/kernel/fs/s5fs/s5fs.c b/kernel/fs/s5fs/s5fs.c index ba406e7..8fdfc7b 100644 --- a/kernel/fs/s5fs/s5fs.c +++ b/kernel/fs/s5fs/s5fs.c @@ -306,7 +306,7 @@ static void s5fs_delete_vnode(fs_t *fs, vnode_t *vn) { // Write the inode back to disk and return pframe_t *pf; - s5_get_meta_disk_block(FS_TO_S5FS(fs), S5_INODE_BLOCK(vn->vn_vno), 0, &pf); + s5_get_meta_disk_block(FS_TO_S5FS(fs), S5_INODE_BLOCK(vn->vn_vno), 1, &pf); // // Check if the page frame was not found // if (err < 0) // { @@ -481,7 +481,7 @@ static long s5fs_mknod(struct vnode *dir, const char *name, size_t namelen, } // Link the new inode/vnode to the parent directory - long link = s5_link(dir, name, namelen, VNODE_TO_S5NODE(new_vnode)); + long link = s5_link(VNODE_TO_S5NODE(dir), name, namelen, VNODE_TO_S5NODE(new_vnode)); // Check if the link operation failed if (link < 0) { @@ -700,7 +700,7 @@ static long s5fs_rename(vnode_t *olddir, const char *oldname, size_t oldnamelen, } // Remove the old directory entry - s5_remove_dirent(s5_node, oldname, oldnamelen, filepos); + s5_remove_dirent(s5_node, oldname, oldnamelen, VNODE_TO_S5NODE(olddir)); // Check if this failed (TODO: ask in hours) return link; @@ -741,7 +741,7 @@ static long s5fs_rename(vnode_t *olddir, const char *oldname, size_t oldnamelen, } // Remove the old directory entry - s5_remove_dirent(s5_node, oldname, oldnamelen, filepos); + s5_remove_dirent(s5_node, oldname, oldnamelen, VNODE_TO_S5NODE(olddir)); vput_locked(&child); vput_locked(&new_child); @@ -819,7 +819,7 @@ static long s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen, // Check if the link operation failed if (link2 < 0) { - s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), ".", 1, 0); + s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), ".", 1, VNODE_TO_S5FS(dir)); vput(new_vnode); s5_free_inode(s5fs, inode_num); return link2; @@ -835,8 +835,8 @@ static long s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen, // Check if the link operation failed if (link3 < 0) { - s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), ".", 1, 0); - s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), "..", 2, 0); + s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), ".", 1, VNODE_TO_S5FS(dir)); + s5_remove_dirent(VNODE_TO_S5NODE(new_vnode), "..", 2, VNODE_TO_S5FS(dir)); vput(new_vnode); s5_free_inode(s5fs, inode_num); return link3; @@ -973,7 +973,7 @@ static long s5fs_stat(vnode_t *vnode, stat_t *ss) s5_inode_t *s5_inode = &VNODE_TO_S5NODE(vnode)->inode; // Initialize the stat struct - ss->st_blocks = s5_inode_blocks(vnode); + ss->st_blocks = s5_inode_blocks(VNODE_TO_S5NODE(vnode)); ss->st_mode = vnode->vn_mode; ss->st_rdev = vnode->vn_devid; ss->st_ino = s5_inode->s5_number; diff --git a/kernel/fs/s5fs/s5fs_subr.c b/kernel/fs/s5fs/s5fs_subr.c index f092d0a..6e89249 100644 --- a/kernel/fs/s5fs/s5fs_subr.c +++ b/kernel/fs/s5fs/s5fs_subr.c @@ -242,7 +242,7 @@ long s5_file_block_to_disk_block(s5_node_t *sn, size_t file_blocknum, } // Update the inode indirect_block[indirect_block_index] = alloced_blocknum; - sn->dirtied_inode = 1; + // sn->dirtied_inode = 1; // set ret params and return *newp = 1; @@ -408,8 +408,8 @@ ssize_t s5_write_file(s5_node_t *sn, size_t pos, const char *buf, size_t len) if (err < 0) { // Restore pos - sn->vnode.vn_len += bytes_written; - sn->inode.s5_un.s5_size += bytes_written; + sn->vnode.vn_len -= bytes_written; + sn->inode.s5_un.s5_size -= bytes_written; return err; } diff --git a/kernel/main/kmain.c b/kernel/main/kmain.c index 6007acd..e16d08e 100644 --- a/kernel/main/kmain.c +++ b/kernel/main/kmain.c @@ -170,7 +170,7 @@ static void *initproc_run(long arg1, void *arg2) // dbg(DBG_PROC, "%s", "In main thread!\n"); - char *argv[1] = {NULL}; + char *argv[2] = {"init", NULL}; char *envp[1] = {NULL}; kernel_execve("/sbin/init", argv, envp); diff --git a/kernel/proc/kthread.c b/kernel/proc/kthread.c index b614ac3..722d932 100644 --- a/kernel/proc/kthread.c +++ b/kernel/proc/kthread.c @@ -140,8 +140,6 @@ kthread_t *kthread_clone(kthread_t *thr) new_thread->kt_kstack = new_thread->kt_ctx.c_kstack; new_thread->kt_ctx.c_kstacksz = DEFAULT_STACK_SIZE; - // context_setup(&new_thread->kt_ctx, NULL, 0, NULL, new_thread->kt_kstack, - // DEFAULT_STACK_SIZE, thr->kt_proc->p_pml4); (done in fork, I hope) // set the retval, errno, cancelled new_thread->kt_retval = thr->kt_retval; @@ -154,7 +152,6 @@ kthread_t *kthread_clone(kthread_t *thr) list_init(&new_thread->kt_mutexes); list_link_init(&new_thread->kt_plink); list_link_init(&new_thread->kt_qlink); - // list_insert_tail(&thr->kt_proc->p_threads, &new_thread->kt_plink); (done in fork) return new_thread; } diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index f7878a2..f13064a 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -223,6 +223,9 @@ proc_t *proc_create(const char *name) proc_initproc = proc; } + proc->p_vmmap = vmmap_clone(curproc->p_vmmap); + curproc->p_vmmap->vmm_proc = proc; + #ifdef __VFS__ // clone and ref the files from curproc for (int fd = 0; fd < NFILES; fd++) diff --git a/kernel/util/debug.c b/kernel/util/debug.c index fab63e7..e2a589d 100644 --- a/kernel/util/debug.c +++ b/kernel/util/debug.c @@ -19,7 +19,7 @@ * always be the first thing in this variable. Note that this setting can be * changed at runtime by modifying the dbg_modes global variable. */ -#define INIT_DBG_MODES "-all,exec,elf" +#define INIT_DBG_MODES "-all,exec,elf,vm,syscall,print" /* Below is a truly terrible poll-driven serial driver that we use for debugging * purposes - it outputs to COM1, but diff --git a/kernel/vm/mmap.c b/kernel/vm/mmap.c index 78aa3b5..ce932de 100644 --- a/kernel/vm/mmap.c +++ b/kernel/vm/mmap.c @@ -161,7 +161,6 @@ long do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, VMMAP_DIR_HILO, &vma ); - // check if vmmap_map() failed if (err < 0) { @@ -213,7 +212,7 @@ long do_munmap(void *addr, size_t len) } // Check if len is in bounds - if (len > USER_MEM_HIGH) + if (len > USER_MEM_HIGH || len == 0) { return -EINVAL; } @@ -224,17 +223,13 @@ long do_munmap(void *addr, size_t len) return -EINVAL; } - // Check if len is 0 - if (len == 0) - { - return -EINVAL; - } - // Remove the mapping + size_t start = ADDR_TO_PN(addr); + size_t end = ADDR_TO_PN(PAGE_ALIGN_UP((uintptr_t)addr + len)); long ret = vmmap_remove( curproc->p_vmmap, - ADDR_TO_PN(addr), - ADDR_TO_PN(PAGE_ALIGN_UP((uintptr_t)addr + len)) + start, + end - start ); return ret; }
\ No newline at end of file diff --git a/kernel/vm/pagefault.c b/kernel/vm/pagefault.c index 2e0c92d..b289537 100644 --- a/kernel/vm/pagefault.c +++ b/kernel/vm/pagefault.c @@ -91,7 +91,7 @@ void handle_pagefault(uintptr_t vaddr, uintptr_t cause) mobj_lock(vma->vma_obj); int ret = mobj_get_pframe( vma->vma_obj, - vma->vma_off + (ADDR_TO_PN(vaddr) - vma->vma_start), + vma->vma_off + ADDR_TO_PN(vaddr) - vma->vma_start, cause & FAULT_WRITE ? 1 : 0, &pf ); @@ -102,6 +102,8 @@ void handle_pagefault(uintptr_t vaddr, uintptr_t cause) } // 4) Finally, set up a call to pt_map to insert a new mapping into the appropriate pagetable + uintptr_t paddr = pt_virt_to_phys(pf->pf_addr); + pframe_release(&pf); int pdflags = PT_PRESENT | PT_WRITE | PT_USER; int ptflags = PT_PRESENT | PT_USER; if (cause & FAULT_WRITE) @@ -111,7 +113,7 @@ void handle_pagefault(uintptr_t vaddr, uintptr_t cause) int err = pt_map( curproc->p_pml4, - pt_virt_to_phys((uintptr_t) pf->pf_addr), + paddr, (uintptr_t) PAGE_ALIGN_DOWN(vaddr), pdflags, ptflags diff --git a/kernel/vm/vmmap.c b/kernel/vm/vmmap.c index fd99c55..8789371 100644 --- a/kernel/vm/vmmap.c +++ b/kernel/vm/vmmap.c @@ -172,21 +172,35 @@ ssize_t vmmap_find_range(vmmap_t *map, size_t npages, int dir) // case 1: dir is VMMAP_DIR_LOHI if (dir == VMMAP_DIR_LOHI) { - // iterate over the page numbers + // iterate over the page numbers, going from low to high + // determine the continguous range of free virtual pages + + int start, end = 0; size_t vfn = ADDR_TO_PN(USER_MEM_LOW); - while (vfn <= ADDR_TO_PN(USER_MEM_HIGH) - npages) + while (vfn <= ADDR_TO_PN(USER_MEM_HIGH)) { // Lookup the vmarea for this page number - vmarea_t *vma = vmmap_lookup(map, vfn); - - // if the vmarea is NULL, return the page number + vmarea_t *vma = vmmap_lookup(map, vfn++); if (vma == NULL) { - return vfn; + // if unmapped, document this + end = vfn; + if (start == 0) + { + start = vfn; + } + } + else + { + // if mapped, start over + start, end = 0; } - // if the vmarea is not NULL, set the page number to the end of the vmarea - vfn = vma->vma_end; + // if the range exists, return the start + if (end == npages) + { + return start; + } } } @@ -194,20 +208,28 @@ ssize_t vmmap_find_range(vmmap_t *map, size_t npages, int dir) else if (dir == VMMAP_DIR_HILO) { // iterate over the page numbers - size_t vfn = ADDR_TO_PN(USER_MEM_HIGH) - npages; + int contig = 0; + size_t vfn = ADDR_TO_PN(USER_MEM_HIGH); while (vfn >= ADDR_TO_PN(USER_MEM_LOW)) { // Lookup the vmarea for this page number - vmarea_t *vma = vmmap_lookup(map, vfn); - - // if the vmarea is NULL, return the page number + vmarea_t *vma = vmmap_lookup(map, --vfn); if (vma == NULL) { - return vfn; + // if unmapped, increment the contig + contig++; + } + else + { + // if mapped, reset the contig + contig = 0; } - // if the vmarea is not NULL, set the page number to the start of the vmarea - vfn = vma->vma_start - npages; + // if there are n contiguous pages, return the current vfn + if (contig == npages) + { + return vfn; + } } } @@ -448,6 +470,7 @@ long vmmap_map(vmmap_t *map, vnode_t *file, size_t lopage, size_t npages, mobj_t *shadow_obj = shadow_create(new_vmarea->vma_obj); mobj_unlock(new_vmarea->vma_obj); mobj_unlock(shadow_obj); // unlock the shadow object before use + mobj_put(&new_vmarea->vma_obj); // put the original object if (shadow_obj == NULL) { vmarea_free(new_vmarea); @@ -674,7 +697,7 @@ long vmmap_read(vmmap_t *map, const void *vaddr, void *buf, size_t count) size_t vfn = ADDR_TO_PN(vaddr); size_t end_vfn = ADDR_TO_PN(vaddr + count); size_t bytes_read = 0; - while (vfn < end_vfn) + while (vfn <= end_vfn) { // Lookup the vmarea for this page number vmarea_t *vma = vmmap_lookup(map, vfn); @@ -697,7 +720,7 @@ long vmmap_read(vmmap_t *map, const void *vaddr, void *buf, size_t count) void *cursor = (void *)(bytes_read + vaddr); size_t bytes_this_iteration = MIN(PAGE_SIZE - PAGE_OFFSET(cursor), count - bytes_read); memcpy( - buf + bytes_read, + (void *) buf + bytes_read, (void *)pf->pf_addr + PAGE_OFFSET(cursor), bytes_this_iteration ); @@ -768,7 +791,7 @@ long vmmap_write(vmmap_t *map, void *vaddr, const void *buf, size_t count) size_t bytes_this_iteration = MIN(PAGE_SIZE - PAGE_OFFSET(cursor), count - bytes_written); memcpy( (void *)pf->pf_addr + PAGE_OFFSET(cursor), - buf + bytes_written, + (void *)buf + bytes_written, bytes_this_iteration ); |