PERFORCE change 112453 for review

Oleksandr Tymoshenko gonzo at FreeBSD.org
Wed Jan 3 11:44:54 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=112453

Change 112453 by gonzo at gonzo_hq on 2007/01/03 19:44:47

	o Proper handle memory faults for both userland
	    and kernel.

Affected files ...

.. //depot/projects/mips2/src/sys/mips/include/trap.h#4 edit
.. //depot/projects/mips2/src/sys/mips/mips/trap.c#13 edit

Differences ...

==== //depot/projects/mips2/src/sys/mips/include/trap.h#4 (text+ko) ====

@@ -53,6 +53,8 @@
 #define	TrCacheErr	30  /* MIPS64 */
 #define	TrVCED		31
 
+#define	TrUser		32  /* Flag to mark userland-inititated traps */
+
 #ifndef LOCORE /* XXX */
 struct trapframe;
 

==== //depot/projects/mips2/src/sys/mips/mips/trap.c#13 (text+ko) ====

@@ -133,22 +133,57 @@
 	code = (cause & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
 	kernelmode = (tf->tf_regs[TF_SR] & MIPS_SR_KSU_USER) == 0;
 
+	if(! kernelmode)
+		code |= TrUser;
+
 	/*
 	 * Handle that which we can.
 	 */
+	va = trunc_page(badvaddr);
+	td = curthread;
+
 	switch (code) {
 	case TrMod:
-		va = trunc_page(badvaddr);
+		/*
+		 * Kernel mode, KVA 
+		 */
 		if (va >= KERNBASE)
+		{
+			pt_entry_t *pte;
+			pte = tlb_kern_pte_find(
+			    kernel_pmap->pm_private.pm_direct_map, va);
+
 			tlb_modified(kernel_pmap, (void *)va);
-		else
-			tlb_modified(&curthread->td_proc->p_vmspace->vm_pmap,
-			    (void *)va);
-		goto done;
+			goto done;
+		}
+		/* FALLTHROUGH */
+	case TrMod + TrUser:
+		/*
+		 * UVA, both kernel and user modes
+		 */
+		{
+			pmap_t pmap;
+			pt_entry_t *pte;
+
+			pmap = vmspace_pmap(td->td_proc->p_vmspace);
+			pte = pmap_segmap(pmap, va);
+			pte += (va >> PAGE_SHIFT) & (NPTEPG - 1);
+
+			if (pte_ro(pte) )
+			{
+				ftype = VM_PROT_WRITE;
+				map = &td->td_proc->p_vmspace->vm_map;
+				goto heavy;
+			}
+
+			tlb_modified(pmap, (void *)va);
+			goto done;
+		}
+		break;
+
 	case TrTLBL:
 	case TrTLBS:
-		va = trunc_page(badvaddr);
-		td = curthread;
+		ftype = (code == TrTLBL) ? VM_PROT_READ : VM_PROT_WRITE;
 
 		if (va >= KERNBASE) {
 			pt_entry_t *pte;
@@ -167,14 +202,22 @@
 				tlb_update(va, kernel_pmap->pm_asid,
 						pte[0], pte[1]);
 			goto done;
-		} else
-			map = &td->td_proc->p_vmspace->vm_map;
+		}
+
+		map = &td->td_proc->p_vmspace->vm_map;
+		goto heavy;
+
+	case TrTLBL + TrUser:
+		map = &td->td_proc->p_vmspace->vm_map;
+		ftype = VM_PROT_READ;
+		goto heavy;
+
+	case TrTLBS + TrUser:
+		map = &td->td_proc->p_vmspace->vm_map;
+		ftype = VM_PROT_WRITE;
 
 heavy:
-		if (code == TrTLBL)
-			ftype = VM_PROT_READ;
-		else
-			ftype = VM_PROT_WRITE;
+
 		error = vm_fault(map, va, ftype,
 		    (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL);
 
@@ -188,7 +231,8 @@
 		    error, va, tf->tf_regs[TF_EPC]	);
 
 		panic("TODO: signal on memory access errors");
-	case TrSys:
+
+	case TrSys + TrUser:
 		syscall(curthread, tf);
 		goto done;
 		break;
@@ -213,6 +257,11 @@
 		break;
 	}
 
+	/* 
+	 * Clear out TrUser flag. Once we get here we need it cleared
+	 * to access mnemonic/description strings.
+	 */
+	code &= ~TrUser;
 	printf("\n\nFatal trap type %d in %s mode:",
 	       code, kernelmode ? "kernel" : "user");
 	if (code <= MAXTRAPID && code >= 0) {


More information about the p4-projects mailing list