changeset 10034:5a676578aeda

6853745 Same ereport is generated every 10 seconds automatically in looping after error injection
author Vuong Nguyen <Vuong.Nguyen@Sun.COM>
date Fri, 03 Jul 2009 12:07:36 -0400
parents fbf01e219914
children 9c430ac1464a
files usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c
diffstat 1 files changed, 26 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c	Fri Jul 03 05:51:28 2009 +0530
+++ b/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c	Fri Jul 03 12:07:36 2009 -0400
@@ -1563,7 +1563,10 @@
 	gcpu_bank_logout_t *gbl, *pgbl;
 	uint64_t status;
 
-	for (i = first, gbl = &gcl->gcl_data[first]; i < last; i++, gbl++) {
+	if (first < 0 || last < 0)
+		return;
+
+	for (i = first, gbl = &gcl->gcl_data[first]; i <= last; i++, gbl++) {
 		status = gbl->gbl_status;
 		if (status == 0)
 			continue;
@@ -1658,7 +1661,7 @@
 	gcpu_data_t *gcpu = cmi_hdl_getcmidata(hdl);
 	gcpu_mca_t *mca = &gcpu->gcpu_mca;
 	int nbanks = mca->gcpu_mca_nbanks;
-	gcpu_bank_logout_t *gbl;
+	gcpu_bank_logout_t *gbl, *pgbl;
 	gcpu_logout_t *gcl, *pgcl;
 	int ismc = (rp != NULL);
 	int ispoll = !ismc;
@@ -1667,8 +1670,8 @@
 	uint64_t mcg_status;
 	uint64_t disp;
 	uint64_t cap;
-	int first = 0;
-	int last = 0;
+	int first = -1;
+	int last = -1;
 	int willpanic = 0;
 
 	if (cmi_hdl_rdmsr(hdl, IA32_MSR_MCG_STATUS, &mcg_status) !=
@@ -1735,7 +1738,8 @@
 		if (!(status & MSR_MC_STATUS_VAL))
 			continue;
 
-		if (first == 0)
+		/* First and last bank that have valid status */
+		if (first < 0)
 			first = i;
 		last = i;
 
@@ -1788,6 +1792,23 @@
 		gbl->gbl_status = status;
 		gbl->gbl_addr = addr;
 		gbl->gbl_misc = misc;
+
+		/*
+		 * For polled observation, if the count of deferred status
+		 * clears updated in the clear_mc() is nonzero and the
+		 * MCi_STATUS has not changed, the last wakeup has produced
+		 * the ereport of the error. Therefore, clear the status in
+		 * this wakeup to avoid duplicate ereport.
+		 */
+		pgbl = &pgcl->gcl_data[i];
+		if (!isxpv && ispoll && IS_MCE_CANDIDATE(status) &&
+		    pgbl->gbl_clrdefcnt != 0) {
+			if (STATUS_EQV(status, pgcl->gcl_data[i].gbl_status)) {
+				gbl->gbl_status = 0;
+				(void) cmi_hdl_wrmsr(hdl,
+				    IA32_MSR_MC(i, STATUS), 0ULL);
+			}
+		}
 	}
 
 	if (gcpu_mca_stack_flag)