Nucleus
Barry Kernel threads + threads share address space 6217f0d (3 years, 1 month ago)
diff --git a/memory/fault.c b/memory/fault.c
index 7dfae10..cbff7b2 100644
--- a/memory/fault.c
+++ b/memory/fault.c
@@ -142,14 +142,10 @@ not_present_write(VMRegion *region, uintptr_t addr)
ASSERT(front);
inode = front->inode;
page = find_page(inode->pages, offset);
+ if (page)
+ return install_page(addr, page, region->prot);
newPage = create_page(inode->pages, alloc_frame(), offset);
install_page(addr, newPage, region->prot);
- if (page) {
- copy_page_frame(PAGE_ADDR(page->frame),
- PAGE_ADDR(newPage->frame));
- remove(inode->pages, page);
- return;
- }
/* Anonymous region, zero-fill */
if (region->flags & MAP_ANONYMOUS) {
@@ -179,14 +175,20 @@ page_fault_handler(struct InterruptFrame *frame)
uint8_t present = frame->err & (1 << 0);
uint8_t write = frame->err & (1 << 1);
uint8_t user = frame->err & (1 << 2);
+ page_t pg = get_page(addr);
ASSERT(current && current->vm);
+ /* Handle lazy invalidation */
+ if (!present && (pg & PTE_PRESENT))
+ return flush_tlb(addr);
+ if (write && (pg & PTE_WRITE))
+ return flush_tlb(addr);
+
/* Iterate VM Regions */
VMRegion *region = find_region(addr);
if (__builtin_expect(!region, 0)) {
/* Not in a region */
- page_t pg = get_page(addr);
panic("Page Fault [%d:%d] (%#.8x -> %#.8x [tbl:%d, pg:%d][%#.8x], %s, %s, %s)",
current->tgid, current->tid, frame->eip,
addr, (addr >> 12) / 1024, (addr >> 12) % 1024, pg,
@@ -195,9 +197,12 @@ page_fault_handler(struct InterruptFrame *frame)
user ? "user" : "kernel");
}
+ /* Protection violation, kill process */
if (user && write && !(region->prot & PROT_WRITE))
- panic("Segmentation violation");
+ panic("Segmentation violation : %#.8x[%#.8x] (%#.8x -> %#.8x)",
+ region, region->prot, frame->eip, addr);
+ /* Update paging structures correctly */
if (present && write)
return copy_on_write(region, addr);
if (!present && write)