Skip to contentSkip to conversation

Extended H/W error log driver

PATCH Superseded Chen, Gong 7 participants 85 messages Oct 11, 2013 – Oct 18, 2013

Subsystems (5)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Chen, Gong

author
#0 lore raw

[PATCH 1/8] ACPI, APEI, CPER: Fix status check during error printing [PATCH 2/8] ACPI, CPER: Update cper info
[PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform [PATCH 4/8] DMI: Parse memory device (type 17) in SMBIOS [PATCH 5/8] ACPI, APEI, CPER: Add UEFI 2.4 support for memory error [PATCH 6/8] ACPI, APEI, CPER: Enhance memory reporting capability [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

This patch series adds an enhanced MCA event logging driver provided by Intel.
Please refer to this link: htpp://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html

Certain usages such as Predictive Failure Analysis (PFA) require more information about the error than what can be described in processor machine check banks. Most server processors log additional information about the error in processor uncore registers. Since the addresses and layout of these registers vary widely from one processor to another, system software cannot readily make use of them. To complicate matters further, some of the additionalerror information cannot be constructed without detailed knowledge about platform topology. This enhanced MCA logging driver allows firmware to provide additional error information to MCE/CMCI handler and thus addresses this gap.

After applying this patch series, when a memory corrected error happens, we can get following information:

dmesg output:

[56005.785917] {3}Hardware error detected on CPU0
[56005.785959] {3}event severity: corrected
[56005.785975] {3}sub_event[0], severity: corrected
[56005.785977] {3}section_type: memory error
[56005.785981] {3}physical_address: 0x0000000851fe0000
[56005.786027] {3}DIMM location: Memriser1 CHANNEL A DIMM 0
[56005.786154] {4}Hardware error detected on CPU0
[56005.786159] {4}event severity: corrected
[56005.786162] {4}sub_event[0], severity: corrected
[56005.786166] {4}section_type: memory error

trace output:

# tracer: nop
#
# entries-in-buffer/entries-written: 4/4 #P:120
#
# _-----=> irqs-off
# / _----=> need-resched

#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
...
...
          <idle>-0     [000] d.h. 56068.488759: extlog_mem_event: 3 corrected errors:unknown on Memriser1 CHANNEL A DIMM 0(FRU: 00000000-0000-0000-0000-000000000000  physical addr: 0x0000000851fe0000 node: 0 card: 0 module: 0 rank: 0 bank: 0 row: 28927 column: 1296)
          <idle>-0     [000] d.h. 56068.488834: extlog_mem_event: 4 corrected errors:unknown

...
...

dmesg output are shrank to only keep the most important data. The trace output will contain most of data. Not sure if all fields are meaningful to users. Some fields like FRU ID/FRU TEXT depends on BIOS manufactor. So welcome to add comments for what is needed or not.

author
#1 lore raw

PATCH 1/8 ACPI, APEI, CPER: Fix status check during error printing

Commit aaf9d93 only catches condition check before print, but the similar check is needed during printing CPER error sections.

---
 drivers/acpi/apei/cper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/apei/cper.c +1 -1
index 33dc6a0..f827f02 100644
@@ -353,7 +353,7 @@ void apei_estatus_print(const char *pfx,
 	       cper_severity_str(severity));
 	data_len = estatus->data_length;
 	gdata = (struct acpi_hest_generic_data *)(estatus + 1);
-	while (data_len > sizeof(*gdata)) {
+	while (data_len >= sizeof(*gdata)) {
 		gedata_len = gdata->error_data_length;
 		apei_estatus_print_section(pfx, gdata, sec_no);
 		data_len -= gedata_len + sizeof(*gdata);
Signature · 1 line
1.8.4.rc3
maintainer Reviewed-by on v1 1/8
#2 lore raw

Re: [PATCH 1/8] ACPI, APEI, CPER: Fix status check during error printing

Quoted 5 lines · Gong

Commit aaf9d93 only catches condition check before print, but the similar check is needed during printing CPER error sections.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#3 lore raw

PATCH 2/8 ACPI, CPER: Update cper info

In reply to Chen, Gong

To satisfy the necessary of following patches and make related definition more clear, update some definitions about CPER. No functional changes.

---
 drivers/acpi/apei/apei-internal.h | 12 ++++-----
 drivers/acpi/apei/cper.c          | 46 ++++++++++++++++-----------------
 drivers/acpi/apei/ghes.c          | 54 +++++++++++++++++++--------------------
 include/acpi/actbl1.h             | 14 +++++-----
 include/acpi/ghes.h               |  2 +-
 5 files changed, 64 insertions(+), 64 deletions(-)
drivers/acpi/apei/apei-internal.h +6 -6
index f220d64..21ba34a 100644
@@ -122,11 +122,11 @@ struct dentry;
 struct dentry *apei_get_debugfs_dir(void);
 
 #define apei_estatus_for_each_section(estatus, section)			\
-	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\
+	for (section = (struct acpi_generic_data *)(estatus + 1);	\
 	     (void *)section - (void *)estatus < estatus->data_length;	\
 	     section = (void *)(section+1) + section->error_data_length)
 
-static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
+static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
 {
 	if (estatus->raw_data_length)
 		return estatus->raw_data_offset + \
@@ -135,10 +135,10 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
 		return sizeof(*estatus) + estatus->data_length;
 }
 
-void apei_estatus_print(const char *pfx,
-			const struct acpi_hest_generic_status *estatus);
-int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
-int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
+void cper_estatus_print(const char *pfx,
+			const struct acpi_generic_status *estatus);
+int cper_estatus_check_header(const struct acpi_generic_status *estatus);
+int cper_estatus_check(const struct acpi_generic_status *estatus);
 
 int apei_osc_setup(void);
 #endif
drivers/acpi/apei/cper.c +23 -23

119 lines not on this page · raw message

drivers/acpi/apei/ghes.c +27 -27

190 lines not on this page · raw message

include/acpi/actbl1.h +7 -7
index 0bd750e..3c62a0a 100644
@@ -596,7 +596,7 @@ struct acpi_hest_generic {
 
 /* Generic Error Status block */
 
-struct acpi_hest_generic_status {
+struct acpi_generic_status {
 	u32 block_status;
 	u32 raw_data_offset;
 	u32 raw_data_length;
@@ -606,15 +606,15 @@ struct acpi_hest_generic_status {
 
 /* Values for block_status flags above */
 
-#define ACPI_HEST_UNCORRECTABLE             (1)
-#define ACPI_HEST_CORRECTABLE               (1<<1)
-#define ACPI_HEST_MULTIPLE_UNCORRECTABLE    (1<<2)
-#define ACPI_HEST_MULTIPLE_CORRECTABLE      (1<<3)
-#define ACPI_HEST_ERROR_ENTRY_COUNT         (0xFF<<4)	/* 8 bits, error count */
+#define ACPI_GEN_ERR_UC			(1)
+#define ACPI_GEN_ERR_CE			(1<<1)
+#define ACPI_GEN_ERR_MULTI_UC		(1<<2)
+#define ACPI_GEN_ERR_MULTI_CE		(1<<3)
+#define ACPI_GEN_ERR_COUNT_SHIFT	(0xFF<<4) /* 8 bits, error count */
 
 /* Generic Error Data entry */
 
-struct acpi_hest_generic_data {
+struct acpi_generic_data {
 	u8 section_type[16];
 	u32 error_severity;
 	u16 revision;
include/acpi/ghes.h +1 -1
index 720446c..dfd60d0 100644
@@ -14,7 +14,7 @@
 
 struct ghes {
 	struct acpi_hest_generic *generic;
-	struct acpi_hest_generic_status *estatus;
+	struct acpi_generic_status *estatus;
 	u64 buffer_paddr;
 	unsigned long flags;
 	union {
Signature · 1 line
1.8.4.rc3
maintainer
#4 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 1 line · Gong

To satisfy the necessary of following patches and make related definition

"To prepare for the following patches... " you mean?

Quoted 10 lines

more clear, update some definitions about CPER. No functional changes.

---
 drivers/acpi/apei/apei-internal.h | 12 ++++-----
 drivers/acpi/apei/cper.c          | 46 ++++++++++++++++-----------------
 drivers/acpi/apei/ghes.c          | 54 +++++++++++++++++++--------------------
 include/acpi/actbl1.h             | 14 +++++-----
 include/acpi/ghes.h               |  2 +-
 5 files changed, 64 insertions(+), 64 deletions(-)

[ … ]

Quoted 23 lines
drivers/acpi/apei/cper.c +2 -2
index f827f02..b2e4134 100644
@@ -5,7 +5,7 @@
  *	Author: Huang Ying <[email protected]>
  *
  * CPER is the format used to describe platform hardware error by
- * various APEI tables, such as ERST, BERT and HEST etc.
+ * various tables, such as ERST, BERT and HEST etc.
  *
  * For more information about CPER, please refer to Appendix N of UEFI
  * Specification version 2.3.
@@ -248,7 +248,7 @@ static const char *cper_pcie_port_type_strs[] = {
 };
 
 static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
-			    const struct acpi_hest_generic_data *gdata)
+			    const struct acpi_generic_data *gdata)
 {
 	if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
 		printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,

drivers/acpi/apei/cper.c static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, · line 286

Quoted 5 lines
drivers/acpi/apei/cper.c +1 -1
@@ -283,17 +283,17 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
 	pfx, pcie->bridge.secondary_status, pcie->bridge.control);
 }
 
-static const char *apei_estatus_section_flag_strs[] = {
+static const char *cper_estatus_section_flag_strs[] = {

"static const char * const" while at it.

Btw, please run your patches through checkpatch.pl - it does catch things like that.

drivers/acpi/apei/cper.c static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, · line 290

Quoted 5 lines
drivers/acpi/apei/cper.c +1 -1
 	"primary",
 	"containment warning",
 	"reset",
-	"threshold exceeded",
+	"error threshold exceeded",

Right, this string is user-visible so if we have to be absolutely honest, the patch does add "functional changes" so you can remove the statement from the commit message. :)

Quoted 29 lines
drivers/acpi/apei/cper.c +5 -6
 	"resource not accessible",
 	"latent error",
 };
 
-static void apei_estatus_print_section(
-	const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
+static void cper_estatus_print_section(
+	const char *pfx, const struct acpi_generic_data *gdata, int sec_no)
 {
 	uuid_le *sec_type = (uuid_le *)gdata->section_type;
 	__u16 severity;
@@ -302,8 +302,8 @@ static void apei_estatus_print_section(
 	printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity,
 	       cper_severity_str(severity));
 	printk("%s""flags: 0x%02x\n", pfx, gdata->flags);
-	cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs,
-			ARRAY_SIZE(apei_estatus_section_flag_strs));
+	cper_print_bits(pfx, gdata->flags, cper_estatus_section_flag_strs,
+			ARRAY_SIZE(cper_estatus_section_flag_strs));
 	if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
 		printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
 	if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
@@ -339,34 +339,34 @@ err_section_too_small:
 	pr_err(FW_WARN "error section length is too small\n");
 }
 
-void apei_estatus_print(const char *pfx,
-			const struct acpi_hest_generic_status *estatus)
+void cper_estatus_print(const char *pfx,

drivers/acpi/apei/cper.c err_section_too_small: · line 350

Quoted 10 lines
drivers/acpi/apei/cper.c +3 -2
+			const struct acpi_generic_status *estatus)
 {
-	struct acpi_hest_generic_data *gdata;
+	struct acpi_generic_data *gdata;
 	unsigned int data_len, gedata_len;
 	int sec_no = 0;
 	__u16 severity;
 
-	printk("%s""APEI generic hardware error status\n", pfx);
+	printk("%s""Generic Hardware Error Status\n", pfx);

Btw, what's the story with printk not using KERN_x levels in this file? Why are we falling back to default printk levels for all printks here and shouldn't we rather prioritize them by urgency into, say, KERN_ERR, KERN_INFO, etc?

Quoted 17 lines
drivers/acpi/apei/cper.c +3 -3
 	severity = estatus->error_severity;
 	printk("%s""severity: %d, %s\n", pfx, severity,
 	       cper_severity_str(severity));
 	data_len = estatus->data_length;
-	gdata = (struct acpi_hest_generic_data *)(estatus + 1);
+	gdata = (struct acpi_generic_data *)(estatus + 1);
 	while (data_len >= sizeof(*gdata)) {
 		gedata_len = gdata->error_data_length;
-		apei_estatus_print_section(pfx, gdata, sec_no);
+		cper_estatus_print_section(pfx, gdata, sec_no);
 		data_len -= gedata_len + sizeof(*gdata);
 		gdata = (void *)(gdata + 1) + gedata_len;
 		sec_no++;
 	}
 }
-EXPORT_SYMBOL_GPL(apei_estatus_print);
+EXPORT_SYMBOL_GPL(cper_estatus_print);

[ ... ]

Quoted 16 lines
include/acpi/actbl1.h +1 -1
index 0bd750e..3c62a0a 100644
@@ -596,7 +596,7 @@ struct acpi_hest_generic {
 
 /* Generic Error Status block */
 
-struct acpi_hest_generic_status {
+struct acpi_generic_status {
 	u32 block_status;
 	u32 raw_data_offset;
 	u32 raw_data_length;
@@ -606,15 +606,15 @@ struct acpi_hest_generic_status {
 
 /* Values for block_status flags above */

include/acpi/actbl1.h struct acpi_hest_generic_status { · line 612

Quoted 10 lines
include/acpi/actbl1.h +4 -5
 
-#define ACPI_HEST_UNCORRECTABLE             (1)
-#define ACPI_HEST_CORRECTABLE               (1<<1)
-#define ACPI_HEST_MULTIPLE_UNCORRECTABLE    (1<<2)
-#define ACPI_HEST_MULTIPLE_CORRECTABLE      (1<<3)
-#define ACPI_HEST_ERROR_ENTRY_COUNT         (0xFF<<4)	/* 8 bits, error count */
+#define ACPI_GEN_ERR_UC			(1)
+#define ACPI_GEN_ERR_CE			(1<<1)
+#define ACPI_GEN_ERR_MULTI_UC		(1<<2)
+#define ACPI_GEN_ERR_MULTI_CE		(1<<3)

Those can simply use BIT().

include/acpi/actbl1.h struct acpi_hest_generic_status { · line 613

Quoted 1 line
include/acpi/actbl1.h +1 -0
+#define ACPI_GEN_ERR_COUNT_SHIFT	(0xFF<<4) /* 8 bits, error count */

Other than the above nits, a patch which slims down struct names and makes them more concrete is always welcome :)

Thanks.

Signature · 9 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
maintainer
#5 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 7 lines · Borislav Petkov

drivers/acpi/apei/cper.c err_section_too_small: · line 350

Quoted 2 lines
drivers/acpi/apei/cper.c +1 -1
-	printk("%s""APEI generic hardware error status\n", pfx);
+	printk("%s""Generic Hardware Error Status\n", pfx);

Btw, what's the story with printk not using KERN_x levels in this file? Why are we falling back to default printk levels for all printks here and shouldn't we rather prioritize them by urgency into, say, KERN_ERR, KERN_INFO, etc?

Ignore that - checkpatch complained about it but I kinda missed that we're handing down the prefix.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#6 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 11 lines · Borislav Petkov
Quoted 7 lines · Borislav Petkov

drivers/acpi/apei/cper.c err_section_too_small: · line 350

Quoted 2 lines
drivers/acpi/apei/cper.c +1 -1
-	printk("%s""APEI generic hardware error status\n", pfx);
+	printk("%s""Generic Hardware Error Status\n", pfx);

Btw, what's the story with printk not using KERN_x levels in this file? Why are we falling back to default printk levels for all printks here and shouldn't we rather prioritize them by urgency into, say, KERN_ERR, KERN_INFO, etc?

Ignore that - checkpatch complained about it but I kinda missed that we're handing down the prefix.

I think it'd be better to rename pfx to level
as that's what printk.h calls them.

author
#7 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 18 lines · Joe Perches

Date: Tue, 15 Oct 2013 18:57:18 -0700
From: Joe Perches <[email protected]>
To: Borislav Petkov <[email protected]>
Cc: "Chen, Gong" <[email protected]>, [email protected],
[email protected], [email protected]
Subject: Re: [PATCH 2/8] ACPI, CPER: Update cper info
X-Mailer: Evolution 3.6.4-0ubuntu1

Quoted 9 lines · Borislav Petkov
Quoted 7 lines · Borislav Petkov

drivers/acpi/apei/cper.c err_section_too_small: · line 350

Quoted 2 lines
drivers/acpi/apei/cper.c +1 -1
-	printk("%s""APEI generic hardware error status\n", pfx);
+	printk("%s""Generic Hardware Error Status\n", pfx);

Btw, what's the story with printk not using KERN_x levels in this file? Why are we falling back to default printk levels for all printks here and shouldn't we rather prioritize them by urgency into, say, KERN_ERR, KERN_INFO, etc?

Quoted 6 lines
Quoted 2 lines

Ignore that - checkpatch complained about it but I kinda missed that we're handing down the prefix.

I think it'd be better to rename pfx to level as that's what printk.h calls them.

No. pfx includes log level and prefix string both.

Quoted 2 lines
#8 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 19 lines · Chen Gong
Quoted 18 lines · Joe Perches

Date: Tue, 15 Oct 2013 18:57:18 -0700
From: Joe Perches <[email protected]>
To: Borislav Petkov <[email protected]>
Cc: "Chen, Gong" <[email protected]>, [email protected],
[email protected], [email protected]
Subject: Re: [PATCH 2/8] ACPI, CPER: Update cper info
X-Mailer: Evolution 3.6.4-0ubuntu1

Quoted 9 lines · Borislav Petkov
Quoted 7 lines · Borislav Petkov

drivers/acpi/apei/cper.c err_section_too_small: · line 350

Quoted 2 lines
drivers/acpi/apei/cper.c +1 -1
-	printk("%s""APEI generic hardware error status\n", pfx);
+	printk("%s""Generic Hardware Error Status\n", pfx);

Btw, what's the story with printk not using KERN_x levels in this file? Why are we falling back to default printk levels for all printks here and shouldn't we rather prioritize them by urgency into, say, KERN_ERR, KERN_INFO, etc?

Quoted 7 lines
Quoted 6 lines
Quoted 2 lines

Ignore that - checkpatch complained about it but I kinda missed that we're handing down the prefix.

I think it'd be better to rename pfx to level as that's what printk.h calls them.

No. pfx includes log level and prefix string both.

Perhaps it'd be better to separate them.

I haven't looked too hard, but is apei_status_print the only place it's used with more than KERN_<LEVEL>?

#9 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

In reply to Chen, Gong
Quoted 17 lines · Chen Gong

To satisfy the necessary of following patches and make related definition more clear, update some definitions about CPER. No functional changes.

---
 drivers/acpi/apei/apei-internal.h | 12 ++++-----
 drivers/acpi/apei/cper.c          | 46 ++++++++++++++++-----------------
 drivers/acpi/apei/ghes.c          | 54 +++++++++++++++++++--------------------
 include/acpi/actbl1.h             | 14 +++++-----
 include/acpi/ghes.h               |  2 +-
 5 files changed, 64 insertions(+), 64 deletions(-)
drivers/acpi/apei/apei-internal.h +0 -0
index f220d64..21ba34a 100644

drivers/acpi/apei/apei-internal.h struct dentry; · line 125

Quoted 5 lines
drivers/acpi/apei/apei-internal.h +1 -1
@@ -122,11 +122,11 @@ struct dentry;
 struct dentry *apei_get_debugfs_dir(void);
 
 #define apei_estatus_for_each_section(estatus, section)			\
-	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\
+	for (section = (struct acpi_generic_data *)(estatus + 1);	\

This is a good one to rename, though I wonder if acpi_generic_error_data is more appropriate?

drivers/acpi/apei/apei-internal.h struct dentry; · line 129

Quoted 5 lines
drivers/acpi/apei/apei-internal.h +1 -1
 	     (void *)section - (void *)estatus < estatus->data_length;	\
 	     section = (void *)(section+1) + section->error_data_length)
 
-static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
+static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)

Not sure I understand the rationale for these changes - we are still dealing with ACPI/APEI generic error status/data structures. So, why the cper_ prefix?

Quoted 5 lines
drivers/acpi/apei/apei-internal.h +0 -0
 {
 	if (estatus->raw_data_length)
 		return estatus->raw_data_offset + \
@@ -135,10 +135,10 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
 		return sizeof(*estatus) + estatus->data_length;

drivers/acpi/apei/apei-internal.h static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) · line 141

Quoted 10 lines
drivers/acpi/apei/apei-internal.h +4 -4
 }
 
-void apei_estatus_print(const char *pfx,
-			const struct acpi_hest_generic_status *estatus);
-int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
-int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
+void cper_estatus_print(const char *pfx,
+			const struct acpi_generic_status *estatus);
+int cper_estatus_check_header(const struct acpi_generic_status *estatus);
+int cper_estatus_check(const struct acpi_generic_status *estatus);

Same here. All the above functions work on ACPI structures...

drivers/acpi/apei/apei-internal.h static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)

Quoted 12 lines
drivers/acpi/apei/apei-internal.h +5 -5
 /* Values for block_status flags above */
 
-#define ACPI_HEST_UNCORRECTABLE             (1)
-#define ACPI_HEST_CORRECTABLE               (1<<1)
-#define ACPI_HEST_MULTIPLE_UNCORRECTABLE    (1<<2)
-#define ACPI_HEST_MULTIPLE_CORRECTABLE      (1<<3)
-#define ACPI_HEST_ERROR_ENTRY_COUNT         (0xFF<<4)	/* 8 bits, error count */
+#define ACPI_GEN_ERR_UC			(1)
+#define ACPI_GEN_ERR_CE			(1<<1)
+#define ACPI_GEN_ERR_MULTI_UC		(1<<2)
+#define ACPI_GEN_ERR_MULTI_CE		(1<<3)
+#define ACPI_GEN_ERR_COUNT_SHIFT	(0xFF<<4) /* 8 bits, error count */

I'd prefer ACPI_GENERIC_ERR_ since ACPI_GEN_ERR sounds far too much like ACPI "Generated" :)

Thanks,
Naveen

author
#10 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 38 lines · Naveen N. Rao

Date: Tue, 15 Oct 2013 23:47:23 +0530
From: "Naveen N. Rao" <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 2/8] ACPI, CPER: Update cper info
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 17 lines · Chen Gong

To satisfy the necessary of following patches and make related definition more clear, update some definitions about CPER. No functional changes.

---
 drivers/acpi/apei/apei-internal.h | 12 ++++-----
 drivers/acpi/apei/cper.c          | 46 ++++++++++++++++-----------------
 drivers/acpi/apei/ghes.c          | 54 +++++++++++++++++++--------------------
 include/acpi/actbl1.h             | 14 +++++-----
 include/acpi/ghes.h               |  2 +-
 5 files changed, 64 insertions(+), 64 deletions(-)
drivers/acpi/apei/apei-internal.h +0 -0
index f220d64..21ba34a 100644

drivers/acpi/apei/apei-internal.h struct dentry; · line 125

Quoted 5 lines
drivers/acpi/apei/apei-internal.h +1 -1
@@ -122,11 +122,11 @@ struct dentry;
 struct dentry *apei_get_debugfs_dir(void);
 
 #define apei_estatus_for_each_section(estatus, section)			\
-	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\
+	for (section = (struct acpi_generic_data *)(estatus + 1);	\

This is a good one to rename, though I wonder if acpi_generic_error_data is more appropriate?

Quoted 3 lines
drivers/acpi/apei/apei-internal.h +0 -0
 	     (void *)section - (void *)estatus < estatus->data_length;	\
 	     section = (void *)(section+1) + section->error_data_length)
 
Quoted 7 lines

drivers/acpi/apei/apei-internal.h struct dentry; · line 129

Quoted 2 lines
drivers/acpi/apei/apei-internal.h +1 -1
-static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
+static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)

Not sure I understand the rationale for these changes - we are still dealing with ACPI/APEI generic error status/data structures. So, why the cper_ prefix?

Because CPER is not APEI specific, beside APEI, some others like eMCA needs this.

Quoted 38 lines
Quoted 5 lines
drivers/acpi/apei/apei-internal.h +0 -0
 {
 	if (estatus->raw_data_length)
 		return estatus->raw_data_offset + \
@@ -135,10 +135,10 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
 		return sizeof(*estatus) + estatus->data_length;

drivers/acpi/apei/apei-internal.h static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) · line 141

Quoted 10 lines
drivers/acpi/apei/apei-internal.h +4 -4
 }
 
-void apei_estatus_print(const char *pfx,
-			const struct acpi_hest_generic_status *estatus);
-int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
-int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
+void cper_estatus_print(const char *pfx,
+			const struct acpi_generic_status *estatus);
+int cper_estatus_check_header(const struct acpi_generic_status *estatus);
+int cper_estatus_check(const struct acpi_generic_status *estatus);

Same here. All the above functions work on ACPI structures...

drivers/acpi/apei/apei-internal.h static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)

Quoted 12 lines
drivers/acpi/apei/apei-internal.h +5 -5
 /* Values for block_status flags above */
 
-#define ACPI_HEST_UNCORRECTABLE             (1)
-#define ACPI_HEST_CORRECTABLE               (1<<1)
-#define ACPI_HEST_MULTIPLE_UNCORRECTABLE    (1<<2)
-#define ACPI_HEST_MULTIPLE_CORRECTABLE      (1<<3)
-#define ACPI_HEST_ERROR_ENTRY_COUNT         (0xFF<<4)	/* 8 bits, error count */
+#define ACPI_GEN_ERR_UC			(1)
+#define ACPI_GEN_ERR_CE			(1<<1)
+#define ACPI_GEN_ERR_MULTI_UC		(1<<2)
+#define ACPI_GEN_ERR_MULTI_CE		(1<<3)
+#define ACPI_GEN_ERR_COUNT_SHIFT	(0xFF<<4) /* 8 bits, error count */

I'd prefer ACPI_GENERIC_ERR_ since ACPI_GEN_ERR sounds far too much like ACPI "Generated" :)

Thanks,
Naveen

#11 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Quoted 47 lines · Chen Gong
Quoted 38 lines · Naveen N. Rao

Date: Tue, 15 Oct 2013 23:47:23 +0530
From: "Naveen N. Rao" <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 2/8] ACPI, CPER: Update cper info
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 17 lines · Chen Gong

To satisfy the necessary of following patches and make related definition more clear, update some definitions about CPER. No functional changes.

---
  drivers/acpi/apei/apei-internal.h | 12 ++++-----
  drivers/acpi/apei/cper.c          | 46 ++++++++++++++++-----------------
  drivers/acpi/apei/ghes.c          | 54 +++++++++++++++++++--------------------
  include/acpi/actbl1.h             | 14 +++++-----
  include/acpi/ghes.h               |  2 +-
  5 files changed, 64 insertions(+), 64 deletions(-)
drivers/acpi/apei/apei-internal.h +0 -0
index f220d64..21ba34a 100644

drivers/acpi/apei/apei-internal.h struct dentry; · line 125

Quoted 5 lines
drivers/acpi/apei/apei-internal.h +1 -1
@@ -122,11 +122,11 @@ struct dentry;
  struct dentry *apei_get_debugfs_dir(void);
 
  #define apei_estatus_for_each_section(estatus, section)			\
-	for (section = (struct acpi_hest_generic_data *)(estatus + 1);	\
+	for (section = (struct acpi_generic_data *)(estatus + 1);	\

This is a good one to rename, though I wonder if acpi_generic_error_data is more appropriate?

Quoted 3 lines
drivers/acpi/apei/apei-internal.h +0 -0
  	     (void *)section - (void *)estatus < estatus->data_length;	\
  	     section = (void *)(section+1) + section->error_data_length)
 
Quoted 7 lines

drivers/acpi/apei/apei-internal.h struct dentry; · line 129

Quoted 2 lines
drivers/acpi/apei/apei-internal.h +1 -1
-static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
+static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)

Not sure I understand the rationale for these changes - we are still dealing with ACPI/APEI generic error status/data structures. So, why the cper_ prefix?

Quoted 2 lines

Because CPER is not APEI specific, beside APEI, some others like eMCA needs this.

Right, but even the document you point to refers to these structures as what they are: ACPI Generic error status/data. Clearly, CPER is an incorrect prefix here since CPER/UEFI does *not* seem to have the same structure format.

Regards,
Naveen

#12 lore raw

Re: [PATCH 2/8] ACPI, CPER: Update cper info

Gong,
This mail seems to have missed copying you given the header issues.

Thanks,
Naveen

Quoted 67 lines · Naveen N. Rao
Quoted 55 lines · Chen Gong
Quoted 44 lines · Naveen N. Rao

Date: Tue, 15 Oct 2013 23:47:23 +0530
From: "Naveen N. Rao" <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 2/8] ACPI, CPER: Update cper info
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 21 lines · Chen Gong

To satisfy the necessary of following patches and make related definition
more clear, update some definitions about CPER. No functional changes.

---
  drivers/acpi/apei/apei-internal.h | 12 ++++-----
  drivers/acpi/apei/cper.c          | 46
++++++++++++++++-----------------
  drivers/acpi/apei/ghes.c          | 54
+++++++++++++++++++--------------------
  include/acpi/actbl1.h             | 14 +++++-----
  include/acpi/ghes.h               |  2 +-
  5 files changed, 64 insertions(+), 64 deletions(-)
drivers/acpi/apei/apei-internal.h +0 -0
index f220d64..21ba34a 100644

drivers/acpi/apei/apei-internal.h struct dentry; · line 126

Quoted 6 lines
drivers/acpi/apei/apei-internal.h +1 -1
@@ -122,11 +122,11 @@ struct dentry;
  struct dentry *apei_get_debugfs_dir(void);
 
  #define apei_estatus_for_each_section(estatus, section)            \
-    for (section = (struct acpi_hest_generic_data *)(estatus +
 1);    \
+    for (section = (struct acpi_generic_data *)(estatus + 1);    \

This is a good one to rename, though I wonder if acpi_generic_error_data is more appropriate?

Quoted 4 lines
drivers/acpi/apei/apei-internal.h +0 -0
           (void *)section - (void *)estatus <
 estatus->data_length;    \
           section = (void *)(section+1) + section->error_data_length)
 
Quoted 9 lines
Quoted 4 lines
drivers/acpi/apei/apei-internal.h +1 -1
-static inline u32 apei_estatus_len(struct acpi_hest_generic_status
 *estatus)
+static inline u32 cper_estatus_len(struct acpi_generic_status

*estatus)

Not sure I understand the rationale for these changes - we are still dealing with ACPI/APEI generic error status/data structures. So, why the cper_ prefix?

Quoted 2 lines

Because CPER is not APEI specific, beside APEI, some others like eMCA needs this.

Right, but even the document you point to refers to these structures as what they are: ACPI Generic error status/data. Clearly, CPER is an incorrect prefix here since CPER/UEFI does *not* seem to have the same structure format.

Regards,
Naveen

author
#13 lore raw

PATCH 3/8 ACPI, x86: Extended error log driver for x86 platform

In reply to Chen, Gong

This error log driver (a.k.a eMCA driver) is implemented based on
http://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html.
After errors are captured, more valuable information can be got with this new enhanced error log driver.

---
 arch/x86/include/asm/mce.h       |   5 +
 arch/x86/kernel/cpu/mcheck/mce.c |  10 ++
 drivers/acpi/Kconfig             |   8 +
 drivers/acpi/Makefile            |   2 +
 drivers/acpi/acpi_extlog.c       | 339 +++++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c               |   3 +-
 include/linux/acpi.h             |   1 +
 7 files changed, 367 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/acpi_extlog.c
arch/x86/include/asm/mce.h +5 -0
index cbe6b9e..f8c33e2 100644
@@ -12,6 +12,7 @@
 #define MCG_CTL_P		(1ULL<<8)    /* MCG_CTL register available */
 #define MCG_EXT_P		(1ULL<<9)    /* Extended registers available */
 #define MCG_CMCI_P		(1ULL<<10)   /* CMCI supported */
+#define MCG_EXT_ERR_LOG		(1ULL<<26)   /* Extended error log supported */
 #define MCG_EXT_CNT_MASK	0xff0000     /* Number of Extended registers */
 #define MCG_EXT_CNT_SHIFT	16
 #define MCG_EXT_CNT(c)		(((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)
@@ -204,6 +205,10 @@ extern void mce_disable_bank(int bank);
  * Exception handler
  */
 
+extern spinlock_t mce_elog_lock;
+extern int (*mce_extlog_support)(void);
+/* Call the installed extended error log print function */
+extern int (*mce_ext_err_print)(const char *, int cpu, int bank);
 /* Call the installed machine check handler for this CPU setup. */
 extern void (*machine_check_vector)(struct pt_regs *, long error_code);
 void do_machine_check(struct pt_regs *, long);
arch/x86/kernel/cpu/mcheck/mce.c +10 -0
index b3218cd..6802637 100644
@@ -48,6 +48,12 @@
 
 #include "mce-internal.h"
 
+DEFINE_SPINLOCK(mce_elog_lock);
+EXPORT_SYMBOL_GPL(mce_elog_lock);
+
+int (*mce_ext_err_print)(const char *, int, int) = NULL;
+EXPORT_SYMBOL_GPL(mce_ext_err_print);
+
 static DEFINE_MUTEX(mce_chrdev_read_mutex);
 
 #define rcu_dereference_check_mce(p) \
@@ -624,6 +630,10 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		    (m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC)))
 			continue;
 
+		spin_lock(&mce_elog_lock);
+		if (mce_ext_err_print)
+			mce_ext_err_print(NULL, m.extcpu, i);
+		spin_unlock(&mce_elog_lock);
 		mce_read_aux(&m, i);
 
 		if (!(flags & MCP_TIMESTAMP))
drivers/acpi/Kconfig +8 -0
index 22327e6..1465fa8 100644
@@ -372,4 +372,12 @@ config ACPI_BGRT
 
 source "drivers/acpi/apei/Kconfig"
 
+config ACPI_EXTLOG
+	tristate "Extended Error Log support"
+	depends on X86 && X86_MCE
+	default n
+	help
+	  This driver adds support for decoding extended errors from hardware.
+	  which allows the operating system to obtain data from trace.
+
 endif	# ACPI
drivers/acpi/Makefile +2 -0
index cdaf68b..bce34af 100644
@@ -82,3 +82,5 @@ processor-$(CONFIG_CPU_FREQ)	+= processor_perflib.o
 obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
 
 obj-$(CONFIG_ACPI_APEI)		+= apei/
+
+obj-$(CONFIG_ACPI_EXTLOG)	+= acpi_extlog.o
drivers/acpi/acpi_extlog.c new file +339 -0

339 lines not on this page · raw message

drivers/acpi/bus.c +2 -1
index b587ec8..e1bd9a1 100644
@@ -174,7 +174,7 @@ static void acpi_print_osc_error(acpi_handle handle,
 	printk("\n");
 }
 
-static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
+acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
 {
 	int i;
 	static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
@@ -195,6 +195,7 @@ static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
 	}
 	return AE_OK;
 }
+EXPORT_SYMBOL_GPL(acpi_str_to_uuid);
 
 acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
 {
include/linux/acpi.h +1 -0
index a5db4ae..c30bac8 100644
@@ -311,6 +311,7 @@ struct acpi_osc_context {
 #define OSC_INVALID_REVISION_ERROR	8
 #define OSC_CAPABILITIES_MASK_ERROR	16
 
+acpi_status acpi_str_to_uuid(char *str, u8 *uuid);
 acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
 
 /* platform-wide _OSC bits */
Signature · 1 line
1.8.4.rc3
maintainer
#14 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 22 lines · Gong

This error log driver (a.k.a eMCA driver) is implemented based on
http://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html.
After errors are captured, more valuable information can be got with this new enhanced error log driver.

---
 arch/x86/include/asm/mce.h       |   5 +
 arch/x86/kernel/cpu/mcheck/mce.c |  10 ++
 drivers/acpi/Kconfig             |   8 +
 drivers/acpi/Makefile            |   2 +
 drivers/acpi/acpi_extlog.c       | 339 +++++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c               |   3 +-
 include/linux/acpi.h             |   1 +
 7 files changed, 367 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/acpi_extlog.c
arch/x86/include/asm/mce.h +0 -0
index cbe6b9e..f8c33e2 100644

arch/x86/include/asm/mce.h line 18

Quoted 7 lines
arch/x86/include/asm/mce.h +1 -0
@@ -12,6 +12,7 @@
 #define MCG_CTL_P		(1ULL<<8)    /* MCG_CTL register available */
 #define MCG_EXT_P		(1ULL<<9)    /* Extended registers available */
 #define MCG_CMCI_P		(1ULL<<10)   /* CMCI supported */
+#define MCG_EXT_ERR_LOG		(1ULL<<26)   /* Extended error log supported */
 #define MCG_EXT_CNT_MASK	0xff0000     /* Number of Extended registers */
 #define MCG_EXT_CNT_SHIFT	16
 #define MCG_EXT_CNT(c)		(((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)

Let's keep them numerically sorted by the bit numbers so put MCG_EXT_ERR_LOG after bit 24, MCG_SER_P.

Besides, this bit should be called MCG_ELOG_P as it is in the docs although your name is much more descriptive than what the hw guys came up with but I know they like to abbreviate to the lowest letter count possible :)

arch/x86/include/asm/mce.h extern void mce_disable_bank(int bank); · line 208

Quoted 5 lines
arch/x86/include/asm/mce.h +1 -0
@@ -204,6 +205,10 @@ extern void mce_disable_bank(int bank);
  * Exception handler
  */
 
+extern spinlock_t mce_elog_lock;

Uuh, I don't think we want to expose the naked spinlock. Rather, we'd need a couple of functions

mce_elog_lock
mce_elog_unlock

which get called by users.

Actually, it would be even better to keep all those details private to acpi_extlog.c and have machine_check_poll() call extlog_print() and in the cases where there's no extlog support, you have an empty extlog_print function.

arch/x86/include/asm/mce.h extern void mce_disable_bank(int bank); · line 209

Quoted 1 line
arch/x86/include/asm/mce.h +1 -0
+extern int (*mce_extlog_support)(void);

Unused leftover?

Quoted 10 lines
arch/x86/include/asm/mce.h +2 -0
+/* Call the installed extended error log print function */
+extern int (*mce_ext_err_print)(const char *, int cpu, int bank);
 /* Call the installed machine check handler for this CPU setup. */
 extern void (*machine_check_vector)(struct pt_regs *, long error_code);
 void do_machine_check(struct pt_regs *, long);
arch/x86/kernel/cpu/mcheck/mce.c +0 -0
index b3218cd..6802637 100644

arch/x86/kernel/cpu/mcheck/mce.c line 52

Quoted 5 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -0
@@ -48,6 +48,12 @@
 
 #include "mce-internal.h"
 
+DEFINE_SPINLOCK(mce_elog_lock);
+EXPORT_SYMBOL_GPL(mce_elog_lock);

Yeah, private to acpi_extlog and it can be simply 'elog_lock' there, without the "mce_" prefix.

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -0
+
+int (*mce_ext_err_print)(const char *, int, int) = NULL;
+EXPORT_SYMBOL_GPL(mce_ext_err_print);
+
 static DEFINE_MUTEX(mce_chrdev_read_mutex);
 
 #define rcu_dereference_check_mce(p) \

arch/x86/kernel/cpu/mcheck/mce.c void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) · line 636

Quoted 7 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -0
@@ -624,6 +630,10 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		    (m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC)))
 			continue;
 
+		spin_lock(&mce_elog_lock);
+		if (mce_ext_err_print)
+			mce_ext_err_print(NULL, m.extcpu, i);
+		spin_unlock(&mce_elog_lock);

private to acpi_extlog.c

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +0 -0
 		mce_read_aux(&m, i);
 
 		if (!(flags & MCP_TIMESTAMP))
drivers/acpi/Kconfig +0 -0
index 22327e6..1465fa8 100644

drivers/acpi/Kconfig config ACPI_BGRT · line 377

Quoted 6 lines
drivers/acpi/Kconfig +3 -0
@@ -372,4 +372,12 @@ config ACPI_BGRT
 
 source "drivers/acpi/apei/Kconfig"
 
+config ACPI_EXTLOG
+	tristate "Extended Error Log support"
+	depends on X86 && X86_MCE

I guess we can depend only on X86_MCE

drivers/acpi/Kconfig config ACPI_BGRT · line 381

Quoted 4 lines
drivers/acpi/Kconfig +4 -0
+	default n
+	help
+	  This driver adds support for decoding extended errors from hardware.
+	  which allows the operating system to obtain data from trace.

Let's make this description a bit better:

"Enhanced MCA Logging allows firmware to provide additional error information to system software, synchronous with MCE or CMCI. This driver adds support for that functionality plus an additional special tracepoint which carries that information to userspace."

Quoted 26 lines
drivers/acpi/Kconfig +1 -0
+
 endif	# ACPI
drivers/acpi/Makefile +2 -0
index cdaf68b..bce34af 100644
@@ -82,3 +82,5 @@ processor-$(CONFIG_CPU_FREQ)	+= processor_perflib.o
 obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
 
 obj-$(CONFIG_ACPI_APEI)		+= apei/
+
+obj-$(CONFIG_ACPI_EXTLOG)	+= acpi_extlog.o
drivers/acpi/acpi_extlog.c new file +8 -0
new file mode 100644
index 0000000..3e3e286
@@ -0,0 +1,339 @@
+/*
+ * Extended Error Log driver
+ *
+ * Copyright (C) 2013 Intel Corp.
+ * Author: Chen, Gong <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version

drivers/acpi/acpi_extlog.c line 18

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Please no more of that boilerplate. Simply say that this file is licensed under GPLv2 and that's it.

drivers/acpi/acpi_extlog.c line 30

Quoted 12 lines
drivers/acpi/acpi_extlog.c new file +12 -0
+ */
+
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <linux/cper.h>
+#include <linux/ratelimit.h>
+#include <asm/mce.h>
+
+#include "apei/apei-internal.h"
+
+#define EXT_ELOG_ENTRY_MASK	0xfffffffffffff /* elog entry address mask */

Am I reading this correctly that these are bits [51:0]?

Btw, we have a GENMASK macro in drivers/edac/amd64_edac.h which can be used for generating contiguous bitmasks:

#define EXT_ELOG_ENTRY_MASK GENMASK(0, 51)

which makes it much more readable.

You could lift it into a more global header like, say, arch/x86/include/asm/edac.h maybe...

Quoted 48 lines
drivers/acpi/acpi_extlog.c new file +48 -0
+
+#define EXTLOG_DSM_REV		0x0
+#define	EXTLOG_FN_QUERY		0x0
+#define	EXTLOG_FN_ADDR		0x1
+
+#define FLAG_OS_OPTIN		BIT(0)
+#define EXTLOG_QUERY_L1_EXIST	BIT(1)
+#define ELOG_ENTRY_VALID	(1ULL<<63)
+#define ELOG_ENTRY_LEN		0x1000
+
+#define EMCA_BUG \
+	"Can not request iomem region <0x%016llx-0x%016llx> - eMCA disabled\n"
+
+struct extlog_l1_head {
+	u32 ver;	/* Header Version */
+	u32 hdr_len;	/* Header Length */
+	u64 total_len;	/* entire L1 Directory length including this header */
+	u64 elog_base;	/* MCA Error Log Directory base address */
+	u64 elog_len;	/* MCA Error Log Directory length */
+	u32 flags;	/* bit 0 - OS/VMM Opt-in */
+	u8  rev0[12];
+	u32 entries;	/* Valid L1 Directory entries per logical processor */
+	u8  rev1[12];
+};
+
+static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295";
+
+/* L1 table related physical address */
+static u64 elog_base;
+static size_t elog_size;
+static u64 l1_dirbase;
+static size_t l1_size;
+
+/* L1 table related virtual address */
+static void __iomem *extlog_l1_addr;
+static void __iomem *elog_addr;
+
+static void *elog_buf;
+
+static u64 *l1_entry_base;
+static u32 l1_percpu_entry;
+
+#define ELOG_IDX(cpu, bank) \
+	(cpu_physical_id(cpu) * l1_percpu_entry + (bank))
+
+#define ELOG_ENTRY_DATA(idx) \
+	(*(l1_entry_base + (idx)))
+

drivers/acpi/acpi_extlog.c line 88

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+#define ELOG_ENTRY_ADDR(phyaddr) \
+	(phyaddr - elog_base + (u8 *)elog_addr)
+
+static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
+{
+	int idx;
+	u64 data;
+	struct acpi_generic_status *estatus;
+
+	BUG_ON(cpu < 0);

What is this supposed to guard? And why such a heavy hammer?

Quoted 7 lines
drivers/acpi/acpi_extlog.c new file +7 -0
+	idx = ELOG_IDX(cpu, bank);
+	data = ELOG_ENTRY_DATA(idx);
+	if ((data & ELOG_ENTRY_VALID) == 0)
+		return NULL;
+
+	data &= EXT_ELOG_ENTRY_MASK;
+	estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data);

drivers/acpi/acpi_extlog.c line 105

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+
+	/* if no valid data in elog entry, just return */
+	if (estatus->block_status == 0)
+		return NULL;
+
+	return estatus;
+}
+
+static void __print_extlog_rcd(const char *pfx,
+		struct acpi_generic_status *estatus, int cpu)

Please align args after the opening bracket.

drivers/acpi/acpi_extlog.c line 111

Quoted 6 lines
drivers/acpi/acpi_extlog.c new file +6 -0
+{
+	static atomic_t seqno;
+	unsigned int curr_seqno;
+	char pfx_seq[64];
+
+	if (pfx == NULL) {
	if (!pfx)

drivers/acpi/acpi_extlog.c

Quoted 13 lines
drivers/acpi/acpi_extlog.c new file +13 -0
+		if (estatus->error_severity <= CPER_SEV_CORRECTED)
+			pfx = KERN_INFO;
+		else
+			pfx = KERN_ERR;
+	}
+	curr_seqno = atomic_inc_return(&seqno);
+	snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}", pfx, curr_seqno);
+	printk("%s""Hardware error detected on CPU%d\n", pfx_seq, cpu);
+	cper_estatus_print(pfx_seq, estatus);
+}
+
+static int print_extlog_rcd(const char *pfx,
+		struct acpi_generic_status *estatus, int cpu)a

Ditto.

drivers/acpi/acpi_extlog.c line 132

Quoted 8 lines
drivers/acpi/acpi_extlog.c new file +8 -0
+{
+	/* Not more than 2 messages every 5 seconds */
+	static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
+	static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2);
+	struct ratelimit_state *ratelimit;
+
+	if (estatus->error_severity == CPER_SEV_CORRECTED ||
+			(estatus->error_severity == CPER_SEV_INFORMATIONAL))

alignment:

	if ( estatus->error_severity == CPER_SEV_CORRECTED ||
	    (estatus->error_severity == CPER_SEV_INFORMATIONAL))

drivers/acpi/acpi_extlog.c line 137

Quoted 5 lines
drivers/acpi/acpi_extlog.c new file +5 -0
+		ratelimit = &ratelimit_corrected;
+	else
+		ratelimit = &ratelimit_uncorrected;
+	if (__ratelimit(ratelimit)) {
+		__print_extlog_rcd(pfx, estatus, cpu);

Btw, __print_extlog_rcd is only called once, AFAICT. Why not fold it in here?

Quoted 50 lines
drivers/acpi/acpi_extlog.c new file +50 -0
+		return 0;
+	}
+
+	return 1;
+}
+
+static int extlog_print(const char *pfx, int cpu, int bank)
+{
+	struct acpi_generic_status *estatus;
+	int rc;
+
+	estatus = extlog_elog_entry_check(cpu, bank);
+	if (estatus == NULL)
+		return -EINVAL;
+
+	memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
+	/* clear record status to enable BIOS to update it again */
+	estatus->block_status = 0;
+
+	rc = print_extlog_rcd(pfx, (struct acpi_generic_status *)elog_buf, cpu);
+
+	return rc;
+}
+
+static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret)
+{
+	struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_object_list input;
+	union acpi_object params[4], *obj;
+	u8 uuid[16];
+	int i;
+
+	acpi_str_to_uuid(extlog_dsm_uuid, uuid);
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = 16;
+	params[0].buffer.pointer = uuid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = rev;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = func;
+	params[3].type = ACPI_TYPE_PACKAGE;
+	params[3].package.count = 0;
+	params[3].package.elements = NULL;
+
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf)))
+		return -1;
+
+	*ret = 0;

drivers/acpi/acpi_extlog.c line 197

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+	obj = (union acpi_object *)buf.pointer;
+	if (obj->type == ACPI_TYPE_INTEGER)
+		*ret = obj->integer.value;
+	else if (obj->type == ACPI_TYPE_BUFFER) {
+		if (obj->buffer.length <= 8) {
+			for (i = 0; i < obj->buffer.length; i++)
+				*ret |= (obj->buffer.pointer[i] << (i * 8));
+		}
+	}
+	kfree(buf.pointer);

I'm guessing this is how acpi does allocation - ACPI_ALLOCATE_BUFFER and caller has to free it?

Quoted 12 lines
drivers/acpi/acpi_extlog.c new file +12 -0
+
+	return 0;
+}
+
+static bool extlog_get_l1addr(void)
+{
+	acpi_handle handle;
+	u64 ret;
+
+	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
+		goto fail;
+

drivers/acpi/acpi_extlog.c line 219

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+	if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) ||
+			!(ret & EXTLOG_QUERY_L1_EXIST))
+		goto fail;
+
+	if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret))
+		goto fail;
+
+	l1_dirbase = ret;
+	/* Spec says L1 directory must be 4K aligned, bail out if it isn't */
+	if (l1_dirbase & ((1 << 12) - 1)) {
		       & (PAGE_SIZE - 1)

drivers/acpi/acpi_extlog.c line 227

Quoted 8 lines
drivers/acpi/acpi_extlog.c new file +8 -0
+		pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n",
+			l1_dirbase);
+		goto fail;
+	}
+
+	return true;
+fail:
+	return false;

You probably could drop the labels and simply do "return false" in the error cases as it is obvious.

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#15 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 60 lines · Borislav Petkov

Date: Fri, 11 Oct 2013 17:24:52 +0200
From: Borislav Petkov <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86
platform
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 22 lines · Gong

This error log driver (a.k.a eMCA driver) is implemented based on
http://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html.
After errors are captured, more valuable information can be got with this new enhanced error log driver.

---
 arch/x86/include/asm/mce.h       |   5 +
 arch/x86/kernel/cpu/mcheck/mce.c |  10 ++
 drivers/acpi/Kconfig             |   8 +
 drivers/acpi/Makefile            |   2 +
 drivers/acpi/acpi_extlog.c       | 339 +++++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c               |   3 +-
 include/linux/acpi.h             |   1 +
 7 files changed, 367 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/acpi_extlog.c
arch/x86/include/asm/mce.h +0 -0
index cbe6b9e..f8c33e2 100644

arch/x86/include/asm/mce.h line 18

Quoted 7 lines
arch/x86/include/asm/mce.h +1 -0
@@ -12,6 +12,7 @@
 #define MCG_CTL_P		(1ULL<<8)    /* MCG_CTL register available */
 #define MCG_EXT_P		(1ULL<<9)    /* Extended registers available */
 #define MCG_CMCI_P		(1ULL<<10)   /* CMCI supported */
+#define MCG_EXT_ERR_LOG		(1ULL<<26)   /* Extended error log supported */
 #define MCG_EXT_CNT_MASK	0xff0000     /* Number of Extended registers */
 #define MCG_EXT_CNT_SHIFT	16
 #define MCG_EXT_CNT(c)		(((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)

Let's keep them numerically sorted by the bit numbers so put MCG_EXT_ERR_LOG after bit 24, MCG_SER_P.

Besides, this bit should be called MCG_ELOG_P as it is in the docs although your name is much more descriptive than what the hw guys came up with but I know they like to abbreviate to the lowest letter count possible :)

arch/x86/include/asm/mce.h extern void mce_disable_bank(int bank); · line 208

Quoted 5 lines
arch/x86/include/asm/mce.h +1 -0
@@ -204,6 +205,10 @@ extern void mce_disable_bank(int bank);
  * Exception handler
  */
 
+extern spinlock_t mce_elog_lock;

Uuh, I don't think we want to expose the naked spinlock. Rather, we'd need a couple of functions

mce_elog_lock
mce_elog_unlock

Quoted 7 lines

which get called by users.

Actually, it would be even better to keep all those details private to acpi_extlog.c and have machine_check_poll() call extlog_print() and in the cases where there's no extlog support, you have an empty extlog_print function.

But this driver can be loaded as a module. If this module is unloaded, extlog_print is gone. I can't keep such a pointer internally.

Quoted 4 lines

arch/x86/include/asm/mce.h extern void mce_disable_bank(int bank); · line 209

Quoted 1 line
arch/x86/include/asm/mce.h +1 -0
+extern int (*mce_extlog_support)(void);

Unused leftover?

Yes, it should be deleted.

Quoted 125 lines
Quoted 10 lines
arch/x86/include/asm/mce.h +2 -0
+/* Call the installed extended error log print function */
+extern int (*mce_ext_err_print)(const char *, int cpu, int bank);
 /* Call the installed machine check handler for this CPU setup. */
 extern void (*machine_check_vector)(struct pt_regs *, long error_code);
 void do_machine_check(struct pt_regs *, long);
arch/x86/kernel/cpu/mcheck/mce.c +0 -0
index b3218cd..6802637 100644

arch/x86/kernel/cpu/mcheck/mce.c line 52

Quoted 5 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -0
@@ -48,6 +48,12 @@
 
 #include "mce-internal.h"
 
+DEFINE_SPINLOCK(mce_elog_lock);
+EXPORT_SYMBOL_GPL(mce_elog_lock);

Yeah, private to acpi_extlog and it can be simply 'elog_lock' there, without the "mce_" prefix.

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -0
+
+int (*mce_ext_err_print)(const char *, int, int) = NULL;
+EXPORT_SYMBOL_GPL(mce_ext_err_print);
+
 static DEFINE_MUTEX(mce_chrdev_read_mutex);
 
 #define rcu_dereference_check_mce(p) \

arch/x86/kernel/cpu/mcheck/mce.c void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) · line 636

Quoted 7 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -0
@@ -624,6 +630,10 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		    (m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC)))
 			continue;
 
+		spin_lock(&mce_elog_lock);
+		if (mce_ext_err_print)
+			mce_ext_err_print(NULL, m.extcpu, i);
+		spin_unlock(&mce_elog_lock);

private to acpi_extlog.c

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +0 -0
 		mce_read_aux(&m, i);
 
 		if (!(flags & MCP_TIMESTAMP))
drivers/acpi/Kconfig +0 -0
index 22327e6..1465fa8 100644

drivers/acpi/Kconfig config ACPI_BGRT · line 377

Quoted 6 lines
drivers/acpi/Kconfig +3 -0
@@ -372,4 +372,12 @@ config ACPI_BGRT
 
 source "drivers/acpi/apei/Kconfig"
 
+config ACPI_EXTLOG
+	tristate "Extended Error Log support"
+	depends on X86 && X86_MCE

I guess we can depend only on X86_MCE

drivers/acpi/Kconfig config ACPI_BGRT · line 381

Quoted 4 lines
drivers/acpi/Kconfig +4 -0
+	default n
+	help
+	  This driver adds support for decoding extended errors from hardware.
+	  which allows the operating system to obtain data from trace.

Let's make this description a bit better:

"Enhanced MCA Logging allows firmware to provide additional error information to system software, synchronous with MCE or CMCI. This driver adds support for that functionality plus an additional special tracepoint which carries that information to userspace."

Quoted 26 lines
drivers/acpi/Kconfig +1 -0
+
 endif	# ACPI
drivers/acpi/Makefile +2 -0
index cdaf68b..bce34af 100644
@@ -82,3 +82,5 @@ processor-$(CONFIG_CPU_FREQ)	+= processor_perflib.o
 obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
 
 obj-$(CONFIG_ACPI_APEI)		+= apei/
+
+obj-$(CONFIG_ACPI_EXTLOG)	+= acpi_extlog.o
drivers/acpi/acpi_extlog.c new file +8 -0
new file mode 100644
index 0000000..3e3e286
@@ -0,0 +1,339 @@
+/*
+ * Extended Error Log driver
+ *
+ * Copyright (C) 2013 Intel Corp.
+ * Author: Chen, Gong <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version

drivers/acpi/acpi_extlog.c line 18

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Please no more of that boilerplate. Simply say that this file is licensed under GPLv2 and that's it.

drivers/acpi/acpi_extlog.c line 30

Quoted 12 lines
drivers/acpi/acpi_extlog.c new file +12 -0
+ */
+
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <linux/cper.h>
+#include <linux/ratelimit.h>
+#include <asm/mce.h>
+
+#include "apei/apei-internal.h"
+
+#define EXT_ELOG_ENTRY_MASK	0xfffffffffffff /* elog entry address mask */

Am I reading this correctly that these are bits [51:0]?

Btw, we have a GENMASK macro in drivers/edac/amd64_edac.h which can be used for generating contiguous bitmasks:

Quoted 8 lines

#define EXT_ELOG_ENTRY_MASK GENMASK(0, 51)

which makes it much more readable.

You could lift it into a more global header like, say, arch/x86/include/asm/edac.h maybe...

This macro is great and I'd loved to use it. But it looks like a litttle bit weird to let eMCA depends on a header file like edac.h. Meanwhile, I found in drivers/video/sis/init.c:3323 we have a very similar macro for this purpose. So how about writing a separate patch to clean it up first?

Quoted 52 lines
Quoted 52 lines
drivers/acpi/acpi_extlog.c new file +52 -0
+
+#define EXTLOG_DSM_REV		0x0
+#define	EXTLOG_FN_QUERY		0x0
+#define	EXTLOG_FN_ADDR		0x1
+
+#define FLAG_OS_OPTIN		BIT(0)
+#define EXTLOG_QUERY_L1_EXIST	BIT(1)
+#define ELOG_ENTRY_VALID	(1ULL<<63)
+#define ELOG_ENTRY_LEN		0x1000
+
+#define EMCA_BUG \
+	"Can not request iomem region <0x%016llx-0x%016llx> - eMCA disabled\n"
+
+struct extlog_l1_head {
+	u32 ver;	/* Header Version */
+	u32 hdr_len;	/* Header Length */
+	u64 total_len;	/* entire L1 Directory length including this header */
+	u64 elog_base;	/* MCA Error Log Directory base address */
+	u64 elog_len;	/* MCA Error Log Directory length */
+	u32 flags;	/* bit 0 - OS/VMM Opt-in */
+	u8  rev0[12];
+	u32 entries;	/* Valid L1 Directory entries per logical processor */
+	u8  rev1[12];
+};
+
+static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295";
+
+/* L1 table related physical address */
+static u64 elog_base;
+static size_t elog_size;
+static u64 l1_dirbase;
+static size_t l1_size;
+
+/* L1 table related virtual address */
+static void __iomem *extlog_l1_addr;
+static void __iomem *elog_addr;
+
+static void *elog_buf;
+
+static u64 *l1_entry_base;
+static u32 l1_percpu_entry;
+
+#define ELOG_IDX(cpu, bank) \
+	(cpu_physical_id(cpu) * l1_percpu_entry + (bank))
+
+#define ELOG_ENTRY_DATA(idx) \
+	(*(l1_entry_base + (idx)))
+
+#define ELOG_ENTRY_ADDR(phyaddr) \
+	(phyaddr - elog_base + (u8 *)elog_addr)
+
+static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
Quoted 9 lines

drivers/acpi/acpi_extlog.c line 88

Quoted 6 lines
drivers/acpi/acpi_extlog.c new file +6 -0
+{
+	int idx;
+	u64 data;
+	struct acpi_generic_status *estatus;
+
+	BUG_ON(cpu < 0);

What is this supposed to guard? And why such a heavy hammer?

Because I think in theory "CPU < 0" is impossible. When it hits such situation, it should be a very serious H/W or firmware bug. At least, It think it should be a WARN_ON.

Quoted 59 lines
Quoted 7 lines
drivers/acpi/acpi_extlog.c new file +7 -0
+	idx = ELOG_IDX(cpu, bank);
+	data = ELOG_ENTRY_DATA(idx);
+	if ((data & ELOG_ENTRY_VALID) == 0)
+		return NULL;
+
+	data &= EXT_ELOG_ENTRY_MASK;
+	estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data);

drivers/acpi/acpi_extlog.c line 105

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+
+	/* if no valid data in elog entry, just return */
+	if (estatus->block_status == 0)
+		return NULL;
+
+	return estatus;
+}
+
+static void __print_extlog_rcd(const char *pfx,
+		struct acpi_generic_status *estatus, int cpu)

Please align args after the opening bracket.

drivers/acpi/acpi_extlog.c line 111

Quoted 6 lines
drivers/acpi/acpi_extlog.c new file +6 -0
+{
+	static atomic_t seqno;
+	unsigned int curr_seqno;
+	char pfx_seq[64];
+
+	if (pfx == NULL) {
	if (!pfx)

drivers/acpi/acpi_extlog.c

Quoted 13 lines
drivers/acpi/acpi_extlog.c new file +13 -0
+		if (estatus->error_severity <= CPER_SEV_CORRECTED)
+			pfx = KERN_INFO;
+		else
+			pfx = KERN_ERR;
+	}
+	curr_seqno = atomic_inc_return(&seqno);
+	snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}", pfx, curr_seqno);
+	printk("%s""Hardware error detected on CPU%d\n", pfx_seq, cpu);
+	cper_estatus_print(pfx_seq, estatus);
+}
+
+static int print_extlog_rcd(const char *pfx,
+		struct acpi_generic_status *estatus, int cpu)a

Ditto.

drivers/acpi/acpi_extlog.c line 132

Quoted 8 lines
drivers/acpi/acpi_extlog.c new file +8 -0
+{
+	/* Not more than 2 messages every 5 seconds */
+	static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
+	static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2);
+	struct ratelimit_state *ratelimit;
+
+	if (estatus->error_severity == CPER_SEV_CORRECTED ||
+			(estatus->error_severity == CPER_SEV_INFORMATIONAL))

alignment:

	if ( estatus->error_severity == CPER_SEV_CORRECTED ||
	    (estatus->error_severity == CPER_SEV_INFORMATIONAL))
Quoted 8 lines

drivers/acpi/acpi_extlog.c line 137

Quoted 5 lines
drivers/acpi/acpi_extlog.c new file +5 -0
+		ratelimit = &ratelimit_corrected;
+	else
+		ratelimit = &ratelimit_uncorrected;
+	if (__ratelimit(ratelimit)) {
+		__print_extlog_rcd(pfx, estatus, cpu);

Btw, __print_extlog_rcd is only called once, AFAICT. Why not fold it in here?

Just make codes cleaner.

Quoted 56 lines
Quoted 56 lines
drivers/acpi/acpi_extlog.c new file +55 -0
+		return 0;
+	}
+
+	return 1;
+}
+
+static int extlog_print(const char *pfx, int cpu, int bank)
+{
+	struct acpi_generic_status *estatus;
+	int rc;
+
+	estatus = extlog_elog_entry_check(cpu, bank);
+	if (estatus == NULL)
+		return -EINVAL;
+
+	memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
+	/* clear record status to enable BIOS to update it again */
+	estatus->block_status = 0;
+
+	rc = print_extlog_rcd(pfx, (struct acpi_generic_status *)elog_buf, cpu);
+
+	return rc;
+}
+
+static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret)
+{
+	struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_object_list input;
+	union acpi_object params[4], *obj;
+	u8 uuid[16];
+	int i;
+
+	acpi_str_to_uuid(extlog_dsm_uuid, uuid);
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = 16;
+	params[0].buffer.pointer = uuid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = rev;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = func;
+	params[3].type = ACPI_TYPE_PACKAGE;
+	params[3].package.count = 0;
+	params[3].package.elements = NULL;
+
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf)))
+		return -1;
+
+	*ret = 0;
+	obj = (union acpi_object *)buf.pointer;
+	if (obj->type == ACPI_TYPE_INTEGER)
+		*ret = obj->integer.value;
+	else if (obj->type == ACPI_TYPE_BUFFER) {
+		if (obj->buffer.length <= 8) {
Quoted 9 lines

drivers/acpi/acpi_extlog.c line 197

Quoted 5 lines
drivers/acpi/acpi_extlog.c new file +5 -0
+			for (i = 0; i < obj->buffer.length; i++)
+				*ret |= (obj->buffer.pointer[i] << (i * 8));
+		}
+	}
+	kfree(buf.pointer);

I'm guessing this is how acpi does allocation - ACPI_ALLOCATE_BUFFER and caller has to free it?

Yes it is.

Quoted 45 lines
Quoted 12 lines
drivers/acpi/acpi_extlog.c new file +12 -0
+
+	return 0;
+}
+
+static bool extlog_get_l1addr(void)
+{
+	acpi_handle handle;
+	u64 ret;
+
+	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
+		goto fail;
+

drivers/acpi/acpi_extlog.c line 219

Quoted 10 lines
drivers/acpi/acpi_extlog.c new file +10 -0
+	if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) ||
+			!(ret & EXTLOG_QUERY_L1_EXIST))
+		goto fail;
+
+	if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret))
+		goto fail;
+
+	l1_dirbase = ret;
+	/* Spec says L1 directory must be 4K aligned, bail out if it isn't */
+	if (l1_dirbase & ((1 << 12) - 1)) {
		       & (PAGE_SIZE - 1)

drivers/acpi/acpi_extlog.c line 227

Quoted 8 lines
drivers/acpi/acpi_extlog.c new file +8 -0
+		pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n",
+			l1_dirbase);
+		goto fail;
+	}
+
+	return true;
+fail:
+	return false;

You probably could drop the labels and simply do "return false" in the error cases as it is obvious.

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
maintainer
#16 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 2 lines · Chen Gong

But this driver can be loaded as a module. If this module is unloaded, extlog_print is gone. I can't keep such a pointer internally.

Sure you can - you define a weak extlog_print() function in a compilation unit which is always builtin. Maybe mce.c or so.

Quoted 5 lines

This macro is great and I'd loved to use it. But it looks like a litttle bit weird to let eMCA depends on a header file like edac.h. Meanwhile, I found in drivers/video/sis/init.c:3323 we have a very similar macro for this purpose. So how about writing a separate patch to clean it up first?

Actually, you're right. Those macros are much more generic and could be exposed to the general public by putting them, say into include/include/bitops.h, for example?

Btw, the sis one generates unsigneds (4 byte on x86) while the edac one 8 byte ULLs. So you could call them

GENMASK
and
GENMASK_ULL

How does that sound?

Quoted 3 lines

Because I think in theory "CPU < 0" is impossible. When it hits such situation, it should be a very serious H/W or firmware bug. At least, It think it should be a WARN_ON.

Yes, I think a WARN_ON is much better than the heavy hammer. We can always turn it into a FW_BUG later if it really starts to trigger anywhere...

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#17 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 9 lines · Borislav Petkov

Date: Mon, 14 Oct 2013 12:26:35 +0200
From: Borislav Petkov <[email protected]>
To: Chen Gong <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86
platform
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 7 lines
Quoted 2 lines · Chen Gong

But this driver can be loaded as a module. If this module is unloaded, extlog_print is gone. I can't keep such a pointer internally.

Sure you can - you define a weak extlog_print() function in a compilation unit which is always builtin. Maybe mce.c or so.

Oh, yes. Let me do it.

Quoted 10 lines
Quoted 5 lines

This macro is great and I'd loved to use it. But it looks like a litttle bit weird to let eMCA depends on a header file like edac.h. Meanwhile, I found in drivers/video/sis/init.c:3323 we have a very similar macro for this purpose. So how about writing a separate patch to clean it up first?

Actually, you're right. Those macros are much more generic and could be exposed to the general public by putting them, say into include/include/bitops.h, for example?

Quoted 8 lines

Btw, the sis one generates unsigneds (4 byte on x86) while the edac one 8 byte ULLs. So you could call them

GENMASK
and
GENMASK_ULL

How does that sound?

This kind of mask is often unsigned. So how about following mode:

GENMASKL / GENMASKQ
or
GENMASK_L / GENMASK_Q

Quoted 9 lines
Quoted 4 lines

Because I think in theory "CPU < 0" is impossible. When it hits such situation, it should be a very serious H/W or firmware bug. At least, It think it should be a WARN_ON.

Yes, I think a WARN_ON is much better than the heavy hammer. We can always turn it into a FW_BUG later if it really starts to trigger anywhere...

Agree.

Quoted 8 lines

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
maintainer
#18 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 5 lines · Chen Gong

This kind of mask is often unsigned. So how about following mode:

GENMASKL / GENMASKQ
or
GENMASK_L / GENMASK_Q

Right, I think the "_ULL" thing is more accepted in the kernel, see DIV_ROUND_UP{,_ULL}. Also, Joe had a patch to convert BIT to that scheme too:

https://lkml.org/lkml/2013/9/19/307

There are macros with "_Q" but it does not necessarily mean Quadword but something else like queues and stuff.

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#19 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

In reply to Borislav Petkov
Quoted 6 lines · Borislav Petkov
Quoted 2 lines · Chen Gong

But this driver can be loaded as a module. If this module is unloaded, extlog_print is gone. I can't keep such a pointer internally.

Sure you can - you define a weak extlog_print() function in a compilation unit which is always builtin. Maybe mce.c or so.

"weak" is a good compile/link time tool to provide a default function while allowing override with a architecture (or more generally a CONFIG_*) specific one. But it is no help when loading/unloading modules.

Think about it ... we have a call to this function from some place in the base kernel (originating from mce.o). Before the module is loaded you want that to leap to your weak function.

Now load the module with the not-weak definition of the function - the module loader would have to go do a relocation fix-up in the base kernel to point to this new function. At module unload it would have to undo that.

-Tony

maintainer
#20 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 4 lines · Tony Luck

Now load the module with the not-weak definition of the function - the module loader would have to go do a relocation fix-up in the base kernel to point to this new function. At module unload it would have to undo that.

Ok, then. How about a reg/dereg functionality, something like what I did in drivers/edac/mce_amd.c, near the top? We're basically handing down a proper function pointer to call and at module unload time we clear it.

Also, those register/unregister functions could be made to return an errval so that code calling them can handle that gracefully.

Bottom line is, IMO we're much better off having a clearly defined interface like that instead of exporting a naked function pointer.

Thoughts?

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#21 lore raw

Re: [PATCH 3/8] ACPI, x86: Extended error log driver for x86 platform

Quoted 3 lines · Borislav Petkov

Ok, then. How about a reg/dereg functionality, something like what I did in drivers/edac/mce_amd.c, near the top? We're basically handing down a proper function pointer to call and at module unload time we clear it.

Yes - register and unregister functions would be better than

Quoted 1 line

exporting a naked function pointer.

-Tony

author
#22 lore raw

PATCH 4/8 DMI: Parse memory device (type 17) in SMBIOS

In reply to Chen, Gong

This patch adds a new interface to decode memory device (type 17) to help error reporting on DIMMs.

Original-author: Tony Luck <[email protected]>

---
 arch/ia64/kernel/setup.c    |  1 +
 arch/x86/kernel/setup.c     |  1 +
 drivers/firmware/dmi_scan.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/dmi.h         |  5 ++++
 4 files changed, 67 insertions(+)
arch/ia64/kernel/setup.c +1 -0
index 4fc2e95..d86669b 100644
@@ -1063,6 +1063,7 @@ check_bugs (void)
 static int __init run_dmi_scan(void)
 {
 	dmi_scan_machine();
+	dmi_memdev_walk();
 	dmi_set_dump_stack_arch_desc();
 	return 0;
 }
arch/x86/kernel/setup.c +1 -0
index f0de629..918d489 100644
@@ -993,6 +993,7 @@ void __init setup_arch(char **cmdline_p)
 		efi_init();
 
 	dmi_scan_machine();
+	dmi_memdev_walk();
 	dmi_set_dump_stack_arch_desc();
 
 	/*
drivers/firmware/dmi_scan.c +60 -0

75 lines not on this page · raw message

include/linux/dmi.h +5 -0
index b6eb7a0..f820f0a 100644
@@ -99,6 +99,7 @@ extern const char * dmi_get_system_info(int field);
 extern const struct dmi_device * dmi_find_device(int type, const char *name,
 	const struct dmi_device *from);
 extern void dmi_scan_machine(void);
+extern void dmi_memdev_walk(void);
 extern void dmi_set_dump_stack_arch_desc(void);
 extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp);
 extern int dmi_name_in_vendors(const char *str);
@@ -107,6 +108,7 @@ extern int dmi_available;
 extern int dmi_walk(void (*decode)(const struct dmi_header *, void *),
 	void *private_data);
 extern bool dmi_match(enum dmi_field f, const char *str);
+extern void dmi_memdev_name(u16 handle, const char **bank, const char **device);
 
 #else
 
@@ -115,6 +117,7 @@ static inline const char * dmi_get_system_info(int field) { return NULL; }
 static inline const struct dmi_device * dmi_find_device(int type, const char *name,
 	const struct dmi_device *from) { return NULL; }
 static inline void dmi_scan_machine(void) { return; }
+static inline void dmi_memdev_walk(void) { }
 static inline void dmi_set_dump_stack_arch_desc(void) { }
 static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
 {
@@ -133,6 +136,8 @@ static inline int dmi_walk(void (*decode)(const struct dmi_header *, void *),
 	void *private_data) { return -1; }
 static inline bool dmi_match(enum dmi_field f, const char *str)
 	{ return false; }
+static inline void dmi_memdev_name(u16 handle, const char **bank,
+		const char **device) { }
 static inline const struct dmi_system_id *
 	dmi_first_match(const struct dmi_system_id *list) { return NULL; }
 
Signature · 1 line
1.8.4.rc3
maintainer Reviewed-by on v1 4/8
#23 lore raw

Re: [PATCH 4/8] DMI: Parse memory device (type 17) in SMBIOS

Quoted 5 lines · Gong

This patch adds a new interface to decode memory device (type 17) to help error reporting on DIMMs.

Original-author: Tony Luck <[email protected]>

Just a question below:

Quoted 7 lines
---
 arch/ia64/kernel/setup.c    |  1 +
 arch/x86/kernel/setup.c     |  1 +
 drivers/firmware/dmi_scan.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/dmi.h         |  5 ++++
 4 files changed, 67 insertions(+)

[ ... ]

Quoted 29 lines
drivers/firmware/dmi_scan.c +14 -0
index fa0affb..ca3619d 100644
@@ -25,6 +25,13 @@ static int dmi_initialized;
 /* DMI system identification string used during boot */
 static char dmi_ids_string[128] __initdata;
 
+static struct dmi_memdev_info {
+	const char *device;
+	const char *bank;
+	u16 handle;
+} *dmi_memdev;
+static int dmi_memdev_nr;
+
 static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
 {
 	const u8 *bp = ((u8 *) dm) + dm->length;
@@ -322,6 +329,42 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
 	dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
 }
 
+static void __init count_mem_devices(const struct dmi_header *dm, void *v)
+{
+	if (dm->type != DMI_ENTRY_MEM_DEVICE)
+		return;
+	dmi_memdev_nr++;
+}
+

drivers/firmware/dmi_scan.c static void __init dmi_save_extended_devices(const struct dmi_header *dm) · line 348

Quoted 10 lines
drivers/firmware/dmi_scan.c +10 -0
+static void __init save_mem_devices(const struct dmi_header *dm, void *v)
+{
+	const char *d = (const char *)dm;
+	static int nr;
+
+	if (dm->type != DMI_ENTRY_MEM_DEVICE)
+		return;
+	if (nr >= dmi_memdev_nr) {
+		pr_warn_once("Too many DIMM entries in SMBIOS table\n");
+		return;

Is this and count_mem_devices() some sort of precaution against insane DMI tables?

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#24 lore raw

Re: [PATCH 4/8] DMI: Parse memory device (type 17) in SMBIOS

Quoted 63 lines · Borislav Petkov

Date: Fri, 11 Oct 2013 17:40:48 +0200
From: Borislav Petkov <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 4/8] DMI: Parse memory device (type 17) in SMBIOS
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 5 lines · Gong

This patch adds a new interface to decode memory device (type 17) to help error reporting on DIMMs.

Original-author: Tony Luck <[email protected]>

Just a question below:

Quoted 7 lines
---
 arch/ia64/kernel/setup.c    |  1 +
 arch/x86/kernel/setup.c     |  1 +
 drivers/firmware/dmi_scan.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/dmi.h         |  5 ++++
 4 files changed, 67 insertions(+)

[ ... ]

Quoted 34 lines
drivers/firmware/dmi_scan.c +19 -0
index fa0affb..ca3619d 100644
@@ -25,6 +25,13 @@ static int dmi_initialized;
 /* DMI system identification string used during boot */
 static char dmi_ids_string[128] __initdata;
 
+static struct dmi_memdev_info {
+	const char *device;
+	const char *bank;
+	u16 handle;
+} *dmi_memdev;
+static int dmi_memdev_nr;
+
 static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
 {
 	const u8 *bp = ((u8 *) dm) + dm->length;
@@ -322,6 +329,42 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
 	dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
 }
 
+static void __init count_mem_devices(const struct dmi_header *dm, void *v)
+{
+	if (dm->type != DMI_ENTRY_MEM_DEVICE)
+		return;
+	dmi_memdev_nr++;
+}
+
+static void __init save_mem_devices(const struct dmi_header *dm, void *v)
+{
+	const char *d = (const char *)dm;
+	static int nr;
+
Quoted 9 lines

drivers/firmware/dmi_scan.c static void __init dmi_save_extended_devices(const struct dmi_header *dm) · line 348

Quoted 5 lines
drivers/firmware/dmi_scan.c +5 -0
+	if (dm->type != DMI_ENTRY_MEM_DEVICE)
+		return;
+	if (nr >= dmi_memdev_nr) {
+		pr_warn_once("Too many DIMM entries in SMBIOS table\n");
+		return;

Is this and count_mem_devices() some sort of precaution against insane DMI tables?

Yes, but we highly expect BIOS manufactors to make is valid and complete.

Quoted 6 lines
Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
maintainer
#25 lore raw

Re: [PATCH 4/8] DMI: Parse memory device (type 17) in SMBIOS

Quoted 2 lines · Chen Gong

Yes, but we highly expect BIOS manufactors to make is valid and complete.

Well, you can always do sanity checks with FW_BUG noisy printks. I don't see any other way to move fw vendors - simply expecting them is not an incentive enough, IMO. :-)

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
Acked-by on v1 4/8
#26 lore raw

Re: [PATCH 4/8] DMI: Parse memory device (type 17) in SMBIOS

In reply to Chen, Gong
Quoted 11 lines · Chen Gong

This patch adds a new interface to decode memory device (type 17) to help error reporting on DIMMs.

Original-author: Tony Luck <[email protected]>

---
 arch/ia64/kernel/setup.c    |  1 +
 arch/x86/kernel/setup.c     |  1 +
 drivers/firmware/dmi_scan.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/dmi.h         |  5 ++++
 4 files changed, 67 insertions(+)
author
#27 lore raw

PATCH 5/8 ACPI, APEI, CPER: Add UEFI 2.4 support for memory error

In reply to Chen, Gong

In latest UEFI spec(by now it is 2.4) memory error definition for CPER (UEFI 2.4 Appendix N Common Platform Error Record) adds some new fields. These fields help people to locate memory error on actual DIMM location.

Original-author: Tony Luck <[email protected]>

---
 drivers/acpi/apei/cper.c | 3 ++-
 include/linux/cper.h     | 7 +++++++
 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/acpi/apei/cper.c +2 -1
index b2e4134..680230c 100644
@@ -8,7 +8,7 @@
  * various tables, such as ERST, BERT and HEST etc.
  *
  * For more information about CPER, please refer to Appendix N of UEFI
- * Specification version 2.3.
+ * Specification version 2.4.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version
@@ -191,6 +191,7 @@ static const char *cper_mem_err_type_strs[] = {
 	"memory sparing",
 	"scrub corrected error",
 	"scrub uncorrected error",
+	"Physical Memory Map-out event",
 };
 
 static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
include/linux/cper.h +7 -0
index c230494..bd01c9a 100644
@@ -232,6 +232,9 @@ enum {
 #define CPER_MEM_VALID_RESPONDER_ID		0x1000
 #define CPER_MEM_VALID_TARGET_ID		0x2000
 #define CPER_MEM_VALID_ERROR_TYPE		0x4000
+#define CPER_MEM_VALID_RANK_NUMBER		0x8000
+#define CPER_MEM_VALID_CARD_HANDLE		0x10000
+#define CPER_MEM_VALID_MODULE_HANDLE		0x20000
 
 #define CPER_PCIE_VALID_PORT_TYPE		0x0001
 #define CPER_PCIE_VALID_VERSION			0x0002
@@ -347,6 +350,10 @@ struct cper_sec_mem_err {
 	__u64	responder_id;
 	__u64	target_id;
 	__u8	error_type;
+	__u8	reserved;
+	__u16	rank;
+	__u16	mem_array_handle;
+	__u16	mem_dev_handle;
 };
 
 struct cper_sec_pcie {
Signature · 1 line
1.8.4.rc3
maintainer Reviewed-by on v1 5/8
#28 lore raw

Re: [PATCH 5/8] ACPI, APEI, CPER: Add UEFI 2.4 support for memory error

Quoted 7 lines · Gong

In latest UEFI spec(by now it is 2.4) memory error definition for CPER (UEFI 2.4 Appendix N Common Platform Error Record) adds some new fields. These fields help people to locate memory error on actual DIMM location.

Original-author: Tony Luck <[email protected]>

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#29 lore raw

Re: [PATCH 5/8] ACPI, APEI, CPER: Add UEFI 2.4 support for memory error

In reply to Chen, Gong
Quoted 26 lines · Chen Gong

In latest UEFI spec(by now it is 2.4) memory error definition for CPER (UEFI 2.4 Appendix N Common Platform Error Record) adds some new fields. These fields help people to locate memory error on actual DIMM location.

Original-author: Tony Luck <[email protected]>

---
 drivers/acpi/apei/cper.c | 3 ++-
 include/linux/cper.h     | 7 +++++++
 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/acpi/apei/cper.c +1 -1
index b2e4134..680230c 100644
@@ -8,7 +8,7 @@
  * various tables, such as ERST, BERT and HEST etc.
  *
  * For more information about CPER, please refer to Appendix N of UEFI
- * Specification version 2.3.
+ * Specification version 2.4.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version

drivers/acpi/apei/cper.c static const char *cper_mem_err_type_strs[] = { · line 194

Quoted 4 lines
drivers/acpi/apei/cper.c +1 -0
@@ -191,6 +191,7 @@ static const char *cper_mem_err_type_strs[] = {
 	"memory sparing",
 	"scrub corrected error",
 	"scrub uncorrected error",
+	"Physical Memory Map-out event",

All small letters to match the rest of the items:
"physical memory map-out event"

Quoted 18 lines
drivers/acpi/apei/cper.c +0 -0
 };
 
 static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
include/linux/cper.h +3 -0
index c230494..bd01c9a 100644
@@ -232,6 +232,9 @@ enum {
 #define CPER_MEM_VALID_RESPONDER_ID		0x1000
 #define CPER_MEM_VALID_TARGET_ID		0x2000
 #define CPER_MEM_VALID_ERROR_TYPE		0x4000
+#define CPER_MEM_VALID_RANK_NUMBER		0x8000
+#define CPER_MEM_VALID_CARD_HANDLE		0x10000
+#define CPER_MEM_VALID_MODULE_HANDLE		0x20000
 
 #define CPER_PCIE_VALID_PORT_TYPE		0x0001
 #define CPER_PCIE_VALID_VERSION			0x0002

include/linux/cper.h struct cper_sec_mem_err { · line 356

Quoted 7 lines
include/linux/cper.h +4 -0
@@ -347,6 +350,10 @@ struct cper_sec_mem_err {
 	__u64	responder_id;
 	__u64	target_id;
 	__u8	error_type;
+	__u8	reserved;
+	__u16	rank;
+	__u16	mem_array_handle;
+	__u16	mem_dev_handle;

Nit: could you name those fields similar to what the spec has:
card_handle and module_handle, with perhaps a comment to indicate relationship to SMBIOS type 16/17 tables?

Regards,
Naveen

Quoted 6 lines
include/linux/cper.h +0 -0
 };
 
 struct cper_sec_pcie {
Signature · 1 line
1.8.4.rc3
author
#30 lore raw

Re: [PATCH 5/8] ACPI, APEI, CPER: Add UEFI 2.4 support for memory error

Quoted 35 lines · Naveen N. Rao

Date: Tue, 15 Oct 2013 22:56:25 +0530
From: "Naveen N. Rao" <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 5/8] ACPI, APEI, CPER: Add UEFI 2.4 support for memory
error
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 25 lines · Chen Gong

In latest UEFI spec(by now it is 2.4) memory error definition for CPER (UEFI 2.4 Appendix N Common Platform Error Record) adds some new fields. These fields help people to locate memory error on actual DIMM location.

Original-author: Tony Luck <[email protected]>

---
 drivers/acpi/apei/cper.c | 3 ++-
 include/linux/cper.h     | 7 +++++++
 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/acpi/apei/cper.c +1 -1
index b2e4134..680230c 100644
@@ -8,7 +8,7 @@
  * various tables, such as ERST, BERT and HEST etc.
  *
  * For more information about CPER, please refer to Appendix N of UEFI
- * Specification version 2.3.
+ * Specification version 2.4.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version
Quoted 9 lines

drivers/acpi/apei/cper.c static const char *cper_mem_err_type_strs[] = { · line 194

Quoted 5 lines
drivers/acpi/apei/cper.c +1 -0
@@ -191,6 +191,7 @@ static const char *cper_mem_err_type_strs[] = {
 	"memory sparing",
 	"scrub corrected error",
 	"scrub uncorrected error",
+	"Physical Memory Map-out event",

All small letters to match the rest of the items:
"physical memory map-out event"

sure, of course.

Quoted 15 lines
Quoted 15 lines
drivers/acpi/apei/cper.c +0 -0
 };
 
 static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
include/linux/cper.h +3 -0
index c230494..bd01c9a 100644
@@ -232,6 +232,9 @@ enum {
 #define CPER_MEM_VALID_RESPONDER_ID		0x1000
 #define CPER_MEM_VALID_TARGET_ID		0x2000
 #define CPER_MEM_VALID_ERROR_TYPE		0x4000
+#define CPER_MEM_VALID_RANK_NUMBER		0x8000
+#define CPER_MEM_VALID_CARD_HANDLE		0x10000
+#define CPER_MEM_VALID_MODULE_HANDLE		0x20000
 
Quoted 16 lines

include/linux/cper.h struct cper_sec_mem_err { · line 356

Quoted 10 lines
include/linux/cper.h +4 -0
 #define CPER_PCIE_VALID_PORT_TYPE		0x0001
 #define CPER_PCIE_VALID_VERSION			0x0002
@@ -347,6 +350,10 @@ struct cper_sec_mem_err {
 	__u64	responder_id;
 	__u64	target_id;
 	__u8	error_type;
+	__u8	reserved;
+	__u16	rank;
+	__u16	mem_array_handle;
+	__u16	mem_dev_handle;

Nit: could you name those fields similar to what the spec has:
card_handle and module_handle, with perhaps a comment to indicate relationship to SMBIOS type 16/17 tables?

On the contrary, what I'm thinking is reserve these names but adding comments for what it is in the spec. I consider a reasonable name is more meaningful than just following the spec strictly.

Quoted 10 lines

Regards,
Naveen

Quoted 6 lines
include/linux/cper.h +0 -0
 };
 
 struct cper_sec_pcie {
Signature · 1 line
1.8.4.rc3
author
#31 lore raw

PATCH 6/8 ACPI, APEI, CPER: Enhance memory reporting capability

In reply to Chen, Gong

After H/W error happens under FFM enabled mode, lots of information are shown but some important parts like DIMM location missed. This patch is used to show these extra fileds.

Original-author: Tony Luck <[email protected]>

---
 drivers/acpi/apei/cper.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/acpi/apei/cper.c +12 -0
index 680230c..2a4389f 100644
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/cper.h>
+#include <linux/dmi.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
@@ -210,6 +211,8 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		printk("%s""card: %d\n", pfx, mem->card);
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
 		printk("%s""module: %d\n", pfx, mem->module);
+	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
+		printk("%s""rank: %d\n", pfx, mem->rank);
 	if (mem->validation_bits & CPER_MEM_VALID_BANK)
 		printk("%s""bank: %d\n", pfx, mem->bank);
 	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
@@ -232,6 +235,15 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		       etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
 		       cper_mem_err_type_strs[etype] : "unknown");
 	}
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
+		const char *bank = NULL, *device = NULL;
+		dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
+		if (bank != NULL && device != NULL)
+			printk("%s""DIMM location: %s %s", pfx, bank, device);
+		else
+			printk("%s""DIMM DMI handle: 0x%.4x", pfx,
+					mem->mem_dev_handle);
+	}
 }
 
 static const char *cper_pcie_port_type_strs[] = {
Signature · 1 line
1.8.4.rc3
maintainer
#32 lore raw

Re: [PATCH 6/8] ACPI, APEI, CPER: Enhance memory reporting capability

Quoted 33 lines · Gong

After H/W error happens under FFM enabled mode, lots of information are shown but some important parts like DIMM location missed. This patch is used to show these extra fileds.

Original-author: Tony Luck <[email protected]>

---
 drivers/acpi/apei/cper.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/acpi/apei/cper.c +3 -0
index 680230c..2a4389f 100644
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/cper.h>
+#include <linux/dmi.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
@@ -210,6 +211,8 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		printk("%s""card: %d\n", pfx, mem->card);
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
 		printk("%s""module: %d\n", pfx, mem->module);
+	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
+		printk("%s""rank: %d\n", pfx, mem->rank);
 	if (mem->validation_bits & CPER_MEM_VALID_BANK)
 		printk("%s""bank: %d\n", pfx, mem->bank);
 	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
@@ -232,6 +235,15 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		       etype < ARRAY_SIZE(cper_mem_err_type_strs) ?

drivers/acpi/apei/cper.c static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) · line 245

Quoted 10 lines
drivers/acpi/apei/cper.c +8 -0
 		       cper_mem_err_type_strs[etype] : "unknown");
 	}
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
+		const char *bank = NULL, *device = NULL;
+		dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
+		if (bank != NULL && device != NULL)
+			printk("%s""DIMM location: %s %s", pfx, bank, device);
+		else
+			printk("%s""DIMM DMI handle: 0x%.4x", pfx,
+					mem->mem_dev_handle);

Just a nitpick: maybe better arg alignment:

			printk("%s""DIMM DMI handle: 0x%.4x",
			       pfx, mem->mem_dev_handle);
Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
Acked-by on v1 6/8
#33 lore raw

Re: [PATCH 6/8] ACPI, APEI, CPER: Enhance memory reporting capability

In reply to Chen, Gong
Quoted 10 lines · Chen Gong

After H/W error happens under FFM enabled mode, lots of information are shown but some important parts like DIMM location missed. This patch is used to show these extra fileds.

Original-author: Tony Luck <[email protected]>

---
 drivers/acpi/apei/cper.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
Quoted 40 lines
drivers/acpi/apei/cper.c +12 -0
index 680230c..2a4389f 100644
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/cper.h>
+#include <linux/dmi.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
@@ -210,6 +211,8 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		printk("%s""card: %d\n", pfx, mem->card);
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
 		printk("%s""module: %d\n", pfx, mem->module);
+	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
+		printk("%s""rank: %d\n", pfx, mem->rank);
 	if (mem->validation_bits & CPER_MEM_VALID_BANK)
 		printk("%s""bank: %d\n", pfx, mem->bank);
 	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
@@ -232,6 +235,15 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		       etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
 		       cper_mem_err_type_strs[etype] : "unknown");
 	}
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
+		const char *bank = NULL, *device = NULL;
+		dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
+		if (bank != NULL && device != NULL)
+			printk("%s""DIMM location: %s %s", pfx, bank, device);
+		else
+			printk("%s""DIMM DMI handle: 0x%.4x", pfx,
+					mem->mem_dev_handle);
+	}
 }
 
 static const char *cper_pcie_port_type_strs[] = {
Signature · 1 line
1.8.4.rc3
author
#34 lore raw

PATCH 7/8 ACPI, APEI, CPER: Cleanup CPER memory error output format

In reply to Chen, Gong

Keep up only the most important fields for memory error reporting. The detail information will be moved to perf/trace interface.

---
 drivers/acpi/apei/cper.c | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)
drivers/acpi/apei/cper.c +14 -28
index 2a4389f..567410e 100644
@@ -206,29 +206,29 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		printk("%s""physical_address_mask: 0x%016llx\n",
 		       pfx, mem->physical_addr_mask);
 	if (mem->validation_bits & CPER_MEM_VALID_NODE)
-		printk("%s""node: %d\n", pfx, mem->node);
+		pr_debug("node: %d\n", mem->node);
 	if (mem->validation_bits & CPER_MEM_VALID_CARD)
-		printk("%s""card: %d\n", pfx, mem->card);
+		pr_debug("card: %d\n", mem->card);
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
-		printk("%s""module: %d\n", pfx, mem->module);
+		pr_debug("module: %d\n", mem->module);
 	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
-		printk("%s""rank: %d\n", pfx, mem->rank);
+		pr_debug("rank: %d\n", mem->rank);
 	if (mem->validation_bits & CPER_MEM_VALID_BANK)
-		printk("%s""bank: %d\n", pfx, mem->bank);
+		pr_debug("bank: %d\n", mem->bank);
 	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
-		printk("%s""device: %d\n", pfx, mem->device);
+		pr_debug("device: %d\n", mem->device);
 	if (mem->validation_bits & CPER_MEM_VALID_ROW)
-		printk("%s""row: %d\n", pfx, mem->row);
+		pr_debug("row: %d\n", mem->row);
 	if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
-		printk("%s""column: %d\n", pfx, mem->column);
+		pr_debug("column: %d\n", mem->column);
 	if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
-		printk("%s""bit_position: %d\n", pfx, mem->bit_pos);
+		pr_debug("bit_position: %d\n", mem->bit_pos);
 	if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
-		printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id);
+		pr_debug("requestor_id: 0x%016llx\n", mem->requestor_id);
 	if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
-		printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id);
+		pr_debug("responder_id: 0x%016llx\n", mem->responder_id);
 	if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
-		printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id);
+		pr_debug("target_id: 0x%016llx\n", mem->target_id);
 	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
 		u8 etype = mem->error_type;
 		printk("%s""error_type: %d, %s\n", pfx, etype,
@@ -296,15 +296,6 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
 	pfx, pcie->bridge.secondary_status, pcie->bridge.control);
 }
 
-static const char *cper_estatus_section_flag_strs[] = {
-	"primary",
-	"containment warning",
-	"reset",
-	"error threshold exceeded",
-	"resource not accessible",
-	"latent error",
-};
-
 static void cper_estatus_print_section(
 	const char *pfx, const struct acpi_generic_data *gdata, int sec_no)
 {
@@ -312,11 +303,8 @@ static void cper_estatus_print_section(
 	__u16 severity;
 
 	severity = gdata->error_severity;
-	printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity,
+	printk("%s""sub_event[%d], severity: %s\n", pfx, sec_no,
 	       cper_severity_str(severity));
-	printk("%s""flags: 0x%02x\n", pfx, gdata->flags);
-	cper_print_bits(pfx, gdata->flags, cper_estatus_section_flag_strs,
-			ARRAY_SIZE(cper_estatus_section_flag_strs));
 	if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
 		printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
 	if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
@@ -360,10 +348,8 @@ void cper_estatus_print(const char *pfx,
 	int sec_no = 0;
 	__u16 severity;
 
-	printk("%s""Generic Hardware Error Status\n", pfx);
 	severity = estatus->error_severity;
-	printk("%s""severity: %d, %s\n", pfx, severity,
-	       cper_severity_str(severity));
+	printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
 	data_len = estatus->data_length;
 	gdata = (struct acpi_generic_data *)(estatus + 1);
 	while (data_len >= sizeof(*gdata)) {
Signature · 1 line
1.8.4.rc3
maintainer
#35 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 46 lines · Gong

Keep up only the most important fields for memory error reporting. The detail information will be moved to perf/trace interface.

---
 drivers/acpi/apei/cper.c | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)
drivers/acpi/apei/cper.c +9 -10
index 2a4389f..567410e 100644
@@ -206,29 +206,29 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		printk("%s""physical_address_mask: 0x%016llx\n",
 		       pfx, mem->physical_addr_mask);
 	if (mem->validation_bits & CPER_MEM_VALID_NODE)
-		printk("%s""node: %d\n", pfx, mem->node);
+		pr_debug("node: %d\n", mem->node);
 	if (mem->validation_bits & CPER_MEM_VALID_CARD)
-		printk("%s""card: %d\n", pfx, mem->card);
+		pr_debug("card: %d\n", mem->card);
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
-		printk("%s""module: %d\n", pfx, mem->module);
+		pr_debug("module: %d\n", mem->module);
 	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
-		printk("%s""rank: %d\n", pfx, mem->rank);
+		pr_debug("rank: %d\n", mem->rank);
 	if (mem->validation_bits & CPER_MEM_VALID_BANK)
-		printk("%s""bank: %d\n", pfx, mem->bank);
+		pr_debug("bank: %d\n", mem->bank);
 	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
-		printk("%s""device: %d\n", pfx, mem->device);
+		pr_debug("device: %d\n", mem->device);
 	if (mem->validation_bits & CPER_MEM_VALID_ROW)
-		printk("%s""row: %d\n", pfx, mem->row);
+		pr_debug("row: %d\n", mem->row);
 	if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
-		printk("%s""column: %d\n", pfx, mem->column);
+		pr_debug("column: %d\n", mem->column);
 	if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
-		printk("%s""bit_position: %d\n", pfx, mem->bit_pos);
+		pr_debug("bit_position: %d\n", mem->bit_pos);
 	if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
-		printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id);

drivers/acpi/apei/cper.c static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) · line 234

Quoted 10 lines
drivers/acpi/apei/cper.c +3 -2
+		pr_debug("requestor_id: 0x%016llx\n", mem->requestor_id);
 	if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
-		printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id);
+		pr_debug("responder_id: 0x%016llx\n", mem->responder_id);
 	if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
-		printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id);
+		pr_debug("target_id: 0x%016llx\n", mem->target_id);
 	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
 		u8 etype = mem->error_type;
 		printk("%s""error_type: %d, %s\n", pfx, etype,

Hmm, so this cper_print_mem is called for CPER_SEC_PLATFORM_MEM section type.

With the change above, the other caller __ghes_print_estatus() won't see the error messages if they're debug. Do we want that?

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#36 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 70 lines · Borislav Petkov

Date: Fri, 11 Oct 2013 18:02:08 +0200
From: Borislav Petkov <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output
format
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 46 lines · Gong

Keep up only the most important fields for memory error reporting. The detail information will be moved to perf/trace interface.

---
 drivers/acpi/apei/cper.c | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)
drivers/acpi/apei/cper.c +9 -10
index 2a4389f..567410e 100644
@@ -206,29 +206,29 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 		printk("%s""physical_address_mask: 0x%016llx\n",
 		       pfx, mem->physical_addr_mask);
 	if (mem->validation_bits & CPER_MEM_VALID_NODE)
-		printk("%s""node: %d\n", pfx, mem->node);
+		pr_debug("node: %d\n", mem->node);
 	if (mem->validation_bits & CPER_MEM_VALID_CARD)
-		printk("%s""card: %d\n", pfx, mem->card);
+		pr_debug("card: %d\n", mem->card);
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
-		printk("%s""module: %d\n", pfx, mem->module);
+		pr_debug("module: %d\n", mem->module);
 	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
-		printk("%s""rank: %d\n", pfx, mem->rank);
+		pr_debug("rank: %d\n", mem->rank);
 	if (mem->validation_bits & CPER_MEM_VALID_BANK)
-		printk("%s""bank: %d\n", pfx, mem->bank);
+		pr_debug("bank: %d\n", mem->bank);
 	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
-		printk("%s""device: %d\n", pfx, mem->device);
+		pr_debug("device: %d\n", mem->device);
 	if (mem->validation_bits & CPER_MEM_VALID_ROW)
-		printk("%s""row: %d\n", pfx, mem->row);
+		pr_debug("row: %d\n", mem->row);
 	if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
-		printk("%s""column: %d\n", pfx, mem->column);
+		pr_debug("column: %d\n", mem->column);
 	if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
-		printk("%s""bit_position: %d\n", pfx, mem->bit_pos);
+		pr_debug("bit_position: %d\n", mem->bit_pos);
 	if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
-		printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id);

drivers/acpi/apei/cper.c static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) · line 234

Quoted 10 lines
drivers/acpi/apei/cper.c +3 -2
+		pr_debug("requestor_id: 0x%016llx\n", mem->requestor_id);
 	if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
-		printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id);
+		pr_debug("responder_id: 0x%016llx\n", mem->responder_id);
 	if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
-		printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id);
+		pr_debug("target_id: 0x%016llx\n", mem->target_id);
 	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
 		u8 etype = mem->error_type;
 		printk("%s""error_type: %d, %s\n", pfx, etype,

Hmm, so this cper_print_mem is called for CPER_SEC_PLATFORM_MEM section type.

Quoted 3 lines

With the change above, the other caller __ghes_print_estatus() won't see the error messages if they're debug. Do we want that?

Because most of data in CPER are empty or unimportant. To avoid too much disturbance to end users, it is worthy to do that. Moreover, I reserve another way via trace to show these data.

Quoted 6 lines
Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
maintainer
#37 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 1 line · Chen Gong

Because most of data in CPER are empty or unimportant.

It is not about whether it is important or not - the question is whether changing existing functionality which someone might rely upon is a problem here? Someone might be expecting exactly those messages to appear in dmesg.

Btw, what is the real reason for this patch, to save yourself the output in dmesg? If so, you can disable this output when eMCA module has been loaded but leave it intact otherwise.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#38 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 7 lines · Borislav Petkov
Quoted 1 line · Chen Gong

Because most of data in CPER are empty or unimportant.

It is not about whether it is important or not - the question is whether changing existing functionality which someone might rely upon is a problem here? Someone might be expecting exactly those messages to appear in dmesg.

Pulling in a couple more people who have been touching error reporting code in the last year or so (Hi Lance, Naveen ... feel free to drag more people to look at this thread).

I prodded Chen Gong in to make this change because our console messages are way to verbose (and scary) for simple corrected errors. There are 18 fields in the memory error section (as of UEFI 2.4 ... more are likely to be added because there are issues that some of the 16-bit wide fields are too small to handle increased internal values in modern DIMMs). Whether you print that one item per line, or a few very long lines - it is way more information
than the average user will ever want or need to see.

Quoted 3 lines

Btw, what is the real reason for this patch, to save yourself the output in dmesg? If so, you can disable this output when eMCA module has been loaded but leave it intact otherwise.

This is an excellent idea - if the full data is being logged via TRACE, then we can drop to virtually nothing on the console (just have something similar to the "Machine check events logged" message so that people will get a tip that they might want to go dig into other logs). Maybe something like:
%d corrected memory errors\n", count
[rate limited]

But we'd have to make sure that the existing user(s) of this code also have a TRACE path.

-Tony

maintainer
#39 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 9 lines · Tony Luck

This is an excellent idea - if the full data is being logged via TRACE, then we can drop to virtually nothing on the console (just have something similar to the "Machine check events logged" message so that people will get a tip that they might want to go dig into other logs). Maybe something like: %d corrected memory errors\n", count [rate limited]

But we'd have to make sure that the existing user(s) of this code also have a TRACE path.

It is basically the same idea as with the ras daemon - if we have a userspace consumer of ras trace events, we disable dmesg output. So the decision will be left to the userspace tool to disable dmesg output as a last step of its initialization.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#40 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 4 lines · Borislav Petkov

It is basically the same idea as with the ras daemon - if we have a userspace consumer of ras trace events, we disable dmesg output. So the decision will be left to the userspace tool to disable dmesg output as a last step of its initialization.

Do you have a suggested mechanism for this disabling of dmesg?

-Tony

maintainer
#41 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 1 line · Tony Luck

Do you have a suggested mechanism for this disabling of dmesg?

Hmm, how about a 64-bit flag variable (we can use the remaining bits for other stuff later) called x86_ras_flags which is private to arch/x86/ras/core.c (a new file)...

[ btw, I'm thinking of something similar to efi's x86_efi_facility which we nicely query with test_bit and set with set_bit and clear_bit, etc, etc ]

Also, look at arch/x86/platform/efi/efi.c::efi_enabled() how it hides the actual variable and we can do something similar so that eMCA and other users like cper.c can do

apei_estatus_print_section:

	if (!ras_tracepoint_enabled())
		cper_print_mem(...)

We set the bit in x86_ras_flags from, say, debugfs, i.e., a userspace tool sets it and from that moment on all RAS output is rerouted to the trace event. I.e., the output for which there is a trace event...

How does that look like?

Purely hypothetical, of course, I might me missing something but it looks ok from here. As always, the devil is in the detail, of course.

HTH.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#42 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 27 lines · Borislav Petkov

Date: Mon, 14 Oct 2013 23:50:47 +0200
From: Borislav Petkov <[email protected]>
To: Tony Luck <[email protected]>
Cc: Chen Gong <[email protected]>, Linux Kernel Mailing List
<[email protected]>, linux-acpi <[email protected]>, Lance Ortiz <[email protected]>, "Naveen N. Rao" <[email protected]>
Subject: Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output
format
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 1 line · Tony Luck

Do you have a suggested mechanism for this disabling of dmesg?

Hmm, how about a 64-bit flag variable (we can use the remaining bits for other stuff later) called x86_ras_flags which is private to arch/x86/ras/core.c (a new file)...

[ btw, I'm thinking of something similar to efi's x86_efi_facility which we nicely query with test_bit and set with set_bit and clear_bit, etc, etc ]

Also, look at arch/x86/platform/efi/efi.c::efi_enabled() how it hides the actual variable and we can do something similar so that eMCA and other users like cper.c can do

apei_estatus_print_section:

Quoted 9 lines
	if (!ras_tracepoint_enabled())
		cper_print_mem(...)

We set the bit in x86_ras_flags from, say, debugfs, i.e., a userspace tool sets it and from that moment on all RAS output is rerouted to the trace event. I.e., the output for which there is a trace event...

How does that look like?

Looks fine to me. But a little bit out of current patch series. How about adding such interfaces after this patch series is merged? And from your words, it looks like you prefer to reserve all current fields to avoid breaking user space things. IOW, drop patch [7/8] and use another patch with above idea to get the same purpose. This is what you want, Boris?

maintainer
#43 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 2 lines · Chen Gong

Looks fine to me. But a little bit out of current patch series. How about adding such interfaces after this patch series is merged?

Ok.

Quoted 2 lines

And from your words, it looks like you prefer to reserve all current fields to avoid breaking user space things. IOW, drop patch [7/8]

Well, I was simply wondering whether something is using those. And since we don't know, apparently, we probably should keep them for now.

Quoted 2 lines

and use another patch with above idea to get the same purpose. This is what you want, Boris?

Yeah, let's not break userspace. :-)

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#44 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

In reply to Tony Luck
Quoted 13 lines · Tony Luck
Quoted 7 lines · Borislav Petkov
Quoted 1 line · Chen Gong

Because most of data in CPER are empty or unimportant.

It is not about whether it is important or not - the question is whether changing existing functionality which someone might rely upon is a problem here? Someone might be expecting exactly those messages to appear in dmesg.

Pulling in a couple more people who have been touching error reporting code in the last year or so (Hi Lance, Naveen ... feel free to drag more people to look at this thread).

Quoted 8 lines

I prodded Chen Gong in to make this change because our console messages are way to verbose (and scary) for simple corrected errors. There are 18 fields in the memory error section (as of UEFI 2.4 ... more are likely to be added because there are issues that some of the 16-bit wide fields are too small to handle increased internal values in modern DIMMs). Whether you print that one item per line, or a few very long lines - it is way more information
than the average user will ever want or need to see.

I completely agree and I am all for bringing down the verbosity of GHES logs. In my testing, a corrected error event reported through GHES takes upwards of 10 lines, which is far too much. Perhaps a single line per GHES event with only a few important fields would be better?

Thanks,
Naveen

#45 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

In reply to Tony Luck
Quoted 8 lines · Tony Luck
Quoted 7 lines · Borislav Petkov
Quoted 1 line · Chen Gong

Because most of data in CPER are empty or unimportant.

It is not about whether it is important or not - the question is whether changing existing functionality which someone might rely upon is a problem here? Someone might be expecting exactly those messages to appear in dmesg.

If so, how will disabling dmesg output and switching to a trace event help? The user-space program will still break unless they add support for that trace event, right?

I'm not sure if we actually provide guarantees w.r.t kernel log messages. The issue in this specific scenario is the sheer verbosity of the log messages. I personally feel that it will be good if we can simplify the log output.

Thanks,
Naveen

maintainer
#46 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 3 lines · Naveen N. Rao

If so, how will disabling dmesg output and switching to a trace event help? The user-space program will still break unless they add support for that trace event, right?

Well, as yourself this: what happens to a userspace program which relies on this *exact* error message format and greps dmesg?

Quoted 3 lines

I'm not sure if we actually provide guarantees w.r.t kernel log messages. The issue in this specific scenario is the sheer verbosity of the log messages.

No, the issue is what I said above: userspace programs expecting exactly this output. Once we exposed it to userspace, we cannot simply assume that nothing is using it.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#47 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 2 lines · Borislav Petkov

Once we exposed it to userspace, we cannot simply assume that nothing is using it.

Yes, we can.

No guarantees are made about dmesg output.

If guarantees were made, no typo could ever be fixed nor could any conversion from printk to dev_<level> be done.

#48 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 1 line · Joe Perches

No guarantees are made about dmesg output.

I'm with Joe here. Current users that parse dmesg have grumbled a bit that format changes - but they know that's the way life is. Perhaps they'll be too busy cheering about the TRACE formats that we are going to give them that they won't whine too much about this.

-Tony

maintainer
#49 lore raw

Re: [PATCH 7/8] ACPI, APEI, CPER: Cleanup CPER memory error output format

Quoted 7 lines · Tony Luck
Quoted 1 line · Joe Perches

No guarantees are made about dmesg output.

I'm with Joe here. Current users that parse dmesg have grumbled a bit that format changes - but they know that's the way life is. Perhaps they'll be too busy cheering about the TRACE formats that we are going to give them that they won't whine too much about this.

Ok, I'll make sure to forward all complaints to you and Joe then. :)

In any case, we talked about it, you think it is not worth preserving it, we can drop the printks and see who cries out.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#50 lore raw

PATCH 8/8 ACPI / trace: Add trace interface for eMCA driver

In reply to Chen, Gong

Use trace interface to elaborate all H/W error related information.

---
 drivers/acpi/Kconfig        |   7 ++-
 drivers/acpi/Makefile       |   4 ++
 drivers/acpi/acpi_extlog.c  |  28 +++++++++++-
 drivers/acpi/apei/cper.c    |  13 ++++--
 drivers/acpi/debug_extlog.h |  16 +++++++
 drivers/acpi/extlog_trace.c | 105 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/extlog_trace.h |  77 ++++++++++++++++++++++++++++++++
 include/linux/cper.h        |   2 +
 8 files changed, 246 insertions(+), 6 deletions(-)
 create mode 100644 drivers/acpi/debug_extlog.h
 create mode 100644 drivers/acpi/extlog_trace.c
 create mode 100644 drivers/acpi/extlog_trace.h
drivers/acpi/Kconfig +6 -1
index 1465fa8..9ea343e 100644
@@ -372,12 +372,17 @@ config ACPI_BGRT
 
 source "drivers/acpi/apei/Kconfig"
 
+config EXTLOG_TRACE
+	def_bool n
+
 config ACPI_EXTLOG
 	tristate "Extended Error Log support"
 	depends on X86 && X86_MCE
+	select EXTLOG_TRACE
 	default n
 	help
 	  This driver adds support for decoding extended errors from hardware.
-	  which allows the operating system to obtain data from trace.
+	  which allows the operating system to obtain data from trace. It will
+	  appear under /sys/kernel/debug/tracing/ras/ .
 
 endif	# ACPI
drivers/acpi/Makefile +4 -0
index bce34af..a6e41b7 100644
@@ -83,4 +83,8 @@ obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
 
 obj-$(CONFIG_ACPI_APEI)		+= apei/
 
+# extended log support
+acpi-$(CONFIG_EXTLOG_TRACE)	+= extlog_trace.o
+CFLAGS_extlog_trace.o := -I$(src)
+
 obj-$(CONFIG_ACPI_EXTLOG)	+= acpi_extlog.o
drivers/acpi/acpi_extlog.c +26 -2
index 3e3e286..ca51eb0 100644
@@ -26,6 +26,7 @@
 #include <asm/mce.h>
 
 #include "apei/apei-internal.h"
+#include "debug_extlog.h"
 
 #define EXT_ELOG_ENTRY_MASK	0xfffffffffffff /* elog entry address mask */
 
@@ -55,6 +56,8 @@ struct extlog_l1_head {
 
 static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295";
 
+static const uuid_le invalid_uuid = NULL_UUID_LE;
+
 /* L1 table related physical address */
 static u64 elog_base;
 static size_t elog_size;
@@ -143,7 +146,12 @@ static int print_extlog_rcd(const char *pfx,
 
 static int extlog_print(const char *pfx, int cpu, int bank)
 {
-	struct acpi_generic_status *estatus;
+	struct acpi_generic_status *estatus, *tmp;
+	struct acpi_generic_data *gdata;
+	const uuid_le *fru_id = &invalid_uuid;
+	char *fru_text = "";
+	uuid_le *sec_type;
+	static u64 err_count;
 	int rc;
 
 	estatus = extlog_elog_entry_check(cpu, bank);
@@ -154,7 +162,23 @@ static int extlog_print(const char *pfx, int cpu, int bank)
 	/* clear record status to enable BIOS to update it again */
 	estatus->block_status = 0;
 
-	rc = print_extlog_rcd(pfx, (struct acpi_generic_status *)elog_buf, cpu);
+	tmp = (struct acpi_generic_status *)elog_buf;
+	gdata = (struct acpi_generic_data *)(tmp + 1);
+	rc = print_extlog_rcd(pfx, tmp, cpu);
+
+	/* trace extended error log */
+	err_count++;
+	if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+		fru_id = (uuid_le *)gdata->fru_id;
+	if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+		fru_text = gdata->fru_text;
+	sec_type = (uuid_le *)gdata->section_type;
+	if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
+		struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
+		if (gdata->error_data_length >= sizeof(*mem_err))
+			trace_mem_error(fru_id, fru_text, err_count,
+					gdata->error_severity, mem_err);
+	}
 
 	return rc;
 }
drivers/acpi/apei/cper.c +10 -3
index 567410e..0b4cfad 100644
@@ -56,11 +56,12 @@ static const char *cper_severity_strs[] = {
 	"info",
 };
 
-static const char *cper_severity_str(unsigned int severity)
+const char *cper_severity_str(unsigned int severity)
 {
 	return severity < ARRAY_SIZE(cper_severity_strs) ?
 		cper_severity_strs[severity] : "unknown";
 }
+EXPORT_SYMBOL_GPL(cper_severity_str);
 
 /*
  * cper_print_bits - print strings for set bits
@@ -195,6 +196,13 @@ static const char *cper_mem_err_type_strs[] = {
 	"Physical Memory Map-out event",
 };
 
+const char *cper_mem_err_type_str(unsigned int etype)
+{
+	return etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
+		cper_mem_err_type_strs[etype] : "unknown";
+}
+EXPORT_SYMBOL_GPL(cper_mem_err_type_str);
+
 static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 {
 	if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
@@ -232,8 +240,7 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
 	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
 		u8 etype = mem->error_type;
 		printk("%s""error_type: %d, %s\n", pfx, etype,
-		       etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
-		       cper_mem_err_type_strs[etype] : "unknown");
+			cper_mem_err_type_str(etype));
 	}
 	if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
 		const char *bank = NULL, *device = NULL;
drivers/acpi/debug_extlog.h new file +16 -0
new file mode 100644
index 0000000..67bb2c5
@@ -0,0 +1,16 @@
+#ifndef __DEBUG_EXTLOG_H
+#define __DEBUG_EXTLOG_H
+
+#include <linux/cper.h>
+
+#ifdef CONFIG_EXTLOG_TRACE
+extern void trace_mem_error(const uuid_le *fru_id, char *fru_text,
+		u64 err_count, u32 severity, struct cper_sec_mem_err *mem);
+#else
+void trace_mem_error(const uuid_le *fru_id, char *fru_text,
+		u64 err_count, u32 severity, struct cper_sec_mem_err *mem)
+{
+}
+#endif
+
+#endif
drivers/acpi/extlog_trace.c new file +105 -0

105 lines not on this page · raw message

drivers/acpi/extlog_trace.h new file +77 -0

77 lines not on this page · raw message

include/linux/cper.h +2 -0
index bd01c9a..c00eb55 100644
@@ -395,6 +395,8 @@ struct cper_sec_pcie {
 #pragma pack()
 
 u64 cper_next_record_id(void);
+const char *cper_severity_str(unsigned int);
+const char *cper_mem_err_type_str(unsigned int);
 void cper_print_bits(const char *prefix, unsigned int bits,
 		     const char *strs[], unsigned int strs_size);
 
Signature · 1 line
1.8.4.rc3
maintainer
#51 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 7 lines · Gong
drivers/acpi/extlog_trace.h new file +1 -0
new file mode 100644
index 0000000..21f0887
@@ -0,0 +1,77 @@
+#if !defined(_TRACE_EXTLOG_H) || defined(TRACE_HEADER_MULTI_READ)

drivers/acpi/extlog_trace.h line 11

Quoted 10 lines
drivers/acpi/extlog_trace.h new file +10 -0
+#define _TRACE_EXTLOG_H
+
+#include <linux/tracepoint.h>
+#include <linux/cper.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM extlog
+
+/*
+ * MCE Extended Error Log Trace event

Right, we have a perfectly good header for ras TPs:

include/ras/ras_event.h

Mind adding this TP there please?

Quoted 83 lines
drivers/acpi/extlog_trace.h new file +66 -0
+ *
+ * These events are generated when hardware detects a corrected or
+ * uncorrected event.
+ *
+ */
+
+/* memory trace event */
+
+#define LOC_LEN		512
+#define MSG_LEN		((LOC_LEN) * 2)
+
+TRACE_EVENT(extlog_mem_event,
+	TP_PROTO(u32 etype,
+		char *dimm_loc,
+		const uuid_le *fru_id,
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),
+
+	TP_ARGS(etype, dimm_loc, fru_id, fru_text, error_count, severity,
+		phy_addr, mem_loc),
+
+	TP_STRUCT__entry(
+		__field(u32, etype)
+		__dynamic_array(char, dimm_info, LOC_LEN)
+		__field(u64, error_count)
+		__field(u32, severity)
+		__dynamic_array(char, msg, MSG_LEN)
+	),
+
+	TP_fast_assign(
+		__entry->error_count = error_count;
+		__entry->severity = severity;
+		__entry->etype = etype;
+		if (dimm_loc[0] != '\0')
+			snprintf(__get_dynamic_array(dimm_info), LOC_LEN - 1,
+				"on %s", dimm_loc);
+		else
+			__assign_str(dimm_info, "");
+		if (phy_addr != 0)
+			snprintf(__get_dynamic_array(msg), MSG_LEN - 1,
+				"(FRU: %pUl %.20s physical addr: 0x%016llx%s)",
+				fru_id, fru_text, phy_addr, mem_loc);
+		else
+			__assign_str(msg, "");
+	),
+
+	TP_printk("%llu %s error%s:%s %s%s",
+			__entry->error_count,
+			cper_severity_str(__entry->severity),
+			__entry->error_count > 1 ? "s" : "",
+			cper_mem_err_type_str(__entry->etype),
+			__get_str(dimm_info),
+			__get_str(msg))
+);
+
+#endif /* _TRACE_EXTLOG_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE extlog_trace
+#include <trace/define_trace.h>
include/linux/cper.h +2 -0
index bd01c9a..c00eb55 100644
@@ -395,6 +395,8 @@ struct cper_sec_pcie {
 #pragma pack()
 
 u64 cper_next_record_id(void);
+const char *cper_severity_str(unsigned int);
+const char *cper_mem_err_type_str(unsigned int);
 void cper_print_bits(const char *prefix, unsigned int bits,
 		     const char *strs[], unsigned int strs_size);
 
Signature · 1 line
1.8.4.rc3
Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
maintainer
#52 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

In reply to Chen, Gong
Quoted 23 lines · Gong

Use trace interface to elaborate all H/W error related information.

---
 drivers/acpi/Kconfig        |   7 ++-
 drivers/acpi/Makefile       |   4 ++
 drivers/acpi/acpi_extlog.c  |  28 +++++++++++-
 drivers/acpi/apei/cper.c    |  13 ++++--
 drivers/acpi/debug_extlog.h |  16 +++++++
 drivers/acpi/extlog_trace.c | 105 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/extlog_trace.h |  77 ++++++++++++++++++++++++++++++++
 include/linux/cper.h        |   2 +
 8 files changed, 246 insertions(+), 6 deletions(-)
 create mode 100644 drivers/acpi/debug_extlog.h
 create mode 100644 drivers/acpi/extlog_trace.c
 create mode 100644 drivers/acpi/extlog_trace.h
drivers/acpi/Kconfig +0 -0
index 1465fa8..9ea343e 100644

drivers/acpi/Kconfig config ACPI_BGRT · line 376

Quoted 5 lines
drivers/acpi/Kconfig +2 -0
@@ -372,12 +372,17 @@ config ACPI_BGRT
 
 source "drivers/acpi/apei/Kconfig"
 
+config EXTLOG_TRACE
+	def_bool n

Why the separate config item?

Quoted 18 lines
drivers/acpi/Kconfig +4 -1
+
 config ACPI_EXTLOG
 	tristate "Extended Error Log support"
 	depends on X86 && X86_MCE
+	select EXTLOG_TRACE
 	default n
 	help
 	  This driver adds support for decoding extended errors from hardware.
-	  which allows the operating system to obtain data from trace.
+	  which allows the operating system to obtain data from trace. It will
+	  appear under /sys/kernel/debug/tracing/ras/ .
 
 endif	# ACPI
drivers/acpi/Makefile +0 -0
index bce34af..a6e41b7 100644

drivers/acpi/Makefile obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o · line 87

Quoted 5 lines
drivers/acpi/Makefile +2 -0
@@ -83,4 +83,8 @@ obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
 
 obj-$(CONFIG_ACPI_APEI)		+= apei/
 
+# extended log support
+acpi-$(CONFIG_EXTLOG_TRACE)	+= extlog_trace.o

You can simply do

obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o extlog_trace.o

Quoted 3 lines
drivers/acpi/Makefile +2 -0
+CFLAGS_extlog_trace.o := -I$(src)
+
 obj-$(CONFIG_ACPI_EXTLOG)	+= acpi_extlog.o

[ ... ]

Quoted 69 lines
drivers/acpi/extlog_trace.c new file +63 -0
new file mode 100644
index 0000000..2b2824c
@@ -0,0 +1,105 @@
+#include <linux/export.h>
+#include <linux/dmi.h>
+#include "debug_extlog.h"
+
+#define CREATE_TRACE_POINTS
+#include "extlog_trace.h"
+
+static char mem_location[LOC_LEN];
+static char dimm_location[LOC_LEN];
+
+static void mem_err_location(struct cper_sec_mem_err *mem)
+{
+	char *p;
+	u32 n = 0;
+
+	memset(mem_location, 0, LOC_LEN);
+	p = mem_location;
+	if (mem->validation_bits & CPER_MEM_VALID_NODE)
+		n += sprintf(p + n, " node: %d", mem->node);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_CARD)
+		n += sprintf(p + n, " card: %d", mem->card);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
+		n += sprintf(p + n, " module: %d", mem->module);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
+		n += sprintf(p + n, " rank: %d", mem->rank);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_BANK)
+		n += sprintf(p + n, " bank: %d", mem->bank);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
+		n += sprintf(p + n, " device: %d", mem->device);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_ROW)
+		n += sprintf(p + n, " row: %d", mem->row);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
+		n += sprintf(p + n, " column: %d", mem->column);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
+		n += sprintf(p + n, " bit_position: %d", mem->bit_pos);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
+		n += sprintf(p + n, " requestor_id: 0x%016llx",
+				mem->requestor_id);
+	if (n >= LOC_LEN)
+		goto end;
+	if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
+		n += sprintf(p + n, " responder_id: 0x%016llx",
+				mem->responder_id);
+	if (n >= LOC_LEN)
+		goto end;

drivers/acpi/extlog_trace.c line 73

Quoted 10 lines
drivers/acpi/extlog_trace.c new file +10 -0
+	if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
+		n += sprintf(p + n, " target_id: 0x%016llx", mem->target_id);
+end:
+	return;
+}
+
+static void dimm_err_location(struct cper_sec_mem_err *mem)
+{
+	memset(dimm_location, 0, LOC_LEN);
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {

By reversing this test you can save yourself an indentation level and a superfluous memset:

	if (!(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE))
		return;

	memset(dimm_location, 0, LOC_LEN);
	dmi_memdev_name...
	...
Quoted 13 lines
drivers/acpi/extlog_trace.c new file +13 -0
+		const char *bank = NULL, *device = NULL;
+		dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
+		if (bank != NULL && device != NULL)
+			snprintf(dimm_location, LOC_LEN - 1,
+				"%s %s", bank, device);
+		else
+			snprintf(dimm_location, LOC_LEN - 1,
+				"DMI handle: 0x%.4x", mem->mem_dev_handle);
+	}
+}
+
+void trace_mem_error(const uuid_le *fru_id, char *fru_text,
+		u64 err_count, u32 severity, struct cper_sec_mem_err *mem)

drivers/acpi/extlog_trace.c line 96

Quoted 10 lines
drivers/acpi/extlog_trace.c new file +10 -0
+{
+	u32 etype = ~0U;
+	u64 phy_addr = 0;
+
+	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE)
+		etype = mem->error_type;
+	if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
+		phy_addr = mem->physical_addr;
+		if (mem->validation_bits &
+				CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK)

This mask could use some slimming:

CPER_MEM_VALID_PA_MASK or CPER_MEM_VALID_PHYS_ADDR_MASK or so so that it fits in 80 cols.

drivers/acpi/extlog_trace.c line 103

Quoted 7 lines
drivers/acpi/extlog_trace.c new file +7 -0
+			phy_addr &= mem->physical_addr_mask;
+	}
+	mem_err_location(mem);
+	dimm_err_location(mem);
+
+	trace_extlog_mem_event(etype, dimm_location, fru_id, fru_text,
+			err_count, severity, phy_addr, mem_location);

arg alignment

Quoted 8 lines
drivers/acpi/extlog_trace.c new file +2 -0
+}
+EXPORT_SYMBOL_GPL(trace_mem_error);
drivers/acpi/extlog_trace.h new file +0 -0
new file mode 100644
index 0000000..21f0887

drivers/acpi/extlog_trace.h line 8

Quoted 8 lines
drivers/acpi/extlog_trace.h new file +8 -0
@@ -0,0 +1,77 @@
+#if !defined(_TRACE_EXTLOG_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EXTLOG_H
+
+#include <linux/tracepoint.h>
+#include <linux/cper.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM extlog

Shouldn't that be TRACE_SYSTEM ras

...

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#53 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 8 lines · Borislav Petkov

Date: Fri, 11 Oct 2013 18:14:36 +0200
From: Borislav Petkov <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver
User-Agent: Mutt/1.5.21 (2010-09-15)

...

Quoted 8 lines

drivers/acpi/extlog_trace.c line 73

Quoted 4 lines
drivers/acpi/extlog_trace.c new file +4 -0
+static void dimm_err_location(struct cper_sec_mem_err *mem)
+{
+	memset(dimm_location, 0, LOC_LEN);
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {

By reversing this test you can save yourself an indentation level and a superfluous memset:

Quoted 8 lines
	if (!(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE))
		return;

	memset(dimm_location, 0, LOC_LEN);
	dmi_memdev_name...
	...

memset should be called before return, otherwise the values from last time will happen again in this time.

#54 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

In reply to Chen, Gong
Quoted 5 lines · Chen Gong

Use trace interface to elaborate all H/W error related information.

---

<snip>

drivers/acpi/extlog_trace.h line 31

Quoted 9 lines
drivers/acpi/extlog_trace.h new file +9 -0
+TRACE_EVENT(extlog_mem_event,
+	TP_PROTO(u32 etype,
+		char *dimm_loc,
+		const uuid_le *fru_id,
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

[Adding Mauro...]

This looks very similar to the trace event I wrote a while back, which was similar to the one provided by ghes_edac:
http://thread.gmane.org/gmane.linux.kernel.pci/24616

Seems to me this has the same issues we previously discussed w.r.t EDAC conflicts...

Regards,
Naveen

maintainer
#55 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 19 lines · Naveen N. Rao
Quoted 5 lines · Chen Gong

Use trace interface to elaborate all H/W error related information.

---

<snip>

drivers/acpi/extlog_trace.h line 31

Quoted 9 lines
drivers/acpi/extlog_trace.h new file +9 -0
+TRACE_EVENT(extlog_mem_event,
+	TP_PROTO(u32 etype,
+		char *dimm_loc,
+		const uuid_le *fru_id,
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

[Adding Mauro...]

Quoted 6 lines

This looks very similar to the trace event I wrote a while back, which was similar to the one provided by ghes_edac:
http://thread.gmane.org/gmane.linux.kernel.pci/24616

Seems to me this has the same issues we previously discussed w.r.t EDAC conflicts...

Right, I'm inclined to leave this trace_mc_event in ras_event.h to edac use alone because of all those layers which don't mean whit for GHES and eMCA error sources.

And maybe define a trace_mem_event which is shared by GHES and eMCA and not use the edac tracepoint there not load ghes_edac on such systems which have sufficient decoding capability in firmware.

Thoughts?

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#56 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 31 lines · Borislav Petkov
Quoted 19 lines · Naveen N. Rao
Quoted 5 lines · Chen Gong

Use trace interface to elaborate all H/W error related information.

---

<snip>

drivers/acpi/extlog_trace.h line 31

Quoted 9 lines
drivers/acpi/extlog_trace.h new file +9 -0
+TRACE_EVENT(extlog_mem_event,
+	TP_PROTO(u32 etype,
+		char *dimm_loc,
+		const uuid_le *fru_id,
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

[Adding Mauro...]

Quoted 6 lines

This looks very similar to the trace event I wrote a while back, which was similar to the one provided by ghes_edac:
http://thread.gmane.org/gmane.linux.kernel.pci/24616

Seems to me this has the same issues we previously discussed w.r.t EDAC conflicts...

Right, I'm inclined to leave this trace_mc_event in ras_event.h to edac use alone because of all those layers which don't mean whit for GHES and eMCA error sources.

Quoted 5 lines

And maybe define a trace_mem_event which is shared by GHES and eMCA and not use the edac tracepoint there not load ghes_edac on such systems which have sufficient decoding capability in firmware.

Thoughts?

I thought the primary problem was the conflict with edac core itself. So, if I'm not mistaken, we would have to prevent all edac drivers from loading.

Thanks,
Naveen

maintainer
#57 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 3 lines · Naveen N. Rao

I thought the primary problem was the conflict with edac core itself. So, if I'm not mistaken, we would have to prevent all edac drivers from loading.

That too - I don't see the need for them if the firmware does the decoding.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#58 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

In reply to Naveen N. Rao

I see a few problems on this patchset:

Em Tue, 15 Oct 2013 23:00:53 +0530
"Naveen N. Rao" <[email protected]> escreveu:

Quoted 6 lines · Borislav Petkov
Quoted 5 lines · Naveen N. Rao
Quoted 4 lines · Chen Gong
Quoted 3 lines

Use trace interface to elaborate all H/W error related information.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

---

<snip>

drivers/acpi/extlog_trace.h line 26

Quoted 4 lines
drivers/acpi/extlog_trace.h new file +4 -0
+TRACE_EVENT(extlog_mem_event,
+	TP_PROTO(u32 etype,
+		char *dimm_loc,
+		const uuid_le *fru_id,

Using a custom typedef here seems problematic, as that can make userspace interface more complicated.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

drivers/acpi/extlog_trace.h line 31

Quoted 5 lines
drivers/acpi/extlog_trace.h new file +5 -0
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

By looking on the rest of the changes, the mem_loc can now contain the right location of the memory error, including on what DIMM the error happened. It can also (optionally) contain the DIMM label.

Mangling those information on just one string field seems to be a very bad idea to me, as it prevents to write a generic logic, on userspace, that would apply a per-DIMM threshold policy.

Also, userspace needs to know what's the granularity for the error that an eMCA driver will give, in order to adjust its policies.

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

[Adding Mauro...]

This looks very similar to the trace event I wrote a while back, which was similar to the one provided by ghes_edac:
http://thread.gmane.org/gmane.linux.kernel.pci/24616

Seems to me this has the same issues we previously discussed w.r.t EDAC conflicts...

Agreed.

Quoted 4 lines
Quoted 4 lines

Right, I'm inclined to leave this trace_mc_event in ras_event.h to edac use alone because of all those layers which don't mean whit for GHES and eMCA error sources.

If you don't create the EDAC nodes, it means that userspace doesn't have any glue about what error information will be provided.

The right thing to do is, IMHO, add some additional EDAC sysfs nodes that shows what kind of error information will be provided by the device, e. g.:

- a complete hardware-based type of information directly obtained from the hardware;

- a very poor BIOS-based type of error information, where the provided data is not sufficient to pinpoint to the DIMM where the error actually occurred (what's currently there at ghes_edac);

- an eMCA-based type of error information, where the BIOS and ACPI will provide the complete error path, allowing userspace to properly parse the errors as if they come from the hardware-based approach.

In any case, this is provided by the EDAC core functions that describe the memory in details. So, IMHO, get rid of EDAC is a big mistake.

Quoted 9 lines
Quoted 5 lines

And maybe define a trace_mem_event which is shared by GHES and eMCA and not use the edac tracepoint there not load ghes_edac on such systems which have sufficient decoding capability in firmware.

Thoughts?

I thought the primary problem was the conflict with edac core itself. So, if I'm not mistaken, we would have to prevent all edac drivers from loading.

Yes, this is another aspect of this approach: whatever provided mechanism, the Kernel should assure that one error path won't conflict with the other ones. We know by experience that enabling both BIOS-based and hardware-based mechanisms cause race conditions, with affects both ways.
It is also nice to allow the user to choose his preferred mechanism, when more than one is properly supported on a given system.

Regards,
Mauro

(c/c Aristeu, as he might also being working with similar stuff)

maintainer
#59 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 2 lines · Mauro Carvalho Chehab

Using a custom typedef here seems problematic, as that can make userspace interface more complicated.

It is defined in a userspace header: include/uapi/linux/uuid.h

Quoted 9 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

drivers/acpi/extlog_trace.h line 31

Quoted 5 lines
drivers/acpi/extlog_trace.h new file +5 -0
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

By looking on the rest of the changes, the mem_loc can now contain the right location of the memory error, including on what DIMM the error happened. It can also (optionally) contain the DIMM label.

No, dimm_loc contains the label.

Quoted 2 lines

Also, userspace needs to know what's the granularity for the error that an eMCA driver will give, in order to adjust its policies.

u32 error_count

Quoted 2 lines

If you don't create the EDAC nodes, it means that userspace doesn't have any glue about what error information will be provided.

Of course it does - it is a tracepoint. There's no need for EDAC at all with eMCA present on the system.

Quoted 2 lines

In any case, this is provided by the EDAC core functions that describe the memory in details. So, IMHO, get rid of EDAC is a big mistake.

No one said we're getting rid of EDAC - we're basically disabling its services on machines with eMCA because we simply don't need it.

Quoted 2 lines

It is also nice to allow the user to choose his preferred mechanism, when more than one is properly supported on a given system.

We did this with firmware-first reporting so I don't see any need for user interaction. When you have eMCA on the system, you disable everything else reporting memory errors and go to sleep. So, similar to firmware first.

If eMCA turns out to have f*cked BIOS implementations - which I don't doubt - then we can add a chicken bit similar to "acpi=nocmcff"

It is that simple.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#60 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Em Wed, 16 Oct 2013 11:16:40 +0200
Borislav Petkov <[email protected]> escreveu:

Quoted 6 lines · Mauro Carvalho Chehab
Quoted 3 lines

drivers/acpi/extlog_trace.h line 26

Quoted 1 line
drivers/acpi/extlog_trace.h new file +1 -0
+		const uuid_le *fru_id,

Using a custom typedef here seems problematic, as that can make userspace interface more complicated.

It is defined in a userspace header: include/uapi/linux/uuid.h

Hmm... a non-packed structure is defined there. Ok, it has 16 bytes. I generally avoid using non-packed structs on uapi, as the compiler alignment rules can cause troubles if kernelspace is compiled with 64 bits, and userspace with 32 bits. In this specific case, it looks ok.

Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

drivers/acpi/extlog_trace.h line 31

Quoted 6 lines
drivers/acpi/extlog_trace.h new file +5 -0
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

By looking on the rest of the changes, the mem_loc can now contain the right location of the memory error, including on what DIMM the error happened. It can also (optionally) contain the DIMM label.

Quoted 1 line

No, dimm_loc contains the label.

Yeah, right. This is badly named, then.

Anyway, the dimm_loc is filled from DMI table by dmi_memdev_name(). Based on past experiences, this can be problematic, as manufactures tend to re-use the same DMI table on machines with different layouts.

Tony/Chen,

Are there any changes with regards to that, like some enforcement policy for BIOS manufacturers to make it right?

If not, then I think we still need EDAC's code to allow overriding those labels by the ones actually found on the system.

Quoted 4 lines
Quoted 2 lines

Also, userspace needs to know what's the granularity for the error that an eMCA driver will give, in order to adjust its policies.

u32 error_count

I'm talking about granularity, not error count. I mean: how the memory is organized, what happens with errors that could be affecting more than one DIMM (for example, on mirrored memories), etc.

Userspace can only do something useful if it knows what kind of support the hardware error mechanism is providing.

Quoted 5 lines
Quoted 2 lines

If you don't create the EDAC nodes, it means that userspace doesn't have any glue about what error information will be provided.

Of course it does - it is a tracepoint. There's no need for EDAC at all with eMCA present on the system.

Well, try to write some code on userspace to discover what's the error.

An error threshold mechanism on userspace will only work if userspace knows that the error belongs to the same DIMM.

If several different DIMMs are showing errors at the very same channel, and replacing those dimms don't happen, that likely means that the channel BUS is damaged.

What I'm saying is that hiding those information from userspace doesn't help at all to improve the quality of the error report mechanism.

I can't see any reason why hiding those information from userspace.

The tracepoint interface is not for that. Such data is provided via sysfs, and should be used for the application to properly tune their algorithms.

Quoted 5 lines
Quoted 2 lines

In any case, this is provided by the EDAC core functions that describe the memory in details. So, IMHO, get rid of EDAC is a big mistake.

No one said we're getting rid of EDAC - we're basically disabling its services on machines with eMCA because we simply don't need it.

We do need, if we want do do a good job decoding the errors.

Quoted 8 lines
Quoted 2 lines

It is also nice to allow the user to choose his preferred mechanism, when more than one is properly supported on a given system.

We did this with firmware-first reporting so I don't see any need for user interaction. When you have eMCA on the system, you disable everything else reporting memory errors and go to sleep. So, similar to firmware first.

Quoted 5 lines

If eMCA turns out to have f*cked BIOS implementations - which I don't doubt - then we can add a chicken bit similar to "acpi=nocmcff"

It is that simple.

Works for me.

Regards,
Mauro

maintainer
#61 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 4 lines · Mauro Carvalho Chehab

Well, try to write some code on userspace to discover what's the error.

An error threshold mechanism on userspace will only work if userspace knows that the error belongs to the same DIMM.

Just read the first mail again:

          <idle>-0     [000] d.h. 56068.488759: extlog_mem_event: 3 corrected errors:unknown on Memriser1 CHANNEL A DIMM 0(FRU: 00000000-0000

-0000-0000-000000000000 physical addr: 0x0000000851fe0000 node: 0 card: 0 module: 0 rank: 0 bank: 0 row: 28927 column: 1296)

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#62 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Em Wed, 16 Oct 2013 12:42:21 +0200
Borislav Petkov <[email protected]> escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 4 lines

Well, try to write some code on userspace to discover what's the error.

An error threshold mechanism on userspace will only work if userspace knows that the error belongs to the same DIMM.

Just read the first mail again:

          <idle>-0     [000] d.h. 56068.488759: extlog_mem_event: 3 corrected errors:unknown on Memriser1 CHANNEL A DIMM 0(FRU: 00000000-0000

-0000-0000-000000000000 physical addr: 0x0000000851fe0000 node: 0 card: 0 module: 0 rank: 0 bank: 0 row: 28927 column: 1296)

On that log, "physical addr: 0x0000000851fe0000 node: 0 card: 0 module: 0 rank: 0 bank: 0 row: 28927 column: 1296" is a string, instead of an hierarchical position, like what it is provided
on EDAC.

Worse than that, not all data may be available, as CPER allows to ommit some data.

Also, I suspect that, if an error happens to affect more than one DIMM (e. g. part of the location is not available for a given error), that the DIMM label will also not be properly shown.

Also, writing the userspace counterpart that would work properly is extremely hard, if the information about the memory layout is not known in advance. So, in practice, if the above memory error is provided, all userspace will likely be able to do is to store it and require someone to manually identify what's happening.

On the other hand, if node, channel and dimm number information is properly filled (like it happens on EDAC), usersapce can rely on those data, in order to apply per dimm, per channel and per node thresholds.

It may even use the physical address to identify if the problem is only on a certain region of a physical DIMM and poison that region, while it is not possible to replace the damaged component.

Regards,
Mauro

maintainer
#63 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 3 lines · Mauro Carvalho Chehab

On that log, "physical addr: 0x0000000851fe0000 node: 0 card: 0 module: 0 rank: 0 bank: 0 row: 28927 column: 1296" is a string, instead of an hierarchical position, like what it is provided
on EDAC.

So you can't split strings in userspace?

Quoted 3 lines

Also, I suspect that, if an error happens to affect more than one DIMM (e. g. part of the location is not available for a given error), that the DIMM label will also not be properly shown.

That's unrelated to these patches and needs to be reported properly by the firmware.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
reviewer
#64 lore raw

RE: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

In reply to Mauro Carvalho Chehab
Quoted 3 lines

Also, I suspect that, if an error happens to affect more than one DIMM (e. g. part of the location is not available for a given error), that the DIMM label will also not be properly shown.

There are a couple of cases here:

1) There are a number of DIMMs behind some flaky h/w that introduces errors that are apparently blamed onto each of those DIMMs.

All we can do here is statistical correlations ... each error is reported independently, it is up to some entity to notice the higher level topology connection. There is enough information in the UEFI error record to do that (assuming that BIOS filled out the necessary fields).

2) There is a single reported error that spans more than one DIMM.

This can happen with a UC error in a pair of lock-step DIMMs. Since the error is UC we know that two (or more) bits are bad. But we have no way to tell whether the bad bits came from the same DIMM, or one bit from each (because we don't know
which bits are bad - if we knew that, we could fix them :-) The eMCA case should
log two subsections in this case - one for each of the lockstep DIMMs involved. A user seeing this will should probably just replace both DIMMs to be safe. If they wanted to diagnose further they should swap DIMMs around so this pair are no longer lockstepped and see if they start seeing correctable errors from each of the split pair - or if the UC errors move with one or the other of the DIMMs

-Tony

#65 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Em Wed, 16 Oct 2013 20:47:05 +0000
"Luck, Tony" <[email protected]> escreveu:

Quoted 16 lines
Quoted 3 lines

Also, I suspect that, if an error happens to affect more than one DIMM (e. g. part of the location is not available for a given error), that the DIMM label will also not be properly shown.

There are a couple of cases here:

1) There are a number of DIMMs behind some flaky h/w that introduces errors that are apparently blamed onto each of those DIMMs.

All we can do here is statistical correlations ... each error is reported independently, it is up to some entity to notice the higher level topology connection. There is enough information in the UEFI error record to do that (assuming that BIOS filled out the necessary fields).

2) There is a single reported error that spans more than one DIMM.

Quoted 9 lines

This can happen with a UC error in a pair of lock-step DIMMs. Since the error is UC we know that two (or more) bits are bad. But we have no way to tell whether the bad bits came from the same DIMM, or one bit from each (because we don't know
which bits are bad - if we knew that, we could fix them :-) The eMCA case should
log two subsections in this case - one for each of the lockstep DIMMs involved. A user seeing this will should probably just replace both DIMMs to be safe. If they wanted to diagnose further they should swap DIMMs around so this pair are no longer lockstepped and see if they start seeing correctable errors from each of the split pair - or if the UC errors move with one or the other of the DIMMs

There's also a third case: mirrored memories.

As a matter of coherency with hw-based reports, for cases (2) and (3), the error tracing should be displaying both memories that are affected by a UC error (or a CE error on a mirrored address space).

Regards,
Mauro

reviewer
#66 lore raw

RE: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 1 line

There's also a third case: mirrored memories.

Mirrors are currently something of a mess - we don't get any useful notification when one breaks. We do need to fix this - and make sure reporting is properly integrated with everything else - I'm just not sure how to do this.

-Tony

reviewer
#67 lore raw

RE: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

In reply to Mauro Carvalho Chehab
Quoted 2 lines

Are there any changes with regards to that, like some enforcement policy for BIOS manufacturers to make it right?

I am using a cricket bat to beat BIOS teams that implement eMCA to make sure they get the labels in SMBIOS right. :-)

It's a non-trivial implementation effort to get all the decoding done for the eMCA log. It's typically a simple string change to fix the SMBIOS table ... there has been some resistance - but so far I have been victorious. Wish me luck as I'm about to engage with another team.

-Tony

#68 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Em Wed, 16 Oct 2013 20:35:32 +0000
"Luck, Tony" <[email protected]> escreveu:

Quoted 5 lines
Quoted 2 lines

Are there any changes with regards to that, like some enforcement policy for BIOS manufacturers to make it right?

I am using a cricket bat to beat BIOS teams that implement eMCA to make sure they get the labels in SMBIOS right. :-)

:)

Quoted 4 lines

It's a non-trivial implementation effort to get all the decoding done for the eMCA log. It's typically a simple string change to fix the SMBIOS table ... there has been some resistance - but so far I have been victorious. Wish me luck as I'm about to engage with another team.

Yes, the DMI changes are trivial. Let's hope that they'll do it right.

Yet, I think we should keep (at least for a while) a mechanism similar to what EDAC does, allowing those names to be overridden by loading a different table, where needed.

Regards,
Mauro

author
#69 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

In reply to Naveen N. Rao
Quoted 27 lines · Naveen N. Rao

Date: Tue, 15 Oct 2013 22:24:35 +0530
From: "Naveen N. Rao" <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected], [email protected]
Subject: Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 5 lines · Chen Gong

Use trace interface to elaborate all H/W error related information.

---

<snip>

drivers/acpi/extlog_trace.h line 31

Quoted 9 lines
drivers/acpi/extlog_trace.h new file +9 -0
+TRACE_EVENT(extlog_mem_event,
+	TP_PROTO(u32 etype,
+		char *dimm_loc,
+		const uuid_le *fru_id,
+		char *fru_text,
+		u64 error_count,
+		u32 severity,
+		u64 phy_addr,
+		char *mem_loc),

[Adding Mauro...]

Quoted 7 lines

This looks very similar to the trace event I wrote a while back, which was similar to the one provided by ghes_edac:
http://thread.gmane.org/gmane.linux.kernel.pci/24616

Seems to me this has the same issues we previously discussed w.r.t EDAC conflicts...

This thread is so long. I have to say I'm lost ... Anyway, it looks like there are many different opnions on this last patch. I will send the 2nd version for further discussion soon.

maintainer
#70 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Btw, I don't know what's the problem but when I hit reply-to-all to your emails, mutt drops your email address from the To: and makes the CC:
list become the To: list. Strange.

Quoted 2 lines · Chen Gong

This thread is so long. I have to say I'm lost ... Anyway, it looks like there are many different opnions on this last patch.

Why, I think it is fine.

The only compatibility issue I see is if we're going to share the tracepoint with Naveen's GHES reporting stuff we were discussing a couple of weeks ago. But AFAIR, we still needed EDAC assistance there while here there's no need for that.

Quoted 1 line

I will send the 2nd version for further discussion soon.

Yes please. :)

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#71 lore raw

Re: [PATCH 8/8] ACPI / trace: Add trace interface for eMCA driver

Quoted 3 lines · Borislav Petkov

Btw, I don't know what's the problem but when I hit reply-to-all to your emails, mutt drops your email address from the To: and makes the CC:
list become the To: list. Strange.

I'm seeing the same thing. Looking at the headers, Chen Gong's email includes a Mail-Follow-Up field which could be the problem.

- Naveen

#72 lore raw
In reply to Chen, Gong
Quoted 1 line · Gong

This patch series adds an enhanced MCA event logging driver provided by Intel.

[]

Quoted 12 lines

dmesg output:

[56005.785917] {3}Hardware error detected on CPU0
[56005.785959] {3}event severity: corrected
[56005.785975] {3}sub_event[0], severity: corrected
[56005.785977] {3}section_type: memory error
[56005.785981] {3}physical_address: 0x0000000851fe0000
[56005.786027] {3}DIMM location: Memriser1 CHANNEL A DIMM 0
[56005.786154] {4}Hardware error detected on CPU0
[56005.786159] {4}event severity: corrected
[56005.786162] {4}sub_event[0], severity: corrected
[56005.786166] {4}section_type: memory error

[]

Quoted 1 line

So welcome to add comments for what is needed or not.

Perhaps there can be a better standardized prefix other than {seq} like KBUILD_MODNAME or some other useful identifier like subsystem name.

maintainer
#73 lore raw
In reply to Chen, Gong
Quoted 6 lines · Gong
[56005.785917] {3}Hardware error detected on CPU0
[56005.785959] {3}event severity: corrected
[56005.785975] {3}sub_event[0], severity: corrected
[56005.785977] {3}section_type: memory error
[56005.785981] {3}physical_address: 0x0000000851fe0000
[56005.786027] {3}DIMM location: Memriser1 CHANNEL A DIMM 0

Very good guys, I've been waiting for years for this to be possible, good job! :-)

Btw, what's "Memriser1"?

Quoted 3 lines
[56005.786154] {4}Hardware error detected on CPU0
[56005.786159] {4}event severity: corrected
[56005.786162] {4}sub_event[0], severity: corrected

This sub_event[0] could use better decoding though.

Quoted 11 lines
[56005.786166] {4}section_type: memory error

trace output:

# tracer: nop
#
# entries-in-buffer/entries-written: 4/4 #P:120
#
# _-----=> irqs-off
# / _----=> need-resched

Quoted 8 lines
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
...
...
          <idle>-0     [000] d.h. 56068.488759: extlog_mem_event: 3 corrected errors:unknown

That "unknown" thing needs a " " in front of it and comes from cper_mem_err_type_str, AFAICT. I'm guessing the value is 0 and uninitialized or so?

Quoted 1 line

on Memriser1 CHANNEL A DIMM 0(FRU:

Also another " " missing here.

Quoted 9 lines

00000000-0000-0000-0000-000000000000 physical addr: 0x0000000851fe0000 node: 0 card: 0 module: 0 rank: 0 bank: 0 row: 28927 column: 1296)

          <idle>-0     [000] d.h. 56068.488834: extlog_mem_event: 4 corrected errors:unknown

...
...

dmesg output are shrank to only keep the most important data. The trace output will contain most of data. Not sure if all fields are meaningful to users. Some fields like FRU ID/FRU TEXT depends on BIOS manufactor. So welcome to add comments for what is needed or not.

Yeah, I guess we again depend on BIOS people to fill those in. I'd expect serious server manifacturers who care about RAS to do so...

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
reviewer
#74 lore raw
Quoted 5 lines
Quoted 2 lines
[56005.785981] {3}physical_address: 0x0000000851fe0000
[56005.786027] {3}DIMM location: Memriser1 CHANNEL A DIMM 0

Very good guys, I've been waiting for years for this to be possible, good job! :-)

It's such a simple goal - I can't believe it took this long to get here :-)

Quoted 1 line

Btw, what's "Memriser1"?

Each memory controller on this machine routes to a plug-in card that has a bunch of DIMMs on it. The silkscreen labels on the motherboard for these cards read "Memriser1" "Memriser2" etc.

-Tony

maintainer
#75 lore raw
Quoted 2 lines · Tony

It's such a simple goal - I can't believe it took this long to get here :-)

Right, I'd guess some standard's body needed to be persuaded :-)

Quoted 5 lines
Quoted 1 line

Btw, what's "Memriser1"?

Each memory controller on this machine routes to a plug-in card that has a bunch of DIMMs on it. The silkscreen labels on the motherboard for these cards read "Memriser1" "Memriser2" etc.

Silkscreen labels? Good!

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#76 lore raw
In reply to Borislav Petkov
Quoted 19 lines · Borislav Petkov

Date: Fri, 11 Oct 2013 10:04:27 +0200
From: Borislav Petkov <[email protected]>
To: "Chen, Gong" <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: Extended H/W error log driver
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 6 lines · Gong
[56005.785917] {3}Hardware error detected on CPU0
[56005.785959] {3}event severity: corrected
[56005.785975] {3}sub_event[0], severity: corrected
[56005.785977] {3}section_type: memory error
[56005.785981] {3}physical_address: 0x0000000851fe0000
[56005.786027] {3}DIMM location: Memriser1 CHANNEL A DIMM 0

Very good guys, I've been waiting for years for this to be possible, good job! :-)

Quoted 8 lines

Btw, what's "Memriser1"?

Quoted 3 lines
[56005.786154] {4}Hardware error detected on CPU0
[56005.786159] {4}event severity: corrected
[56005.786162] {4}sub_event[0], severity: corrected

This sub_event[0] could use better decoding though.

What's your suggestion?

maintainer
#77 lore raw
Quoted 8 lines · Chen Gong
Quoted 6 lines · Borislav Petkov
Quoted 3 lines
[56005.786154] {4}Hardware error detected on CPU0
[56005.786159] {4}event severity: corrected
[56005.786162] {4}sub_event[0], severity: corrected

This sub_event[0] could use better decoding though.

What's your suggestion?

Well, if this only enumerates the sections in CPER, then we can simply drop it.

Btw, I was wondering, why are we dropping cper_estatus_section_flag_strs? This is again the same issue with changing output which people might already rely upon.

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
author
#78 lore raw
Quoted 14 lines · Borislav Petkov

Date: Mon, 14 Oct 2013 12:55:33 +0200
From: Borislav Petkov <[email protected]>
To: Chen Gong <[email protected]>
Cc: [email protected], [email protected],
[email protected]
Subject: Re: Extended H/W error log driver
User-Agent: Mutt/1.5.21 (2010-09-15)

Quoted 5 lines · Chen Gong
Quoted 4 lines · Borislav Petkov
Quoted 3 lines
[56005.786154] {4}Hardware error detected on CPU0
[56005.786159] {4}event severity: corrected
[56005.786162] {4}sub_event[0], severity: corrected
Quoted 7 lines
Quoted 3 lines
Quoted 2 lines

This sub_event[0] could use better decoding though.

What's your suggestion?

Well, if this only enumerates the sections in CPER, then we can simply drop it.

Some errors have multiple sub sections like below:

[ 1442.070522] {2}[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 0
[ 1442.070528] {2}[Hardware Error]: event severity: corrected
[ 1442.070531] {2}[Hardware Error]: sub_event[0], severity: corrected
[ 1442.070534] {2}[Hardware Error]: section_type: memory error
[ 1442.070537] {2}[Hardware Error]: error_status: 0x0000000000000000
[ 1442.070539] {2}[Hardware Error]: sub_event[1], severity: corrected
[ 1442.070541] {2}[Hardware Error]: section_type: memory error
[ 1442.070543] {2}[Hardware Error]: error_status: 0x0000000000000000
Quoted 4 lines

Btw, I was wondering, why are we dropping cper_estatus_section_flag_strs? This is again the same issue with changing output which people might already rely upon.

This depends on how we shrink the output information. Your reply in another patch looks a good idea. Let me try it first.

Quoted 8 lines

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
maintainer
#79 lore raw
Quoted 10 lines · Chen Gong

Some errors have multiple sub sections like below:

[ 1442.070522] {2}[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 0
[ 1442.070528] {2}[Hardware Error]: event severity: corrected
[ 1442.070531] {2}[Hardware Error]: sub_event[0], severity: corrected
[ 1442.070534] {2}[Hardware Error]: section_type: memory error
[ 1442.070537] {2}[Hardware Error]: error_status: 0x0000000000000000
[ 1442.070539] {2}[Hardware Error]: sub_event[1], severity: corrected
[ 1442.070541] {2}[Hardware Error]: section_type: memory error
[ 1442.070543] {2}[Hardware Error]: error_status: 0x0000000000000000

Right, and what do those sub sections mean to the user? Did we have multiple errors?

It looks like this because we have memory errors section type but it is not very telling. How about:

[ 1442.070522] {2}[Hardware Error]: APEI GHES id 0: Hardware errors logged
[ 1442.070528] {2}[Hardware Error]: event severity: corrected
[ 1442.070534] {2}[Hardware Error]:  Error 0, type: corrected memory error.
[ 1442.070537] {2}[Hardware Error]:   error_status: 0x0000000000000000
[ 1442.070539] {2}[Hardware Error]:  Error 1, type: corrected memory error.
[ 1442.070543] {2}[Hardware Error]:   error_status: 0x0000000000000000

I think this is much more human readable and understandable :-)

We can even add a hint for the user like:

"Above errors have been corrected by the hardware and require no further action."

Btw, this is valid for both dmesg and trace event output.

Because from my experience so far people just scream: "Look, I just had an MCE" withot even reading what it says. And this just upsets support people for no valid reason at all.

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#80 lore raw
Quoted 9 lines · Borislav Petkov

We can even add a hint for the user like:

"Above errors have been corrected by the hardware and require no further action."

Btw, this is valid for both dmesg and trace event output.

Because from my experience so far people just scream: "Look, I just had an MCE" withot even reading what it says. And this just upsets support people for no valid reason at all.

"Like", "+1", "metoo" ... or whatever it is we do on LKML to indicate we approve.

-Tony

#81 lore raw
Quoted 5 lines · Tony Luck
Quoted 4 lines · Borislav Petkov

We can even add a hint for the user like:

"Above errors have been corrected by the hardware and require no further action."

Quoted 8 lines
Quoted 5 lines

Btw, this is valid for both dmesg and trace event output.

Because from my experience so far people just scream: "Look, I just had an MCE" withot even reading what it says. And this just upsets support people for no valid reason at all.

"Like", "+1", "metoo" ... or whatever it is we do on LKML to indicate we approve.

+2 ;)

While at it, I wonder if we're better off calling these "Hardware events" rather than "Hardware errors".

Thanks,
Naveen

maintainer
#82 lore raw
Quoted 1 line · Naveen N. Rao

+2 ;)

You're counting for 2 people, huh?

:-)

Quoted 2 lines

While at it, I wonder if we're better off calling these "Hardware events" rather than "Hardware errors".

Oh, please no. That's that euphemistic lying which serves no one. And here's what I mean by "euphemistic lying":

https://www.youtube.com/watch?v=vuEQixrBKCc

Let's call it what it really is but, at the same time, make sure it is understandable to users what action they need to undertake (or none) when they encounter it.

Thanks.

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--
#83 lore raw
Quoted 4 lines · Borislav Petkov
Quoted 1 line · Naveen N. Rao

+2 ;)

You're counting for 2 people, huh?

That's me raising both my hands :)

Quoted 6 lines

:-)

Quoted 2 lines

While at it, I wonder if we're better off calling these "Hardware events" rather than "Hardware errors".

Quoted 8 lines

Oh, please no. That's that euphemistic lying which serves no one. And here's what I mean by "euphemistic lying":

https://www.youtube.com/watch?v=vuEQixrBKCc

Let's call it what it really is but, at the same time, make sure it is understandable to users what action they need to undertake (or none) when they encounter it.

If you feel so strongly about it. "Corrected Error" is an oxymoron. It's really just the hardware notifying us.

Thanks,
Naveen

maintainer
#84 lore raw
Quoted 1 line · Naveen N. Rao

That's me raising both my hands :)

:-)

Quoted 2 lines

If you feel so strongly about it. "Corrected Error" is an oxymoron. It's really just the hardware notifying us.

Yeah, but we can't write

"We just corrected a single-bit flip in DIMM array <foo> - it was supposed to be X but now it is Y. Don't worry, this bit flip had no effect on current architectural machine state."

either.

I just don't want to call a "Hardware Error" a "Hardware Event". Besides, an IRQ is a hardware event too, for example. You can see where I'm getting with this...

Signature · 5 lines
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--