diff --git a/kernel-src/mm/pmm.c b/kernel-src/mm/pmm.c index 93125770..5570b442 100644 --- a/kernel-src/mm/pmm.c +++ b/kernel-src/mm/pmm.c @@ -133,6 +133,7 @@ void pmm_release(void *addr) { uintmax_t newrefcount = __atomic_sub_fetch(&page->refcount, 1, __ATOMIC_SEQ_CST); if (newrefcount == 0) { + __assert((page->flags & PAGE_FLAGS_DIRTY) == 0); MUTEX_ACQUIRE(&freelistmutex, false); insertinfreelist(page); if (page->backing == NULL) diff --git a/kernel-src/mm/vmm.c b/kernel-src/mm/vmm.c index a6057710..9341e475 100644 --- a/kernel-src/mm/vmm.c +++ b/kernel-src/mm/vmm.c @@ -223,15 +223,20 @@ static void destroyrange(vmmrange_t *range, uintmax_t _offset, size_t size, int if (range->vnode->type == V_TYPE_CHDEV) { // character device mapping __assert(VOP_MUNMAP(range->vnode, vaddr, range->offset + offset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0); - } else if (arch_mmu_iswritable(_cpu()->vmmctx->pagetable, vaddr) == false || arch_mmu_isdirty(_cpu()->vmmctx->pagetable, vaddr) == false) { + } else if (arch_mmu_iswritable(_cpu()->vmmctx->pagetable, vaddr) && arch_mmu_isdirty(_cpu()->vmmctx->pagetable, vaddr)) { // dirty page cache mapping + arch_mmu_unmap(_cpu()->vmmctx->pagetable, vaddr); vmmcache_makedirty(pmm_getpage(physical)); pmm_release(physical); + } else { + // non dirty page mapping + arch_mmu_unmap(_cpu()->vmmctx->pagetable, vaddr); + pmm_release(physical); } } else { // anonymous or private non character device mapping - pmm_release(physical); arch_mmu_unmap(_cpu()->vmmctx->pagetable, vaddr); + pmm_release(physical); } }