BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 6217f0db2c8f2513994f4cc773aaa4171a049963 / memory / fault.c

// Related

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)