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