svn commit: r206197 - stable/7/sys/sparc64/sparc64

Marius Strobl marius at FreeBSD.org
Mon Apr 5 18:22:49 UTC 2010


Author: marius
Date: Mon Apr  5 18:22:48 2010
New Revision: 206197
URL: http://svn.freebsd.org/changeset/base/206197

Log:
  MFC: r206086
  
  - Try do deal gracefully with correctable ECC errors.
  - Improve the reporting of unhandled kernel and user traps.

Modified:
  stable/7/sys/sparc64/sparc64/trap.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/sparc64/sparc64/trap.c
==============================================================================
--- stable/7/sys/sparc64/sparc64/trap.c	Mon Apr  5 18:22:42 2010	(r206196)
+++ stable/7/sys/sparc64/sparc64/trap.c	Mon Apr  5 18:22:48 2010	(r206197)
@@ -95,6 +95,7 @@ __FBSDID("$FreeBSD$");
 void trap(struct trapframe *tf);
 void syscall(struct trapframe *tf);
 
+static int trap_cecc(void);
 static int trap_pfault(struct thread *td, struct trapframe *tf);
 
 extern char copy_fault[];
@@ -229,6 +230,10 @@ int debugger_on_signal = 0;
 SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
     &debugger_on_signal, 0, "");
 
+u_int corrected_ecc = 0;
+SYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0,
+    "corrected ECC errors");
+
 /*
  * SUNW,set-trap-table allows to take over %tba from the PROM, which
  * will turn off interrupts and handle outstanding ones while doing so,
@@ -297,10 +302,16 @@ trap(struct trapframe *tf)
 		case T_SPILL:
 			sig = rwindow_save(td);
 			break;
+		case T_CORRECTED_ECC_ERROR:
+			sig = trap_cecc();
+			break;
 		default:
-			if (tf->tf_type < 0 || tf->tf_type >= T_MAX ||
-			    trap_sig[tf->tf_type] == -1)
-				panic("trap: bad trap type");
+			if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
+				panic("trap: bad trap type %#lx (user)",
+				    tf->tf_type);
+			else if (trap_sig[tf->tf_type] == -1)
+				panic("trap: %s (user)",
+				    trap_msg[tf->tf_type]);
 			sig = trap_sig[tf->tf_type];
 			break;
 		}
@@ -389,18 +400,53 @@ trap(struct trapframe *tf)
 			}
 			error = 1;
 			break;
+		case T_CORRECTED_ECC_ERROR:
+			error = trap_cecc();
+			break;
 		default:
 			error = 1;
 			break;
 		}
 
-		if (error != 0)
-			panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]);
+		if (error != 0) {
+			tf->tf_type &= ~T_KERNEL;
+			if (tf->tf_type < 0 || tf->tf_type >= T_MAX)
+				panic("trap: bad trap type %#lx (kernel)",
+				    tf->tf_type);
+			else if (trap_sig[tf->tf_type] == -1)
+				panic("trap: %s (kernel)",
+				    trap_msg[tf->tf_type]);
+		}
 	}
 	CTR1(KTR_TRAP, "trap: td=%p return", td);
 }
 
 static int
+trap_cecc(void)
+{
+	u_long eee;
+
+	/*
+	 * Turn off (non-)correctable error reporting while we're dealing
+	 * with the error.
+	 */
+	eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG);
+	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN |
+	    AA_ESTATE_CEEN));
+	/* Flush the caches in order ensure no corrupt data got installed. */
+	cache_flush();
+	/* Ensure the caches are still turned on (should be). */
+	cache_enable(PCPU_GET(impl));
+	/* Clear the the error from the AFSR. */
+	stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR));
+	corrected_ecc++;
+	printf("corrected ECC error\n");
+	/* Turn (non-)correctable error reporting back on. */
+	stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee);
+	return (0);
+}
+
+static int
 trap_pfault(struct thread *td, struct trapframe *tf)
 {
 	struct vmspace *vm;


More information about the svn-src-stable-7 mailing list