Commit f04c62a7036a4b8490b224a9ad1be4378a3acf4d

Authored by Mauro Carvalho Chehab
1 parent 77c5f5d2f2

ghes_edac: add support for reporting errors via EDAC

Now that the EDAC core is capable of just forward the errors via
the userspace API, add a report mechanism for the GHES errors.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 1 changed file with 54 additions and 2 deletions Side-by-side Diff

drivers/edac/ghes_edac.c
... ... @@ -27,8 +27,60 @@
27 27 static int ghes_edac_mc_num;
28 28  
29 29 void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
30   - struct cper_sec_mem_err *mem_err)
  30 + struct cper_sec_mem_err *mem_err)
31 31 {
  32 + enum hw_event_mc_err_type type;
  33 + struct edac_raw_error_desc *e;
  34 + struct mem_ctl_info *mci;
  35 + struct ghes_edac_pvt *pvt = NULL;
  36 +
  37 + list_for_each_entry(pvt, &ghes_reglist, list) {
  38 + if (ghes == pvt->ghes)
  39 + break;
  40 + }
  41 + if (!pvt) {
  42 + pr_err("Internal error: Can't find EDAC structure\n");
  43 + return;
  44 + }
  45 + mci = pvt->mci;
  46 + e = &mci->error_desc;
  47 +
  48 + /* Cleans the error report buffer */
  49 + memset(e, 0, sizeof (*e));
  50 + e->error_count = 1;
  51 + e->msg = "APEI";
  52 + strcpy(e->label, "unknown");
  53 + e->other_detail = "";
  54 +
  55 + if (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
  56 + e->page_frame_number = mem_err->physical_addr >> PAGE_SHIFT;
  57 + e->offset_in_page = mem_err->physical_addr & ~PAGE_MASK;
  58 + e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK);
  59 + }
  60 +
  61 + switch (sev) {
  62 + case GHES_SEV_CORRECTED:
  63 + type = HW_EVENT_ERR_CORRECTED;
  64 + break;
  65 + case GHES_SEV_RECOVERABLE:
  66 + type = HW_EVENT_ERR_UNCORRECTED;
  67 + break;
  68 + case GHES_SEV_PANIC:
  69 + type = HW_EVENT_ERR_FATAL;
  70 + break;
  71 + default:
  72 + case GHES_SEV_NO:
  73 + type = HW_EVENT_ERR_INFO;
  74 + }
  75 +
  76 + sprintf(e->location,
  77 + "node:%d card:%d module:%d bank:%d device:%d row: %d column:%d bit_pos:%d",
  78 + mem_err->node, mem_err->card, mem_err->module,
  79 + mem_err->bank, mem_err->device, mem_err->row, mem_err->column,
  80 + mem_err->bit_pos);
  81 + edac_dbg(3, "error at location %s\n", e->location);
  82 +
  83 + edac_raw_mc_handle_error(type, mci, e);
32 84 }
33 85 EXPORT_SYMBOL_GPL(ghes_edac_report_mem_error);
34 86  
... ... @@ -60,7 +112,7 @@
60 112  
61 113 pvt = mci->pvt_info;
62 114 memset(pvt, 0, sizeof(*pvt));
63   - list_add_tail(&pvt->list, &ghes_reglist);
  115 + list_add_tail(&pvt->list, &ghes_reglist);
64 116 pvt->ghes = ghes;
65 117 pvt->mci = mci;
66 118 mci->pdev = dev;