mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC][PATCH 0/3] Report APEI GHES error information via printk
@ 2010-11-24  1:16 Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 1/3] Add CPER PCIe error section structure and constants definition Huang Ying
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Huang Ying @ 2010-11-24  1:16 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-kernel, Andi Kleen, ying.huang, linux-acpi, Peter Zijlstra,
	Andrew Morton, Linus Torvalds, Ingo Molnar,
	Mauro Carvalho Chehab, Borislav Petkov, Thomas Gleixner

Although we have no consensus on whether we need a hardware error specific
reporting interface. We have the consensus that we need to report hardware
error information via printk. This patchset adds that to APEI GHES.

[RFC][PATCH 1/3] Add CPER PCIe error section structure and constants definition
[RFC][PATCH 2/3] ACPI, APEI, Add APEI generic error status print support
[RFC][PATCH 3/3] ACPI, APEI, report GHES error information via printk

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC][PATCH 1/3] Add CPER PCIe error section structure and constants definition
  2010-11-24  1:16 [RFC][PATCH 0/3] Report APEI GHES error information via printk Huang Ying
@ 2010-11-24  1:16 ` Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 2/3] ACPI, APEI, Add APEI generic error status print support Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 3/3] ACPI, APEI, report GHES error information via printk Huang Ying
  2 siblings, 0 replies; 4+ messages in thread
From: Huang Ying @ 2010-11-24  1:16 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-kernel, Andi Kleen, ying.huang, linux-acpi, Peter Zijlstra,
	Andrew Morton, Linus Torvalds, Ingo Molnar,
	Mauro Carvalho Chehab, Borislav Petkov, Thomas Gleixner

On some machine, PCIe error is reported via APEI (ACPI Platform Error
Interface).  The error data is passed from firmware to Linux via CPER
PCIe error section structure.

This patch adds CPER PCIe error section structure and constants
definition.

Signed-off-by: Huang Ying <ying.huang@intel.com>
---
 include/linux/cper.h |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -201,6 +201,67 @@
 	UUID_LE(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F,	\
 		0xDF, 0xAA, 0x84, 0xEC)
 
+#define CPER_PROC_VALID_TYPE			0x0001
+#define CPER_PROC_VALID_ISA			0x0002
+#define CPER_PROC_VALID_ERROR_TYPE		0x0004
+#define CPER_PROC_VALID_OPERATION		0x0008
+#define CPER_PROC_VALID_FLAGS			0x0010
+#define CPER_PROC_VALID_LEVEL			0x0020
+#define CPER_PROC_VALID_VERSION			0x0040
+#define CPER_PROC_VALID_BRAND_INFO		0x0080
+#define CPER_PROC_VALID_ID			0x0100
+#define CPER_PROC_VALID_TARGET_ADDRESS		0x0200
+#define CPER_PROC_VALID_REQUESTOR_ID		0x0400
+#define CPER_PROC_VALID_RESPONDER_ID		0x0800
+#define CPER_PROC_VALID_IP			0x1000
+
+#define CPER_MEM_VALID_ERROR_STATUS		0x0001
+#define CPER_MEM_VALID_PHYSICAL_ADDRESS		0x0002
+#define CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK	0x0004
+#define CPER_MEM_VALID_NODE			0x0008
+#define CPER_MEM_VALID_CARD			0x0010
+#define CPER_MEM_VALID_MODULE			0x0020
+#define CPER_MEM_VALID_BANK			0x0040
+#define CPER_MEM_VALID_DEVICE			0x0080
+#define CPER_MEM_VALID_ROW			0x0100
+#define CPER_MEM_VALID_COLUMN			0x0200
+#define CPER_MEM_VALID_BIT_POSITION		0x0400
+#define CPER_MEM_VALID_REQUESTOR_ID		0x0800
+#define CPER_MEM_VALID_RESPONDER_ID		0x1000
+#define CPER_MEM_VALID_TARGET_ID		0x2000
+#define CPER_MEM_VALID_ERROR_TYPE		0x4000
+
+#define CPER_PCIE_VALID_PORT_TYPE		0x0001
+#define CPER_PCIE_VALID_VERSION			0x0002
+#define CPER_PCIE_VALID_COMMAND_STATUS		0x0004
+#define CPER_PCIE_VALID_DEVICE_ID		0x0008
+#define CPER_PCIE_VALID_SERIAL_NUMBER		0x0010
+#define CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS	0x0020
+#define CPER_PCIE_VALID_CAPABILITY		0x0040
+#define CPER_PCIE_VALID_AER_INFO		0x0080
+
+#define CPER_PCIE_VERSION_MINOR			0
+#define CPER_PCIE_VERSION_MAJOR			1
+
+#define CPER_PCIE_COMMAND_REG			0
+#define CPER_PCIE_STATUS_REG			1
+
+#define CPER_PCIE_DEVID_VENDOR_ID		0
+#define CPER_PCIE_DEVID_DEVICE_ID		2
+#define CPER_PCIE_DEVID_CLASS_CODE		4
+#define CPER_PCIE_DEVID_FUNC			7
+#define CPER_PCIE_DEVID_DEV			8
+#define CPER_PCIE_DEVID_SEGMENT			9
+#define CPER_PCIE_DEVID_BUS_PRIMARY		11
+#define CPER_PCIE_DEVID_BUS_SECONDARY		12
+#define CPER_PCIE_DEVID_SLOT			13
+
+#define CPER_PCIE_SERIAL_NUMBER_LOW		0
+#define CPER_PCIE_SERIAL_NUMBER_HIGH		1
+
+#define CPER_PCIE_BRIDGE_SECONDARY_STATUS_REG	0
+#define CPER_PCIE_BRIDGE_CONTROL_REG		1
+
 /*
  * All tables and structs must be byte-packed to match CPER
  * specification, since the tables are provided by the system BIOS
@@ -306,6 +367,19 @@ struct cper_sec_mem_err {
 	__u8	error_type;
 };
 
+struct cper_sec_pcie {
+	__u64	validation_bits;
+	__u32	port_type;
+	__u8	version[4];
+	__u16	command_status[2];
+	__u32	reserved;
+	__u8	device_id[16];
+	__u32	serial_number[2];
+	__u16	bridge_control_status[2];
+	__u8	capability[60];
+	__u8	aer_info[96];
+};
+
 /* Reset to default packing */
 #pragma pack()
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC][PATCH 2/3] ACPI, APEI, Add APEI generic error status print support
  2010-11-24  1:16 [RFC][PATCH 0/3] Report APEI GHES error information via printk Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 1/3] Add CPER PCIe error section structure and constants definition Huang Ying
@ 2010-11-24  1:16 ` Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 3/3] ACPI, APEI, report GHES error information via printk Huang Ying
  2 siblings, 0 replies; 4+ messages in thread
From: Huang Ying @ 2010-11-24  1:16 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-kernel, Andi Kleen, ying.huang, linux-acpi, Peter Zijlstra,
	Andrew Morton, Linus Torvalds, Ingo Molnar,
	Mauro Carvalho Chehab, Borislav Petkov, Thomas Gleixner

printk is one of the methods to report hardware errors to user space.
Hardware error information reported by firmware to Linux kernel is in
the format of APEI generic error status (struct
acpi_hes_generic_status).  This patch adds print support for the
format, so that the corresponding hardware error information can be
reported to user space via printk.

PCIe AER information print is not implemented yet.  Will refactor the
original PCIe AER information printing code to avoid code duplicating.

Signed-off-by: Huang Ying <ying.huang@intel.com>
---
 drivers/acpi/apei/apei-internal.h |    2 
 drivers/acpi/apei/cper.c          |  288 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 290 insertions(+)

--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struc
 		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);
 #endif
--- a/drivers/acpi/apei/cper.c
+++ b/drivers/acpi/apei/cper.c
@@ -30,6 +30,9 @@
 #include <linux/cper.h>
 #include <linux/acpi.h>
 
+#define pr_pfx(pfx, fmt, ...)			\
+	printk("%s" fmt, pfx, ##__VA_ARGS__)
+
 /*
  * CPER record ID need to be unique even after reboot, because record
  * ID is used as index for ERST storage, while CPER records from
@@ -46,6 +49,291 @@ u64 cper_next_record_id(void)
 }
 EXPORT_SYMBOL_GPL(cper_next_record_id);
 
+static const char *cper_severity_strs[] = {
+	[CPER_SEV_RECOVERABLE]		= "recoverable",
+	[CPER_SEV_FATAL]		=  "fatal",
+	[CPER_SEV_CORRECTED]		= "corrected",
+	[CPER_SEV_INFORMATIONAL]	= "info",
+};
+
+static void cper_print_bits(const char *pfx, unsigned int bits,
+			    const char *strs[], unsigned int strs_size)
+{
+	int i, len = 0;
+	const char *str;
+
+	for (i = 0; i < strs_size; i++) {
+		if (!(bits & (1U << i)))
+			continue;
+		str = strs[i];
+		if (len && len + strlen(str) + 2 > 80) {
+			printk("\n");
+			len = 0;
+		}
+		if (!len)
+			len = pr_pfx(pfx, "%s", str);
+		else
+			len += printk(", %s", str);
+	}
+	if (len)
+		printk("\n");
+}
+
+static const char *cper_proc_type_strs[] = {
+	"IA32/X64",
+	"IA64",
+};
+
+static const char *cper_proc_isa_strs[] = {
+	"IA32",
+	"IA64",
+	"X64",
+};
+
+static const char *cper_proc_error_type_strs[] = {
+	"cache error",
+	"TLB error",
+	"bus error",
+	"micro-architectural error",
+};
+
+static const char *cper_proc_op_strs[] = {
+	"Unknown or generic",
+	"data read",
+	"data write",
+	"instruction execution",
+};
+
+static const char *cper_proc_flag_strs[] = {
+	"restartable",
+	"precise IP",
+	"overflow",
+	"corrected",
+};
+
+static void cper_print_proc_generic(const char *pfx,
+				    const struct cper_sec_proc_generic *proc)
+{
+	if (proc->validation_bits & CPER_PROC_VALID_TYPE)
+		pr_pfx(pfx, "processor_type: %d, %s\n", proc->proc_type,
+			proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ?
+			cper_proc_type_strs[proc->proc_type] : "unknown");
+	if (proc->validation_bits & CPER_PROC_VALID_ISA)
+		pr_pfx(pfx, "processor_isa: %d, %s\n", proc->proc_isa,
+			proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ?
+			cper_proc_isa_strs[proc->proc_isa] : "unknown");
+	if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
+		pr_pfx(pfx, "error_type: 0x%02x\n", proc->proc_error_type);
+		cper_print_bits(pfx, proc->proc_error_type,
+				cper_proc_error_type_strs,
+				ARRAY_SIZE(cper_proc_error_type_strs));
+	}
+	if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
+		pr_pfx(pfx, "operation: %d, %s\n", proc->operation,
+		       proc->operation < ARRAY_SIZE(cper_proc_op_strs) ?
+		       cper_proc_op_strs[proc->operation] : "unknown");
+	if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
+		pr_pfx(pfx, "flags: 0x%02x\n", proc->flags);
+		cper_print_bits(pfx, proc->flags, cper_proc_flag_strs,
+				ARRAY_SIZE(cper_proc_flag_strs));
+	}
+	if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
+		pr_pfx(pfx, "level: %d\n", proc->level);
+	if (proc->validation_bits & CPER_PROC_VALID_VERSION)
+		pr_pfx(pfx, "version_info: 0x%016llx\n", proc->cpu_version);
+	if (proc->validation_bits & CPER_PROC_VALID_ID)
+		pr_pfx(pfx, "processor_id: 0x%016llx\n", proc->proc_id);
+	if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS)
+		pr_pfx(pfx, "target_address: 0x%016llx\n",
+		       proc->target_addr);
+	if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID)
+		pr_pfx(pfx, "requestor_id: 0x%016llx\n", proc->requestor_id);
+	if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID)
+		pr_pfx(pfx, "responder_id: 0x%016llx\n", proc->responder_id);
+	if (proc->validation_bits & CPER_PROC_VALID_IP)
+		pr_pfx(pfx, "IP: 0x%016llx\n", proc->ip);
+}
+
+static const char *cper_mem_err_type_strs[] = {
+	"Unknown",
+	"No error",
+	"Single-bit ECC",
+	"Multi-bit ECC",
+	"Single-symbol chipkill ECC",
+	"Multi-symbol chipkill ECC",
+	"Master abort",
+	"Target abort",
+	"Parity error",
+	"Watchdog timeout",
+	"Invalid address",
+	"Mirror Broken",
+	"Memory sparing",
+	"Scrub corrected error",
+	"Scrub uncorrected error",
+};
+
+static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
+{
+	if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
+		pr_pfx(pfx, "error_status: 0x%016llx\n", mem->error_status);
+	if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)
+		pr_pfx(pfx, "physical_address: 0x%016llx\n",
+		       mem->physical_addr);
+	if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK)
+		pr_pfx(pfx, "physical_address_mask: 0x%016llx\n",
+		       mem->physical_addr_mask);
+	if (mem->validation_bits & CPER_MEM_VALID_NODE)
+		pr_pfx(pfx, "node: %d\n", mem->node);
+	if (mem->validation_bits & CPER_MEM_VALID_CARD)
+		pr_pfx(pfx, "card: %d\n", mem->card);
+	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
+		pr_pfx(pfx, "module: %d\n", mem->module);
+	if (mem->validation_bits & CPER_MEM_VALID_BANK)
+		pr_pfx(pfx, "bank: %d\n", mem->bank);
+	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
+		pr_pfx(pfx, "device: %d\n", mem->device);
+	if (mem->validation_bits & CPER_MEM_VALID_ROW)
+		pr_pfx(pfx, "row: %d\n", mem->row);
+	if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
+		pr_pfx(pfx, "column: %d\n", mem->column);
+	if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
+		pr_pfx(pfx, "bit_position: %d\n", mem->bit_pos);
+	if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
+		pr_pfx(pfx, "requestor_id: 0x%016llx\n", mem->requestor_id);
+	if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
+		pr_pfx(pfx, "responder_id: 0x%016llx\n", mem->responder_id);
+	if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
+		pr_pfx(pfx, "target_id: 0x%016llx\n", mem->target_id);
+	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
+		u8 etype = mem->error_type;
+		pr_pfx(pfx, "error_type: %d, %s\n", etype,
+		       etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
+		       cper_mem_err_type_strs[etype] : "unknown");
+	}
+}
+
+static const char *cper_pcie_port_type_strs[] = {
+	"PCIe end point",
+	"legacy PCI end point",
+	"unknown",
+	"unknown",
+	"root port",
+	"upstream switch port",
+	"downstream switch port",
+	"PCIe to PCI/PCI-X bridge",
+	"PCI/PCI-X to PCIe bridge",
+	"root complex integrated endpoint device",
+	"root complex event collector",
+};
+
+static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie)
+{
+	if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
+		pr_pfx(pfx, "port_type: %d, %s\n", pcie->port_type,
+		       pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
+		       cper_pcie_port_type_strs[pcie->port_type] : "unknown");
+	if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
+		pr_pfx(pfx, "version: %d.%d\n",
+		       pcie->version[CPER_PCIE_VERSION_MAJOR],
+		       pcie->version[CPER_PCIE_VERSION_MINOR]);
+	if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS)
+		pr_pfx(pfx, "command: 0x%04x, status: 0x%04x\n",
+		       pcie->command_status[CPER_PCIE_COMMAND_REG],
+		       pcie->command_status[CPER_PCIE_STATUS_REG]);
+	if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) {
+		const __u8 *p;
+		pr_pfx(pfx, "device_id: %04x:%02x:%02x.%x\n",
+		       pcie->device_id[CPER_PCIE_DEVID_SEGMENT],
+		       pcie->device_id[CPER_PCIE_DEVID_BUS_PRIMARY],
+		       pcie->device_id[CPER_PCIE_DEVID_DEV],
+		       pcie->device_id[CPER_PCIE_DEVID_FUNC]);
+		pr_pfx(pfx, "slot: %d\n",
+		       pcie->device_id[CPER_PCIE_DEVID_SLOT]);
+		pr_pfx(pfx, "secondary_bus: 0x%02x\n",
+		       pcie->device_id[CPER_PCIE_DEVID_BUS_SECONDARY]);
+		pr_pfx(pfx, "vendor_id: 0x%04x, device_id: 0x%04x\n",
+		       *(__u16 *)&pcie->device_id[CPER_PCIE_DEVID_VENDOR_ID],
+		       *(__u16 *)&pcie->device_id[CPER_PCIE_DEVID_DEVICE_ID]);
+		p = pcie->device_id + CPER_PCIE_DEVID_CLASS_CODE;
+		pr_pfx(pfx, "class_code: %02x%02x%02x\n", p[0], p[1], p[2]);
+	}
+	if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
+		pr_pfx(pfx, "serial number: 0x%04x, 0x%04x\n",
+		       pcie->serial_number[CPER_PCIE_SERIAL_NUMBER_LOW],
+		       pcie->serial_number[CPER_PCIE_SERIAL_NUMBER_HIGH]);
+	if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS)
+		pr_pfx(pfx,
+	"bridge: secondary_status: 0x%04x, control: 0x%04x\n",
+	pcie->bridge_control_status[CPER_PCIE_BRIDGE_SECONDARY_STATUS_REG],
+	pcie->bridge_control_status[CPER_PCIE_BRIDGE_CONTROL_REG]);
+}
+
+static const char *apei_estatus_section_flag_strs[] = {
+	"primary",
+	"containment_warning",
+	"reset",
+	"threshold_exceeded",
+	"resource_not_accessible",
+	"latent_error",
+};
+
+static void apei_estatus_print_section(
+	const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
+{
+	uuid_le *sec_type = (uuid_le *)gdata->section_type;
+	__u16 severity;
+
+	severity = gdata->error_severity;
+	pr_pfx(pfx, "section: %d, severity: %d, %s\n", sec_no, severity,
+	       severity < ARRAY_SIZE(cper_severity_strs) ?
+	       cper_severity_strs[severity] : "unknown");
+	pr_pfx(pfx, "flags: 0x%02x\n", gdata->flags);
+	cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs,
+			ARRAY_SIZE(apei_estatus_section_flag_strs));
+	if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+		pr_pfx(pfx, "fru_id: %pUl\n", (uuid_le *)gdata->fru_id);
+	if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+		pr_pfx(pfx, "fru_text: %20s\n", gdata->fru_text);
+
+	if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
+		struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
+		pr_pfx(pfx, "section_type: general processor error\n");
+		cper_print_proc_generic(pfx, proc_err);
+	} else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
+		struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
+		pr_pfx(pfx, "section_type: memory error\n");
+		cper_print_mem(pfx, mem_err);
+	} else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
+		struct cper_sec_pcie *pcie = (void *)(gdata + 1);
+		pr_pfx(pfx, "section_type: PCIe error\n");
+		cper_print_pcie(pfx, pcie);
+	} else
+		pr_pfx(pfx, "Unknown section type: %pUl\n", sec_type);
+}
+
+void apei_estatus_print(const char *pfx,
+			const struct acpi_hest_generic_status *estatus)
+{
+	struct acpi_hest_generic_data *gdata;
+	unsigned int data_len, gedata_len;
+	int sec_no = 0;
+	__u16 severity;
+
+	severity = estatus->error_severity;
+	pr_pfx(pfx, "severity: %d, %s\n", severity,
+	       severity < ARRAY_SIZE(cper_severity_strs) ?
+	       cper_severity_strs[severity] : "unknown");
+	data_len = estatus->data_length;
+	gdata = (struct acpi_hest_generic_data *)(estatus + 1);
+	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);
+		sec_no++;
+	}
+}
+EXPORT_SYMBOL_GPL(apei_estatus_print);
+
 int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
 {
 	if (estatus->data_length &&

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC][PATCH 3/3] ACPI, APEI, report GHES error information via printk
  2010-11-24  1:16 [RFC][PATCH 0/3] Report APEI GHES error information via printk Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 1/3] Add CPER PCIe error section structure and constants definition Huang Ying
  2010-11-24  1:16 ` [RFC][PATCH 2/3] ACPI, APEI, Add APEI generic error status print support Huang Ying
@ 2010-11-24  1:16 ` Huang Ying
  2 siblings, 0 replies; 4+ messages in thread
From: Huang Ying @ 2010-11-24  1:16 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-kernel, Andi Kleen, ying.huang, linux-acpi, Peter Zijlstra,
	Andrew Morton, Linus Torvalds, Ingo Molnar,
	Mauro Carvalho Chehab, Borislav Petkov, Thomas Gleixner

printk is one of the methods to report hardware errors to user space.
This patch implements hardware error reporting for GHES via printk.

Signed-off-by: Huang Ying <ying.huang@intel.com>
---
 drivers/acpi/apei/ghes.c |   21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -255,11 +255,23 @@ static void ghes_do_proc(struct ghes *gh
 		}
 #endif
 	}
+}
 
-	if (!processed && printk_ratelimit())
-		pr_warning(GHES_PFX
-		"Unknown error record from generic hardware error source: %d\n",
-			   ghes->generic->header.source_id);
+static void ghes_print_estatus(const char *pfx, struct ghes *ghes)
+{
+	if (pfx == NULL) {
+		if (ghes_severity(ghes->estatus->error_severity) <=
+		    GHES_SEV_CORRECTED)
+			pfx = KERN_WARNING HW_ERR;
+		else
+			pfx = KERN_ERR HW_ERR;
+	}
+	if (printk_ratelimit()) {
+		printk(
+		"%sHardware error from Generic Hardware Error Source: %d\n",
+		pfx, ghes->generic->header.source_id);
+		apei_estatus_print(pfx, ghes->estatus);
+	}
 }
 
 static int ghes_proc(struct ghes *ghes)
@@ -269,6 +281,7 @@ static int ghes_proc(struct ghes *ghes)
 	rc = ghes_read_estatus(ghes, 0);
 	if (rc)
 		goto out;
+	ghes_print_estatus(NULL, ghes);
 	ghes_do_proc(ghes);
 
 out:

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-11-24  1:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-24  1:16 [RFC][PATCH 0/3] Report APEI GHES error information via printk Huang Ying
2010-11-24  1:16 ` [RFC][PATCH 1/3] Add CPER PCIe error section structure and constants definition Huang Ying
2010-11-24  1:16 ` [RFC][PATCH 2/3] ACPI, APEI, Add APEI generic error status print support Huang Ying
2010-11-24  1:16 ` [RFC][PATCH 3/3] ACPI, APEI, report GHES error information via printk Huang Ying

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®