From ea6c22ed3e8787ca90bd0c939d3f389e7e2ec427 Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Fri, 25 May 2007 20:58:40 +0000 Subject: Edge cases can trigger a TLB miss exception instead of an invalid TLB exception on early R5000 revisions. Despite this bug being supposedly fixed in R5000 revision 2 onwards, it nevertheless occurs quite frequently on matthieu's revision 2.1 R5000. Servicing the TLB miss exception would cause a duplicate TLB to be inserted, which causes the processor operation to become unpredictable (but lethal to the kernel, ten times out of nine). More details about the problem can be found in: http://www.linux-mips.org/archives/linux-mips/2000-02/msg00040.html We work around the issue by checking for an existing TLB entry, and handling this as an invalid TLB exception (as it was intended to be), in this case. Unfortunately this causes a measurable 1% slowdown on ``safe'' processors, so we'll work on providing different tlb handler flavours in the near future to recover from this. --- sys/arch/mips64/mips64/tlbhandler.S | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/arch/mips64/mips64/tlbhandler.S b/sys/arch/mips64/mips64/tlbhandler.S index 10d8cd37803..4bbd2603c64 100644 --- a/sys/arch/mips64/mips64/tlbhandler.S +++ b/sys/arch/mips64/mips64/tlbhandler.S @@ -1,4 +1,4 @@ -/* $OpenBSD: tlbhandler.S,v 1.15 2007/05/25 20:47:19 miod Exp $ */ +/* $OpenBSD: tlbhandler.S,v 1.16 2007/05/25 20:58:39 miod Exp $ */ /* * Copyright (c) 1995-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -38,6 +38,8 @@ #include #include +#define HAIRY_R5000_ERRATA + #include "assym.h" .set mips3 @@ -57,6 +59,29 @@ .set noat .ent tlb_miss, 0 tlb_miss: +#ifdef HAIRY_R5000_ERRATA + /* + * R5000 errata: edge cases can trigger a TLB miss exception + * instead of an invalid TLB exception. Servicing the TLB miss + * exception would cause a duplicate TLB to be inserted, which + * causes the processor operation to become unpredictable (but + * very bad for the kernel's health, ten times out of nine). + * + * More details about the problem can be found in: + * http://www.linux-mips.org/archives/linux-mips/2000-02/msg00040.html + * + * We work around the issue by checking for an existing TLB entry, + * and handling this as an invalid TLB exception (as it was intended + * to be), in this case. + */ + tlbp + mfc0 k1, COP_0_TLB_INDEX + bltz k1, 1f # missing! + nop + j k_tlb_inv + nop +1: +#endif PTR_L k1, curprocpaddr dmfc0 k0, COP_0_BAD_VADDR bltz k0, _k_miss # kernel address space @@ -101,6 +126,16 @@ e_tlb_miss: .set noat .ent xtlb_miss, 0 xtlb_miss: +#ifdef HAIRY_R5000_ERRATA + /* See errata comments in tlb_miss above */ + tlbp + mfc0 k1, COP_0_TLB_INDEX + bltz k1, 1f # missing! + nop + j k_tlb_inv + nop +1: +#endif dmfc0 k0, COP_0_BAD_VADDR bltz k0, _k_miss # kernel address space PTR_SRL k0, k0, SEGSHIFT -- cgit v1.2.3