aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2024-05-13 12:10:55 +0000
committersotech117 <michael_foiani@brown.edu>2024-05-13 12:10:55 +0000
commit7585cb5ad84babe9db8c6595de464e33fb878f0c (patch)
tree3acdd29920420ca341ea7e3f90d60b16c384ce51
parentf09878f6327426631d9419d825a4e8396e3b9dc4 (diff)
s5 fixes and issues with weenix
-rw-r--r--kernel/api/access.c28
-rw-r--r--kernel/api/syscall.c10
-rw-r--r--kernel/fs/s5fs/s5fs.c16
-rw-r--r--kernel/fs/s5fs/s5fs_subr.c6
-rw-r--r--kernel/main/kmain.c2
-rw-r--r--kernel/proc/kthread.c3
-rw-r--r--kernel/proc/proc.c3
-rw-r--r--kernel/util/debug.c2
-rw-r--r--kernel/vm/mmap.c15
-rw-r--r--kernel/vm/pagefault.c6
-rw-r--r--kernel/vm/vmmap.c59
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
);