summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorjc25722 <none@none>2006-09-29 04:43:00 -0700
committerjc25722 <none@none>2006-09-29 04:43:00 -0700
commit2f48339a0c14421b8826b39fc3ab783a064cb77b (patch)
treeff49f79c47a10ee893d144e58146a55cd1bbc2db /usr/src
parent731b94c18e9b5138386b0074dc75321a7edf0fb4 (diff)
downloadillumos-joyent-2f48339a0c14421b8826b39fc3ab783a064cb77b.tar.gz
6371709 Events with different AFARs should be treated as separate events
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c21
-rw-r--r--usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h8
-rw-r--r--usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c28
-rw-r--r--usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c24
-rw-r--r--usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c113
5 files changed, 139 insertions, 55 deletions
diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c
index f240974776..8af910607c 100644
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c
@@ -1239,22 +1239,32 @@ cmd_xxcu_train_match(cmd_errcl_t mask)
return (0);
}
-
+/*
+ * Search for the entry that matches the ena and the AFAR
+ * if we have a valid AFAR, otherwise just match the ENA
+ */
cmd_xxcu_trw_t *
-cmd_trw_lookup(uint64_t ena)
+cmd_trw_lookup(uint64_t ena, uint8_t afar_status, uint64_t afar)
{
int i;
- for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) {
+ if (afar_status == AFLT_STAT_VALID) {
+ for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) {
+ if (cmd.cmd_xxcu_trw[i].trw_ena == ena &&
+ cmd.cmd_xxcu_trw[i].trw_afar == afar)
+ return (&cmd.cmd_xxcu_trw[i]);
+ }
+ } else {
+ for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) {
if (cmd.cmd_xxcu_trw[i].trw_ena == ena)
return (&cmd.cmd_xxcu_trw[i]);
+ }
}
-
return (NULL);
}
cmd_xxcu_trw_t *
-cmd_trw_alloc(uint64_t ena)
+cmd_trw_alloc(uint64_t ena, uint64_t afar)
{
int i;
@@ -1262,6 +1272,7 @@ cmd_trw_alloc(uint64_t ena)
cmd_xxcu_trw_t *trw = &cmd.cmd_xxcu_trw[i];
if (trw->trw_ena == NULL) {
trw->trw_ena = ena;
+ trw->trw_afar = afar;
return (trw);
}
}
diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h
index c9ff6ac050..5c88d6cc4c 100644
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.h
@@ -205,6 +205,7 @@ extern void cmd_cpu_uec_set_allmatch(fmd_hdl_t *, cmd_cpu_t *);
typedef struct cmd_xxcu_trw {
uint64_t trw_ena; /* the ENA for this group of ereports */
+ uint64_t trw_afar; /* the AFAR for this group of ereports */
cmd_errcl_t trw_mask; /* ereports seen thus far with this ENA */
uint16_t trw_cpuid; /* CPU to which this watcher belongs */
uint8_t trw_ref; /* number of ereports with this ENA */
@@ -212,8 +213,8 @@ typedef struct cmd_xxcu_trw {
uint32_t trw_pad;
} cmd_xxcu_trw_t;
-extern cmd_xxcu_trw_t *cmd_trw_lookup(uint64_t);
-extern cmd_xxcu_trw_t *cmd_trw_alloc(uint64_t);
+extern cmd_xxcu_trw_t *cmd_trw_lookup(uint64_t, uint8_t, uint64_t);
+extern cmd_xxcu_trw_t *cmd_trw_alloc(uint64_t, uint64_t);
extern void cmd_trw_restore(fmd_hdl_t *);
extern void cmd_trw_write(fmd_hdl_t *);
extern void cmd_trw_ref(fmd_hdl_t *, cmd_xxcu_trw_t *, cmd_errcl_t);
@@ -663,6 +664,9 @@ extern int cmd_cpu_synd_check(uint16_t);
extern int cmd_cpu_synd_check(uint32_t);
#endif /* sun4u */
+extern int cmd_afar_valid(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_errcl_t,
+ uint64_t *afar);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c
index 65effd3def..4e1891898e 100644
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpuerr.c
@@ -352,9 +352,17 @@ cmd_xxcu_resolve(fmd_hdl_t *hdl, cmd_xr_t *xr, fmd_event_t *ep,
{
cmd_xxcu_trw_t *trw;
cmd_errcl_t cause;
+ uint64_t afar;
- if ((trw = cmd_trw_lookup(xr->xr_ena)) == NULL) {
- hdlr(hdl, xr, ep);
+
+ afar = NULL;
+
+ if (xr->xr_afar_status == AFLT_STAT_VALID)
+ afar = xr->xr_afar;
+
+ if ((trw = cmd_trw_lookup(xr->xr_ena,
+ xr->xr_afar_status, afar)) == NULL) {
+ fmd_hdl_debug(hdl, "cmd_trw_lookup: Not found\n");
return;
}
@@ -414,7 +422,9 @@ cmd_xxcu_initial(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
cmd_cpu_t *cpu;
cmd_xr_t *xr;
uint64_t ena;
+ uint64_t afar;
uint8_t level = clcode & CMD_ERRCL_LEVEL_EXTRACT;
+ uint8_t afar_status;
clcode &= CMD_ERRCL_LEVEL_MASK; /* keep level bits out of train masks */
@@ -428,11 +438,21 @@ cmd_xxcu_initial(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
(void) nvlist_lookup_uint64(nvl, FM_EREPORT_ENA, &ena);
+ if (cmd_afar_valid(hdl, nvl, clcode, &afar) != 0) {
+ afar_status = AFLT_STAT_INVALID;
+ afar = NULL;
+ } else {
+ afar_status = AFLT_STAT_VALID;
+ }
+
fmd_hdl_debug(hdl, "scheduling %s (%llx) for redelivery\n",
class, clcode);
+ fmd_hdl_debug(hdl, "looking up ena %llx,afar %llx with\n", ena, afar);
+
+ fmd_hdl_debug(hdl, "afar status of %02x\n", afar_status);
- if ((trw = cmd_trw_lookup(ena)) == NULL) {
- if ((trw = cmd_trw_alloc(ena)) == NULL) {
+ if ((trw = cmd_trw_lookup(ena, afar_status, afar)) == NULL) {
+ if ((trw = cmd_trw_alloc(ena, afar)) == NULL) {
fmd_hdl_debug(hdl, "failed to get new trw\n");
goto redeliver;
}
diff --git a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c
index 9f07d1b878..7ae7fae7b9 100644
--- a/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c
+++ b/usr/src/cmd/fm/modules/sun4u/cpumem-diagnosis/cmd_cpu_arch.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -79,3 +78,20 @@ cmd_cpu_synd_check(uint16_t synd)
else
return (0);
}
+int
+cmd_afar_valid(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_errcl_t clcode,
+ uint64_t *afar)
+{
+ uint8_t afar_status;
+
+ if (nvlist_lookup_uint8(nvl,
+ FM_EREPORT_PAYLOAD_NAME_AFAR_STATUS, &afar_status) == 0) {
+ if (afar_status == AFLT_STAT_VALID) {
+ (void) nvlist_lookup_uint64(nvl,
+ FM_EREPORT_PAYLOAD_NAME_AFAR, afar);
+ return (0);
+ } else
+ return (-1);
+ }
+ return (-1);
+}
diff --git a/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c b/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c
index 6fa9378c69..1e2361c482 100644
--- a/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c
+++ b/usr/src/cmd/fm/modules/sun4v/cpumem-diagnosis/cmd_cpu_arch.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,6 +44,8 @@
#include <sys/fm/cpu/UltraSPARC-T1.h>
#include <sys/niagararegs.h>
+int cmd_afsr_check(fmd_hdl_t *, uint64_t, cmd_errcl_t, uint8_t *);
+
int
cmd_xr_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr, cmd_errcl_t clcode)
{
@@ -60,6 +61,42 @@ cmd_xr_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr, cmd_errcl_t clcode)
&xr->xr_synd) != 0)
return (-1);
+ if (cmd_afsr_check(hdl, niagara_l2_afsr, clcode,
+ &xr->xr_synd_status) != 0)
+ return (-1);
+
+ xr->xr_afar_status = xr->xr_synd_status;
+ return (0);
+}
+
+int
+cmd_cpu_synd_check(uint32_t synd)
+{
+ int i;
+
+ /*
+ * Niagara L2 fetches from a memory location containing a UE
+ * are given a poison syndrome in one or more 7 bit subsyndromes
+ * each covering one of 4 4 byte checkwords.
+ *
+ * 0 is an invalid syndrome because it denotes no error, but
+ * is associated with an ereport -- meaning there WAS an error.
+ */
+ if (synd == 0)
+ return (-1);
+
+ for (i = 0; i < 4; i++) {
+ if (((synd >> i*NI_L2_POISON_SYND_SIZE) &
+ NI_L2_POISON_SYND_MASK) == NI_L2_POISON_SYND_FROM_DAU)
+ return (-1);
+ }
+ return (0);
+}
+
+int
+cmd_afsr_check(fmd_hdl_t *hdl, uint64_t afsr,
+ cmd_errcl_t clcode, uint8_t *stat_val)
+{
/*
* Set Niagara afar and synd validity.
* For a given set of error registers, the payload value is valid iff
@@ -69,65 +106,61 @@ cmd_xr_fill(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_xr_t *xr, cmd_errcl_t clcode)
switch (clcode) {
case CMD_ERRCL_LDAU:
case CMD_ERRCL_LDSU:
- xr->xr_synd_status =
- ((niagara_l2_afsr & NI_L2AFSR_P02) == 0) ?
- AFLT_STAT_VALID : AFLT_STAT_INVALID;
+ *stat_val =
+ ((afsr & NI_L2AFSR_P02) == 0) ?
+ AFLT_STAT_VALID: AFLT_STAT_INVALID;
break;
case CMD_ERRCL_LDWU:
- xr->xr_synd_status =
- ((niagara_l2_afsr & NI_L2AFSR_P03) == 0) ?
- AFLT_STAT_VALID : AFLT_STAT_INVALID;
+ *stat_val =
+ ((afsr & NI_L2AFSR_P03) == 0) ?
+ AFLT_STAT_VALID : AFLT_STAT_INVALID;
break;
case CMD_ERRCL_LDRU:
- xr->xr_synd_status =
- ((niagara_l2_afsr & NI_L2AFSR_P04) == 0) ?
- AFLT_STAT_VALID : AFLT_STAT_INVALID;
+ *stat_val =
+ ((afsr & NI_L2AFSR_P04) == 0) ?
+ AFLT_STAT_VALID : AFLT_STAT_INVALID;
break;
case CMD_ERRCL_LDAC:
case CMD_ERRCL_LDSC:
- xr->xr_synd_status =
- ((niagara_l2_afsr & NI_L2AFSR_P07) == 0) ?
- AFLT_STAT_VALID : AFLT_STAT_INVALID;
+ *stat_val =
+ ((afsr & NI_L2AFSR_P07) == 0) ?
+ AFLT_STAT_VALID : AFLT_STAT_INVALID;
break;
case CMD_ERRCL_LDWC:
- xr->xr_synd_status =
- ((niagara_l2_afsr & NI_L2AFSR_P08) == 0) ?
- AFLT_STAT_VALID : AFLT_STAT_INVALID;
+ *stat_val =
+ ((afsr & NI_L2AFSR_P08) == 0) ?
+ AFLT_STAT_VALID : AFLT_STAT_INVALID;
break;
case CMD_ERRCL_LDRC:
- xr->xr_synd_status =
- ((niagara_l2_afsr & NI_L2AFSR_P09) == 0) ?
- AFLT_STAT_VALID : AFLT_STAT_INVALID;
+ *stat_val =
+ ((afsr & NI_L2AFSR_P09) == 0) ?
+ AFLT_STAT_VALID : AFLT_STAT_INVALID;
break;
default:
fmd_hdl_debug(hdl, "Niagara unrecognized l2cache error\n");
- xr->xr_synd_status = 0;
return (-1);
}
- xr->xr_afar_status = xr->xr_synd_status;
return (0);
}
+
int
-cmd_cpu_synd_check(uint32_t synd)
+cmd_afar_valid(fmd_hdl_t *hdl, nvlist_t *nvl, cmd_errcl_t clcode,
+ uint64_t *afar)
{
- int i;
+ uint64_t niagara_l2_afsr = 0;
+ uint8_t stat_val;
+ if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_NAME_L2_AFSR,
+ &niagara_l2_afsr) != 0)
+ return (-1);
- /*
- * Niagara L2 fetches from a memory location containing a UE
- * are given a poison syndrome in one or more 7 bit subsyndromes
- * each covering one of 4 4 byte checkwords.
- *
- * 0 is an invalid syndrome because it denotes no error, but
- * is associated with an ereport -- meaning there WAS an error.
- */
- if (synd == 0)
+ if (cmd_afsr_check(hdl, niagara_l2_afsr, clcode, &stat_val) != 0)
return (-1);
- for (i = 0; i < 4; i++) {
- if (((synd >> i*NI_L2_POISON_SYND_SIZE) &
- NI_L2_POISON_SYND_MASK) == NI_L2_POISON_SYND_FROM_DAU)
- return (-1);
+ if (stat_val == AFLT_STAT_VALID) {
+ if (nvlist_lookup_uint64(nvl,
+ FM_EREPORT_PAYLOAD_NAME_L2_REAL_AFAR, afar) == 0)
+ return (0);
}
- return (0);
+ return (-1);
}