ACPI, APEI, CPER: Add UEFI 2.4 support for memory error
authorChen, Gong <gong.chen@linux.intel.com>
Fri, 18 Oct 2013 21:30:13 +0000 (14:30 -0700)
committerTony Luck <tony.luck@intel.com>
Wed, 23 Oct 2013 17:10:20 +0000 (10:10 -0700)
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 to an actual DIMM location.

Original-author: Tony Luck <tony.luck@intel.com>
Signed-off-by: Chen, Gong <gong.chen@linux.intel.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
arch/x86/kernel/cpu/mcheck/mce-apei.c
drivers/acpi/apei/cper.c
drivers/acpi/apei/ghes.c
drivers/edac/ghes_edac.c
include/linux/cper.h

index cd8b166a1735326d614d92ef6b44292149c8c5cd..de8b60a53f695f486664d0dac307279d31207be8 100644 (file)
@@ -42,8 +42,7 @@ void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err)
        struct mce m;
 
        /* Only corrected MC is reported */
-       if (!corrected || !(mem_err->validation_bits &
-                               CPER_MEM_VALID_PHYSICAL_ADDRESS))
+       if (!corrected || !(mem_err->validation_bits & CPER_MEM_VALID_PA))
                return;
 
        mce_setup(&m);
index eb5f6d6d7dbcf6986962c742a1f8e5900dbb9bd1..946ef520186f39adca9c6d32a5a392431ae9e479 100644 (file)
@@ -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,16 +191,17 @@ 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)
 {
        if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
                printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
-       if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)
+       if (mem->validation_bits & CPER_MEM_VALID_PA)
                printk("%s""physical_address: 0x%016llx\n",
                       pfx, mem->physical_addr);
-       if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK)
+       if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
                printk("%s""physical_address_mask: 0x%016llx\n",
                       pfx, mem->physical_addr_mask);
        if (mem->validation_bits & CPER_MEM_VALID_NODE)
index 0db6e4ff650133f5a7c088b182f538e4078d5f0b..a30bc313787be65523797da950f3982e13844c35 100644 (file)
@@ -419,7 +419,7 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
 
        if (sec_sev == GHES_SEV_CORRECTED &&
            (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) &&
-           (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)) {
+           (mem_err->validation_bits & CPER_MEM_VALID_PA)) {
                pfn = mem_err->physical_addr >> PAGE_SHIFT;
                if (pfn_valid(pfn))
                        memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE);
@@ -430,7 +430,7 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
        }
        if (sev == GHES_SEV_RECOVERABLE &&
            sec_sev == GHES_SEV_RECOVERABLE &&
-           mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
+           mem_err->validation_bits & CPER_MEM_VALID_PA) {
                pfn = mem_err->physical_addr >> PAGE_SHIFT;
                memory_failure_queue(pfn, 0, 0);
        }
index bb534670ec02385714bce04c769b2d0ded4988d6..0ad797b9db65d3048152d6df08a99d0e0eb77432 100644 (file)
@@ -297,15 +297,14 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
        }
 
        /* Error address */
-       if (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
+       if (mem_err->validation_bits & CPER_MEM_VALID_PA) {
                e->page_frame_number = mem_err->physical_addr >> PAGE_SHIFT;
                e->offset_in_page = mem_err->physical_addr & ~PAGE_MASK;
        }
 
        /* Error grain */
-       if (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK) {
+       if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
                e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK);
-       }
 
        /* Memory error location, mapped on e->location */
        p = e->location;
index 09ebe2113641585863cb488c0971ff010ef9d0ea..2fc0ec3d89cc385ab9e68ac9a26acd5583f1e82d 100644 (file)
@@ -218,8 +218,8 @@ enum {
 #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_PA                      0x0002
+#define CPER_MEM_VALID_PA_MASK                 0x0004
 #define CPER_MEM_VALID_NODE                    0x0008
 #define CPER_MEM_VALID_CARD                    0x0010
 #define CPER_MEM_VALID_MODULE                  0x0020
@@ -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;       /* card handle in UEFI 2.4 */
+       __u16   mem_dev_handle;         /* module handle in UEFI 2.4 */
 };
 
 struct cper_sec_pcie {