The sun mmu is very broken, and we all can thank crashme for
authordavem <davem@openbsd.org>
Sun, 14 Jan 1996 00:39:18 +0000 (00:39 +0000)
committerdavem <davem@openbsd.org>
Sun, 14 Jan 1996 00:39:18 +0000 (00:39 +0000)
helping me find this bug.  On execution of an atomic load/store instruction
the chip will only say that a read fault is happening, we then load up a
readonly translation to the accessed page, and we get the fault again still
showing a read-fault.  We end up faulting in a loop forever and the process
appears to be completely stuck.  The algorithm to fix this problem goes like
this.  If we get a non-text fault, and the fault type is VM_PROT_READ, and
the SER_PROT bit is set in the syncronous fault error register, we take
a peek at the instruction at pc.  If this instruction is indeed an ldstub
or a swap variant we or in VM_PROT_WRITE to the fault type.

sys/arch/sparc/sparc/trap.c

index 2f61034..2925b0a 100644 (file)
@@ -598,6 +598,22 @@ mem_access_fault(type, ser, v, pc, psr, tf)
        if (VA_INHOLE(v))
                goto fault;
        ftype = ser & SER_WRITE ? VM_PROT_READ|VM_PROT_WRITE : VM_PROT_READ;
+       if(ftype == VM_PROT_READ && (ser & SER_PROT) && type != T_TEXTFAULT) {
+               /* If this is an ldstub or swap instruction
+                * then we are about to fault in a loop forever
+                * as only the read part of the fault will be
+                * reported by the mmu.
+                */
+               int error, insn;
+
+               error = copyin((caddr_t) pc, &insn, sizeof(int));
+               if(!error) {
+                       insn = (insn >> 16); /* high word */
+                       insn &= 0xc168;
+                       if(insn == 0xc068)
+                               ftype |= VM_PROT_WRITE;
+               }
+       }
        va = trunc_page(v);
        if (psr & PSR_PS) {
                extern char Lfsbail[];