diff options
author | Michael Foiani <mfoiani@cs.brown.edu> | 2024-05-15 00:04:33 -0400 |
---|---|---|
committer | Michael Foiani <mfoiani@cs.brown.edu> | 2024-05-15 00:04:33 -0400 |
commit | 712b08007bd8101a624a14ecf1f829d4083e1696 (patch) | |
tree | 841b696c9bdb6e3f3c49e6a893b2e0c62716c4c6 | |
parent | d28f705ee3b1c850e41b165bfb966572f0c6a815 (diff) |
shadow collapse fix
-rw-r--r-- | kernel/vm/pagefault.c | 6 | ||||
-rw-r--r-- | kernel/vm/shadow.c | 53 | ||||
-rw-r--r-- | kernel/vm/vmmap.c | 4 |
3 files changed, 25 insertions, 38 deletions
diff --git a/kernel/vm/pagefault.c b/kernel/vm/pagefault.c index 4be12cd..47b3312 100644 --- a/kernel/vm/pagefault.c +++ b/kernel/vm/pagefault.c @@ -53,11 +53,7 @@ void handle_pagefault(uintptr_t vaddr, uintptr_t cause) // NOT_YET_IMPLEMENTED("VM: handle_pagefault"); // Check that the vaddr is valid - if (vaddr < USER_MEM_LOW) - { - do_exit(EFAULT); - } - if (vaddr > USER_MEM_HIGH) + if (vaddr < USER_MEM_LOW ||vaddr > USER_MEM_HIGH) { do_exit(EFAULT); } diff --git a/kernel/vm/shadow.c b/kernel/vm/shadow.c index e0a8674..ca20ab0 100644 --- a/kernel/vm/shadow.c +++ b/kernel/vm/shadow.c @@ -119,58 +119,49 @@ void shadow_collapse(mobj_t *o) // NOT_YET_IMPLEMENTED("VM: shadow_collapse"); mobj_shadow_t *so = MOBJ_TO_SO(o); - mobj_t *shadowed = so->shadowed; - - if (shadowed->mo_type != MOBJ_SHADOW) - { - return; - } - - dbg(DBG_PRINT, "shadow_collapse: refcount bottom: %d\n", so->bottom_mobj->mo_refcount); - - while (shadowed && shadowed->mo_type == MOBJ_SHADOW) + mobj_t *next = so->shadowed; + while(next && next->mo_type==MOBJ_SHADOW) { - // mobj_shadow_t *so_shadowed = MOBJ_TO_SO(shadowed); - mobj_t *shadowed_shadowed = MOBJ_TO_SO(shadowed)->shadowed; - // if the refcount is not 1, then we can't collapse - if (shadowed_shadowed->mo_refcount != 1) + // check if the shadowed object is collapsable + if (next->mo_refcount != 1) { - // continue down the shadow chain - shadowed = shadowed_shadowed; + // continue on the shadow chain + so = MOBJ_TO_SO(next); + next = MOBJ_TO_SO(next)->shadowed; continue; } - mobj_lock(shadowed_shadowed); - list_iterate(&shadowed_shadowed->mo_pframes, pf, pframe_t, pf_link) + // migrate the pframes from o's shadowed object to o + // mobj_lock(next); // lock before iterover + list_iterate(&next->mo_pframes, pf, pframe_t, pf_link) { pframe_t *pf_shadow = NULL; - mobj_find_pframe(shadowed_shadowed, pf->pf_pagenum, &pf_shadow); + mobj_lock(&so->mobj); + mobj_find_pframe(&so->mobj, pf->pf_pagenum, &pf_shadow); + mobj_unlock(&so->mobj); if (!pf_shadow) { list_remove(&pf->pf_link); - // append to the list of pframes - list_insert_tail(&shadowed_shadowed->mo_pframes, &pf->pf_link); + // by migrate, just add to the list of pframes + list_insert_tail(&so->mobj.mo_pframes, &pf->pf_link); } else { + // if it exists, just release it pframe_release(&pf_shadow); } } - // get the pointer to the shadowed object - mobj_shadow_t *so_shadowed_shadowed = MOBJ_TO_SO(shadowed_shadowed); - so->shadowed = shadowed_shadowed; + // update the pointer to the shadowed object + so->shadowed = MOBJ_TO_SO(next)->shadowed; - mobj_lock(so->shadowed); + // update the refcounts mobj_ref(so->shadowed); - mobj_unlock(so->shadowed); - - // put the shadowed object - mobj_put(&shadowed); + mobj_put(&next); - // continue down the shadow chain - shadowed = shadowed_shadowed; + // update next + next = so->shadowed; } } diff --git a/kernel/vm/vmmap.c b/kernel/vm/vmmap.c index ad95d33..e301ac0 100644 --- a/kernel/vm/vmmap.c +++ b/kernel/vm/vmmap.c @@ -270,9 +270,9 @@ void vmmap_collapse(vmmap_t *map) { if (vma->vma_obj->mo_type == MOBJ_SHADOW) { - mobj_lock(vma->vma_obj); + // mobj_lock(vma->vma_obj); shadow_collapse(vma->vma_obj); - mobj_unlock(vma->vma_obj); + // mobj_unlock(vma->vma_obj); } } } |