From: davem Date: Sun, 14 Jan 1996 00:39:18 +0000 (+0000) Subject: The sun mmu is very broken, and we all can thank crashme for X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=8d71c1d45f236c6efb0f749c2d53ba9433acf66a;p=openbsd The sun mmu is very broken, and we all can thank crashme for 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. --- diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c index 2f6103499da..2925b0adea2 100644 --- a/sys/arch/sparc/sparc/trap.c +++ b/sys/arch/sparc/sparc/trap.c @@ -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[];