Skip to content

Commit

Permalink
ghes_edac: add support for reporting errors via EDAC
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mauro Carvalho Chehab committed Feb 25, 2013
1 parent 77c5f5d commit f04c62a
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions drivers/edac/ghes_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,60 @@ static DEFINE_MUTEX(ghes_edac_lock);
static int ghes_edac_mc_num;

void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
struct cper_sec_mem_err *mem_err)
struct cper_sec_mem_err *mem_err)
{
enum hw_event_mc_err_type type;
struct edac_raw_error_desc *e;
struct mem_ctl_info *mci;
struct ghes_edac_pvt *pvt = NULL;

list_for_each_entry(pvt, &ghes_reglist, list) {
if (ghes == pvt->ghes)
break;
}
if (!pvt) {
pr_err("Internal error: Can't find EDAC structure\n");
return;
}
mci = pvt->mci;
e = &mci->error_desc;

/* Cleans the error report buffer */
memset(e, 0, sizeof (*e));
e->error_count = 1;
e->msg = "APEI";
strcpy(e->label, "unknown");
e->other_detail = "";

if (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
e->page_frame_number = mem_err->physical_addr >> PAGE_SHIFT;
e->offset_in_page = mem_err->physical_addr & ~PAGE_MASK;
e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK);
}

switch (sev) {
case GHES_SEV_CORRECTED:
type = HW_EVENT_ERR_CORRECTED;
break;
case GHES_SEV_RECOVERABLE:
type = HW_EVENT_ERR_UNCORRECTED;
break;
case GHES_SEV_PANIC:
type = HW_EVENT_ERR_FATAL;
break;
default:
case GHES_SEV_NO:
type = HW_EVENT_ERR_INFO;
}

sprintf(e->location,
"node:%d card:%d module:%d bank:%d device:%d row: %d column:%d bit_pos:%d",
mem_err->node, mem_err->card, mem_err->module,
mem_err->bank, mem_err->device, mem_err->row, mem_err->column,
mem_err->bit_pos);
edac_dbg(3, "error at location %s\n", e->location);

edac_raw_mc_handle_error(type, mci, e);
}
EXPORT_SYMBOL_GPL(ghes_edac_report_mem_error);

Expand Down Expand Up @@ -60,7 +112,7 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)

pvt = mci->pvt_info;
memset(pvt, 0, sizeof(*pvt));
list_add_tail(&pvt->list, &ghes_reglist);
list_add_tail(&pvt->list, &ghes_reglist);
pvt->ghes = ghes;
pvt->mci = mci;
mci->pdev = dev;
Expand Down

0 comments on commit f04c62a

Please sign in to comment.