diff --git a/SOURCES/0862a096c3a1d0f993703ab3299f1ddfadf53d7f.patch b/SOURCES/0862a096c3a1d0f993703ab3299f1ddfadf53d7f.patch
new file mode 100644
index 0000000..852eb4f
--- /dev/null
+++ b/SOURCES/0862a096c3a1d0f993703ab3299f1ddfadf53d7f.patch
@@ -0,0 +1,85 @@
+commit 0862a096c3a1d0f993703ab3299f1ddfadf53d7f
+Author: Shiju Jose <shiju.jose@huawei.com>
+Date:   Tue Aug 11 13:31:46 2020 +0100
+
+    rasdaemon: ras-mc-ctl: Add ARM processor error information
+    
+    Add supporting ARM processor error in the ras-mc-ctl tool.
+    
+    Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+---
+ util/ras-mc-ctl.in |   40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+--- rasdaemon-0.6.1.orig/util/ras-mc-ctl.in	2021-10-06 14:14:25.000440090 -0400
++++ rasdaemon-0.6.1/util/ras-mc-ctl.in	2021-10-06 14:15:59.995598590 -0400
+@@ -1124,6 +1124,7 @@ sub summary
+     my ($query, $query_handle, $out);
+     my ($err_type, $label, $mc, $top, $mid, $low, $count, $msg);
+     my ($etype, $severity, $etype_string, $severity_string);
++    my ($affinity, $mpidr);
+ 
+     my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", {});
+ 
+@@ -1159,6 +1160,22 @@ sub summary
+     }
+     $query_handle->finish;
+ 
++    # ARM processor arm_event errors
++    $query = "select affinity, mpidr, count(*) from arm_event group by affinity, mpidr";
++    $query_handle = $dbh->prepare($query);
++    $query_handle->execute();
++    $query_handle->bind_columns(\($affinity, $mpidr, $count));
++    $out = "";
++    while($query_handle->fetch()) {
++        $out .= "\t$count errors\n";
++    }
++    if ($out ne "") {
++        print "ARM processor events summary:\n$out\n";
++    } else {
++        print "No ARM processor errors.\n\n";
++    }
++    $query_handle->finish;
++
+     # extlog errors
+     $query = "select etype, severity, count(*) from extlog_event group by etype, severity";
+     $query_handle = $dbh->prepare($query);
+@@ -1202,6 +1219,7 @@ sub errors
+     my ($query, $query_handle, $id, $time, $count, $type, $msg, $label, $mc, $top, $mid, $low, $addr, $grain, $syndrome, $detail, $out);
+     my ($mcgcap,$mcgstatus, $status, $misc, $ip, $tsc, $walltime, $cpu, $cpuid, $apicid, $socketid, $cs, $bank, $cpuvendor, $bank_name, $mcgstatus_msg, $mcistatus_msg, $user_action, $mc_location);
+     my ($timestamp, $etype, $severity, $etype_string, $severity_string, $fru_id, $fru_text, $cper_data);
++    my ($error_count, $affinity, $mpidr, $r_state, $psci_state);
+ 
+     my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", {});
+ 
+@@ -1241,6 +1259,28 @@ sub errors
+     }
+     $query_handle->finish;
+ 
++    # ARM processor arm_event errors
++    $query = "select id, timestamp, error_count, affinity, mpidr, running_state, psci_state from arm_event order by id";
++    $query_handle = $dbh->prepare($query);
++    $query_handle->execute();
++    $query_handle->bind_columns(\($id, $timestamp, $error_count, $affinity, $mpidr, $r_state, $psci_state));
++    $out = "";
++    while($query_handle->fetch()) {
++        $out .= "$id $timestamp error: ";
++        $out .= "error_count=$error_count, " if ($error_count);
++        $out .= "affinity_level=$affinity, ";
++        $out .= sprintf "mpidr=0x%x, ", $mpidr;
++        $out .= sprintf "running_state=0x%x, ", $r_state;
++        $out .= sprintf "psci_state=0x%x", $psci_state;
++        $out .= "\n";
++    }
++    if ($out ne "") {
++        print "ARM processor events:\n$out\n";
++    } else {
++        print "No ARM processor errors.\n\n";
++    }
++    $query_handle->finish;
++
+     # Extlog errors
+     $query = "select id, timestamp, etype, severity, address, fru_id, fru_text, cper_data from extlog_event order by id";
+     $query_handle = $dbh->prepare($query);
diff --git a/SOURCES/16d929b024c31d54a7f8a72eab094376c7be27f5.patch b/SOURCES/16d929b024c31d54a7f8a72eab094376c7be27f5.patch
new file mode 100644
index 0000000..ab66f52
--- /dev/null
+++ b/SOURCES/16d929b024c31d54a7f8a72eab094376c7be27f5.patch
@@ -0,0 +1,32 @@
+commit 16d929b024c31d54a7f8a72eab094376c7be27f5
+Author: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Date:   Wed May 26 10:20:39 2021 +0200
+
+    Makefile.am: fix build header rules
+    
+    non-standard-hisilicon.h was added twice;
+    ras-memory-failure-handler.h is missing.
+    
+    Due to that, the tarball becomes incomplete, causing build
+    errors.
+    
+    While here, also adjust .travis.yml to use --enable-all.
+    
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+---
+ Makefile.am |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/Makefile.am	2021-10-13 13:27:53.402685179 -0400
++++ b/Makefile.am	2021-10-13 13:28:11.664525173 -0400
+@@ -54,7 +54,8 @@ rasdaemon_LDADD = -lpthread $(SQLITE3_LI
+ 
+ include_HEADERS = config.h  ras-events.h  ras-logger.h  ras-mc-handler.h \
+ 		  ras-aer-handler.h ras-mce-handler.h ras-record.h bitfield.h ras-report.h \
+-		  ras-extlog-handler.h ras-arm-handler.h ras-non-standard-handler.h
++		  ras-extlog-handler.h ras-arm-handler.h ras-non-standard-handler.h \
++		  ras-memory-failure-handler.h
+ 
+ # This rule can't be called with more than one Makefile job (like make -j8)
+ # I can't figure out a way to fix that
diff --git a/SOURCES/2290d65b97311dd5736838f1e285355f7f357046.patch b/SOURCES/2290d65b97311dd5736838f1e285355f7f357046.patch
new file mode 100644
index 0000000..0710974
--- /dev/null
+++ b/SOURCES/2290d65b97311dd5736838f1e285355f7f357046.patch
@@ -0,0 +1,538 @@
+commit 2290d65b97311dd5736838f1e285355f7f357046
+Author: Shiju Jose <shiju.jose@huawei.com>
+Date:   Mon Mar 8 16:57:26 2021 +0000
+
+    rasdaemon: add support for memory_failure events
+    
+    Add support to log the memory_failure kernel trace
+    events.
+    
+    Example rasdaemon log and SQLite DB output for the
+    memory_failure event,
+    =================================================
+    rasdaemon: memory_failure_event store: 0x126ce8f8
+    rasdaemon: register inserted at db
+    <...>-785   [000]     0.000024: memory_failure_event: 2020-10-02 13:27:13 -0400 pfn=0x204000000 page_type=free buddy page action_result=Delayed
+    
+    CREATE TABLE memory_failure_event (id INTEGER PRIMARY KEY, timestamp TEXT, pfn TEXT, page_type TEXT, action_result TEXT);
+    INSERT INTO memory_failure_event VALUES(1,'2020-10-02 13:27:13 -0400','0x204000000','free buddy page','Delayed');
+    ==================================================
+    
+    Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+---
+ Makefile.am                  |    4 
+ ras-events.c                 |   15 +++
+ ras-memory-failure-handler.c |  179 +++++++++++++++++++++++++++++++++++++++++++
+ ras-memory-failure-handler.h |   25 ++++++
+ ras-record.c                 |   56 +++++++++++++
+ ras-record.h                 |   13 +++
+ ras-report.c                 |   68 ++++++++++++++++
+ ras-report.h                 |    5 -
+ 8 files changed, 364 insertions(+), 1 deletion(-)
+
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ b/ras-memory-failure-handler.c	2021-10-14 16:31:36.840657728 -0400
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * 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.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include "libtrace/kbuffer.h"
++#include "ras-memory-failure-handler.h"
++#include "ras-record.h"
++#include "ras-logger.h"
++#include "ras-report.h"
++
++/* Memory failure - various types of pages */
++enum mf_action_page_type {
++	MF_MSG_KERNEL,
++	MF_MSG_KERNEL_HIGH_ORDER,
++	MF_MSG_SLAB,
++	MF_MSG_DIFFERENT_COMPOUND,
++	MF_MSG_POISONED_HUGE,
++	MF_MSG_HUGE,
++	MF_MSG_FREE_HUGE,
++	MF_MSG_NON_PMD_HUGE,
++	MF_MSG_UNMAP_FAILED,
++	MF_MSG_DIRTY_SWAPCACHE,
++	MF_MSG_CLEAN_SWAPCACHE,
++	MF_MSG_DIRTY_MLOCKED_LRU,
++	MF_MSG_CLEAN_MLOCKED_LRU,
++	MF_MSG_DIRTY_UNEVICTABLE_LRU,
++	MF_MSG_CLEAN_UNEVICTABLE_LRU,
++	MF_MSG_DIRTY_LRU,
++	MF_MSG_CLEAN_LRU,
++	MF_MSG_TRUNCATED_LRU,
++	MF_MSG_BUDDY,
++	MF_MSG_BUDDY_2ND,
++	MF_MSG_DAX,
++	MF_MSG_UNSPLIT_THP,
++	MF_MSG_UNKNOWN,
++};
++
++/* Action results for various types of pages */
++enum mf_action_result {
++	MF_IGNORED,     /* Error: cannot be handled */
++	MF_FAILED,      /* Error: handling failed */
++	MF_DELAYED,     /* Will be handled later */
++	MF_RECOVERED,   /* Successfully recovered */
++};
++
++/* memory failure page types */
++static const struct {
++	int	type;
++	const char	*page_type;
++} mf_page_type[] = {
++	{ MF_MSG_KERNEL, "reserved kernel page" },
++	{ MF_MSG_KERNEL_HIGH_ORDER, "high-order kernel page"},
++	{ MF_MSG_SLAB, "kernel slab page"},
++	{ MF_MSG_DIFFERENT_COMPOUND, "different compound page after locking"},
++	{ MF_MSG_POISONED_HUGE, "huge page already hardware poisoned"},
++	{ MF_MSG_HUGE, "huge page"},
++	{ MF_MSG_FREE_HUGE, "free huge page"},
++	{ MF_MSG_NON_PMD_HUGE, "non-pmd-sized huge page"},
++	{ MF_MSG_UNMAP_FAILED, "unmapping failed page"},
++	{ MF_MSG_DIRTY_SWAPCACHE, "dirty swapcache page"},
++	{ MF_MSG_CLEAN_SWAPCACHE, "clean swapcache page"},
++	{ MF_MSG_DIRTY_MLOCKED_LRU, "dirty mlocked LRU page"},
++	{ MF_MSG_CLEAN_MLOCKED_LRU, "clean mlocked LRU page"},
++	{ MF_MSG_DIRTY_UNEVICTABLE_LRU, "dirty unevictable LRU page"},
++	{ MF_MSG_CLEAN_UNEVICTABLE_LRU, "clean unevictable LRU page"},
++	{ MF_MSG_DIRTY_LRU, "dirty LRU page"},
++	{ MF_MSG_CLEAN_LRU, "clean LRU page"},
++	{ MF_MSG_TRUNCATED_LRU, "already truncated LRU page"},
++	{ MF_MSG_BUDDY, "free buddy page"},
++	{ MF_MSG_BUDDY_2ND, "free buddy page (2nd try)"},
++	{ MF_MSG_DAX, "dax page"},
++	{ MF_MSG_UNSPLIT_THP, "unsplit thp"},
++	{ MF_MSG_UNKNOWN, "unknown page"},
++};
++
++/* memory failure action results */
++static const struct {
++	int result;
++	const char *action_result;
++} mf_action_result[] = {
++	{ MF_IGNORED, "Ignored" },
++	{ MF_FAILED, "Failed" },
++	{ MF_DELAYED, "Delayed" },
++	{ MF_RECOVERED, "Recovered" },
++};
++
++static const char *get_page_type(int page_type)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(mf_page_type); i++)
++		if (mf_page_type[i].type == page_type)
++			return mf_page_type[i].page_type;
++
++	return "unknown page";
++}
++
++static const char *get_action_result(int result)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(mf_action_result); i++)
++		if (mf_action_result[i].result == result)
++			return mf_action_result[i].action_result;
++
++	return "unknown";
++}
++
++
++int ras_memory_failure_event_handler(struct trace_seq *s,
++				     struct pevent_record *record,
++				     struct event_format *event, void *context)
++{
++	unsigned long long val;
++	struct ras_events *ras = context;
++	time_t now;
++	struct tm *tm;
++	struct ras_mf_event ev;
++
++	/*
++	 * Newer kernels (3.10-rc1 or upper) provide an uptime clock.
++	 * On previous kernels, the way to properly generate an event would
++	 * be to inject a fake one, measure its timestamp and diff it against
++	 * gettimeofday. We won't do it here. Instead, let's use uptime,
++	 * falling-back to the event report's time, if "uptime" clock is
++	 * not available (legacy kernels).
++	 */
++
++	if (ras->use_uptime)
++		now = record->ts/user_hz + ras->uptime_diff;
++	else
++		now = time(NULL);
++
++	tm = localtime(&now);
++	if (tm)
++		strftime(ev.timestamp, sizeof(ev.timestamp),
++			 "%Y-%m-%d %H:%M:%S %z", tm);
++	trace_seq_printf(s, "%s ", ev.timestamp);
++
++	if (pevent_get_field_val(s,  event, "pfn", record, &val, 1) < 0)
++		return -1;
++	sprintf(ev.pfn, "0x%llx", val);
++	trace_seq_printf(s, "pfn=0x%llx ", val);
++
++	if (pevent_get_field_val(s, event, "type", record, &val, 1) < 0)
++		return -1;
++	ev.page_type = get_page_type(val);
++	trace_seq_printf(s, "page_type=%s ", ev.page_type);
++
++	if (pevent_get_field_val(s, event, "result", record, &val, 1) < 0)
++		return -1;
++	ev.action_result = get_action_result(val);
++	trace_seq_printf(s, "action_result=%s ", ev.action_result);
++
++	/* Store data into the SQLite DB */
++#ifdef HAVE_SQLITE3
++	ras_store_mf_event(ras, &ev);
++#endif
++
++#ifdef HAVE_ABRT_REPORT
++	/* Report event to ABRT */
++	ras_report_mf_event(ras, &ev);
++#endif
++
++	return 0;
++}
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ b/ras-memory-failure-handler.h	2021-10-14 16:31:36.840657728 -0400
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * 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.
++*/
++
++#ifndef __RAS_MEMORY_FAILURE_HANDLER_H
++#define __RAS_MEMORY_FAILURE_HANDLER_H
++
++#include "ras-events.h"
++#include "libtrace/event-parse.h"
++
++int ras_memory_failure_event_handler(struct trace_seq *s,
++				     struct pevent_record *record,
++				     struct event_format *event, void *context);
++
++#endif
+--- a/ras-record.c	2018-04-25 06:19:03.000000000 -0400
++++ b/ras-record.c	2021-10-14 16:31:36.840657728 -0400
+@@ -404,6 +404,55 @@ sqlite3_bind_text(priv->stmt_mce_record,
+ }
+ #endif
+ 
++/*
++ * Table and functions to handle ras:memory_failure
++ */
++
++#ifdef HAVE_MEMORY_FAILURE
++static const struct db_fields mf_event_fields[] = {
++	{ .name="id",			.type="INTEGER PRIMARY KEY" },
++	{ .name="timestamp",		.type="TEXT" },
++	{ .name="pfn",			.type="TEXT" },
++	{ .name="page_type",		.type="TEXT" },
++	{ .name="action_result",	.type="TEXT" },
++};
++
++static const struct db_table_descriptor mf_event_tab = {
++	.name = "memory_failure_event",
++	.fields = mf_event_fields,
++	.num_fields = ARRAY_SIZE(mf_event_fields),
++};
++
++int ras_store_mf_event(struct ras_events *ras, struct ras_mf_event *ev)
++{
++	int rc;
++	struct sqlite3_priv *priv = ras->db_priv;
++
++	if (!priv || !priv->stmt_mf_event)
++		return 0;
++	log(TERM, LOG_INFO, "memory_failure_event store: %p\n", priv->stmt_mf_event);
++
++	sqlite3_bind_text(priv->stmt_mf_event,  1, ev->timestamp, -1, NULL);
++	sqlite3_bind_text(priv->stmt_mf_event,  2, ev->pfn, -1, NULL);
++	sqlite3_bind_text(priv->stmt_mf_event,  3, ev->page_type, -1, NULL);
++	sqlite3_bind_text(priv->stmt_mf_event,  4, ev->action_result, -1, NULL);
++
++	rc = sqlite3_step(priv->stmt_mf_event);
++	if (rc != SQLITE_OK && rc != SQLITE_DONE)
++		log(TERM, LOG_ERR,
++		    "Failed to do memory_failure_event step on sqlite: error = %d\n", rc);
++
++	rc = sqlite3_reset(priv->stmt_mf_event);
++	if (rc != SQLITE_OK && rc != SQLITE_DONE)
++		log(TERM, LOG_ERR,
++		    "Failed reset memory_failure_event on sqlite: error = %d\n",
++		    rc);
++
++	log(TERM, LOG_INFO, "register inserted at db\n");
++
++	return rc;
++}
++#endif
+ 
+ /*
+  * Generic code
+@@ -567,6 +616,13 @@ usleep(10000);
+ 		rc = ras_mc_prepare_stmt(priv, &priv->stmt_arm_record,
+ 					&arm_event_tab);
+ #endif
++#ifdef HAVE_MEMORY_FAILURE
++	rc = ras_mc_create_table(priv, &mf_event_tab);
++	if (rc == SQLITE_OK) {
++		rc = ras_mc_prepare_stmt(priv, &priv->stmt_mf_event,
++					 &mf_event_tab);
++	}
++#endif
+ 
+ 		ras->db_priv = priv;
+ 	return 0;
+--- a/ras-record.h	2018-04-25 06:19:03.000000000 -0400
++++ b/ras-record.h	2021-10-14 16:31:36.840657728 -0400
+@@ -75,12 +75,20 @@ struct ras_arm_event {
+ 	int32_t psci_state;
+ };
+ 
++struct ras_mf_event {
++	char timestamp[64];
++	char pfn[30];
++	const char *page_type;
++	const char *action_result;
++};
++
+ struct ras_mc_event;
+ struct ras_aer_event;
+ struct ras_extlog_event;
+ struct ras_non_standard_event;
+ struct ras_arm_event;
+ struct mce_event;
++struct ras_mf_event;
+ 
+ #ifdef HAVE_SQLITE3
+ 
+@@ -104,6 +112,9 @@ struct sqlite3_priv {
+ #ifdef HAVE_ARM
+ 	sqlite3_stmt	*stmt_arm_record;
+ #endif
++#ifdef HAVE_MEMORY_FAILURE
++	sqlite3_stmt	*stmt_mf_event;
++#endif
+ };
+ 
+ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras);
+@@ -113,6 +124,7 @@ int ras_store_mce_record(struct ras_even
+ int ras_store_extlog_mem_record(struct ras_events *ras, struct ras_extlog_event *ev);
+ int ras_store_non_standard_record(struct ras_events *ras, struct ras_non_standard_event *ev);
+ int ras_store_arm_record(struct ras_events *ras, struct ras_arm_event *ev);
++int ras_store_mf_event(struct ras_events *ras, struct ras_mf_event *ev);
+ 
+ #else
+ static inline int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) { return 0; };
+@@ -122,6 +134,7 @@ static inline int ras_store_mce_record(s
+ static inline int ras_store_extlog_mem_record(struct ras_events *ras, struct ras_extlog_event *ev) { return 0; };
+ static inline int ras_store_non_standard_record(struct ras_events *ras, struct ras_non_standard_event *ev) { return 0; };
+ static inline int ras_store_arm_record(struct ras_events *ras, struct ras_arm_event *ev) { return 0; };
++static inline int ras_store_mf_event(struct ras_events *ras, struct ras_mf_event *ev) { return 0; };
+ 
+ #endif
+ 
+--- a/ras-report.c	2017-10-14 05:11:34.000000000 -0400
++++ b/ras-report.c	2021-10-14 16:31:36.840657728 -0400
+@@ -255,6 +255,28 @@ "midr=0x%lx\n"	\
+ 	return 0;
+ }
+ 
++static int set_mf_event_backtrace(char *buf, struct ras_mf_event *ev)
++{
++	char bt_buf[MAX_BACKTRACE_SIZE];
++
++	if (!buf || !ev)
++		return -1;
++
++	sprintf(bt_buf, "BACKTRACE="    \
++                                                "timestamp=%s\n"	\
++                                                "pfn=%s\n"		\
++                                                "page_type=%s\n"	\
++                                                "action_result=%s\n",	\
++                                                ev->timestamp,		\
++                                                ev->pfn,		\
++                                                ev->page_type,		\
++                                                ev->action_result);
++
++	strcat(buf, bt_buf);
++
++	return 0;
++}
++
+ static int commit_report_backtrace(int sockfd, int type, void *ev){
+ 	char buf[MAX_BACKTRACE_SIZE];
+ 	char *pbuf = buf;
+@@ -283,6 +305,9 @@ memset(buf, 0, MAX_BACKTRACE_SIZE);
+ 	case ARM_EVENT:
+ 		rc = set_arm_event_backtrace(buf, (struct ras_arm_event *)ev);
+ 		break;
++	case MF_EVENT:
++		rc = set_mf_event_backtrace(buf, (struct ras_mf_event *)ev);
++		break;
+ 	default:
+ 		return -1;
+ 	}
+@@ -549,3 +574,46 @@ return 0;
+ 		return -1;
+ 	}
+ }
++
++int ras_report_mf_event(struct ras_events *ras, struct ras_mf_event *ev)
++{
++	char buf[MAX_MESSAGE_SIZE];
++	int sockfd = 0;
++	int done = 0;
++	int rc = -1;
++
++	memset(buf, 0, sizeof(buf));
++
++	sockfd = setup_report_socket();
++	if (sockfd < 0)
++		return -1;
++
++	rc = commit_report_basic(sockfd);
++	if (rc < 0)
++		goto mf_fail;
++
++	rc = commit_report_backtrace(sockfd, MF_EVENT, ev);
++	if (rc < 0)
++		goto mf_fail;
++
++	sprintf(buf, "ANALYZER=%s", "rasdaemon-memory_failure");
++	rc = write(sockfd, buf, strlen(buf) + 1);
++	if (rc < strlen(buf) + 1)
++		goto mf_fail;
++
++	sprintf(buf, "REASON=%s", "memory failure problem");
++	rc = write(sockfd, buf, strlen(buf) + 1);
++	if (rc < strlen(buf) + 1)
++		goto mf_fail;
++
++	done = 1;
++
++mf_fail:
++	if (sockfd > 0)
++		close(sockfd);
++
++	if (done)
++		return 0;
++	else
++		return -1;
++}
+--- a/ras-report.h	2017-10-14 05:11:34.000000000 -0400
++++ b/ras-report.h	2021-10-14 16:31:36.840657728 -0400
+@@ -34,7 +34,8 @@ enum {
+ 	MCE_EVENT,
+ 	AER_EVENT,
+ 	NON_STANDARD_EVENT,
+-	ARM_EVENT
++	ARM_EVENT,
++	MF_EVENT,
+ };
+ 
+ #ifdef HAVE_ABRT_REPORT
+@@ -44,6 +45,7 @@ int ras_report_aer_event(struct ras_even
+ int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev);
+ int ras_report_non_standard_event(struct ras_events *ras, struct ras_non_standard_event *ev);
+ int ras_report_arm_event(struct ras_events *ras, struct ras_arm_event *ev);
++int ras_report_mf_event(struct ras_events *ras, struct ras_mf_event *ev);
+ 
+ #else
+ 
+@@ -52,6 +54,7 @@ static inline int ras_report_aer_event(s
+ static inline int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev) { return 0; };
+ static inline int ras_report_non_standard_event(struct ras_events *ras, struct ras_non_standard_event *ev) { return 0; };
+ static inline int ras_report_arm_event(struct ras_events *ras, struct ras_arm_event *ev) { return 0; };
++static inline int ras_report_mf_event(struct ras_events *ras, struct ras_mf_event *ev) { return 0; };
+ 
+ #endif
+ 
+--- a/Makefile.am	2018-04-25 06:21:56.000000000 -0400
++++ b/Makefile.am	2021-10-14 16:37:42.423639762 -0400
+@@ -41,12 +41,16 @@ endif
+ if WITH_EXTLOG
+    rasdaemon_SOURCES += ras-extlog-handler.c
+ endif
++if WITH_MEMORY_FAILURE
++   rasdaemon_SOURCES += ras-memory-failure-handler.c
++endif
+ if WITH_ABRT_REPORT
+    rasdaemon_SOURCES += ras-report.c
+ endif
+ if WITH_HISI_NS_DECODE
+    rasdaemon_SOURCES += non-standard-hisi_hip07.c
+ endif
++
+ rasdaemon_LDADD = -lpthread $(SQLITE3_LIBS) libtrace/libtrace.a
+ 
+ include_HEADERS = config.h  ras-events.h  ras-logger.h  ras-mc-handler.h \
+--- a/ras-events.c	2021-10-14 16:31:36.730658636 -0400
++++ b/ras-events.c	2021-10-14 16:37:11.043898809 -0400
+@@ -33,6 +33,7 @@ * Foundation, Inc., 51 Franklin Street,
+ #include "ras-arm-handler.h"
+ #include "ras-mce-handler.h"
+ #include "ras-extlog-handler.h"
++#include "ras-memory-failure-handler.h"
+ #include "ras-record.h"
+ #include "ras-logger.h"
+ 
+@@ -218,6 +219,10 @@ if (rc < 0) {
+ 	rc |= __toggle_ras_mc_event(ras, "ras", "arm_event", enable);
+ #endif
+ 
++#ifdef HAVE_MEMORY_FAILURE
++	rc |= __toggle_ras_mc_event(ras, "ras", "memory_failure_event", enable);
++#endif
++
+ free_ras:
+ 	free(ras);
+ 	return rc;
+@@ -736,6 +741,16 @@ (void)open("/sys/kernel/debug/ras/daemon
+ 		    "ras", "aer_event");
+ #endif
+ 
++#ifdef HAVE_MEMORY_FAILURE
++       rc = add_event_handler(ras, pevent, page_size, "ras", "memory_failure_event",
++                              ras_memory_failure_event_handler);
++       if (!rc)
++               num_events++;
++       else
++               log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
++                   "ras", "memory_failure_event");
++#endif
++
+ 	if (!num_events) {
+ 		log(ALL, LOG_INFO,
+ 		    "Failed to trace all supported RAS events. Aborting.\n");
diff --git a/SOURCES/28ea956acc2dab7c18b4701f9657afb9ab3ddc79.patch b/SOURCES/28ea956acc2dab7c18b4701f9657afb9ab3ddc79.patch
new file mode 100644
index 0000000..fdc509b
--- /dev/null
+++ b/SOURCES/28ea956acc2dab7c18b4701f9657afb9ab3ddc79.patch
@@ -0,0 +1,28 @@
+commit 28ea956acc2dab7c18b4701f9657afb9ab3ddc79
+Author: Muralidhara M K <muralimk@amd.com>
+Date:   Mon Jul 12 05:18:43 2021 -0500
+
+    rasdaemon: set SMCA maximum number of banks to 64
+    
+    Newer AMD systems with SMCA banks support up to 64 MCA banks per CPU.
+    
+    This patch is based on the commit below upstremed into the kernel:
+    a0bc32b3cacf ("x86/mce: Increase maximum number of banks to 64")
+    
+    Signed-off-by: Muralidhara M K <muralimk@amd.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+diff --git a/mce-amd-smca.c b/mce-amd-smca.c
+index e0cf512..3c346f4 100644
+--- a/mce-amd-smca.c
++++ b/mce-amd-smca.c
+@@ -75,6 +75,9 @@ enum smca_bank_types {
+ 	N_SMCA_BANK_TYPES
+ };
+ 
++/* Maximum number of MCA banks per CPU. */
++#define MAX_NR_BANKS	64
++
+ /* SMCA Extended error strings */
+ /* Load Store */
+ static const char * const smca_ls_mce_desc[] = {
diff --git a/SOURCES/546cf713f667437fb6e283cc3dc090679eb47d08.patch b/SOURCES/546cf713f667437fb6e283cc3dc090679eb47d08.patch
new file mode 100644
index 0000000..448b1f6
--- /dev/null
+++ b/SOURCES/546cf713f667437fb6e283cc3dc090679eb47d08.patch
@@ -0,0 +1,372 @@
+commit 546cf713f667437fb6e283cc3dc090679eb47d08
+Author: Subhendu Saha <subhends@akamai.com>
+Date:   Tue Jan 12 03:29:55 2021 -0500
+
+    Fix ras-mc-ctl script.
+    
+    When rasdaemon is compiled without enabling aer, mce, devlink,
+    etc., those tables are not created in the database file. Then
+    ras-mc-ctl script breaks trying to query data from non-existent
+    tables.
+    
+    Signed-off-by: Subhendu Saha subhends@akamai.com
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+---
+ util/ras-mc-ctl.in |  310 ++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 168 insertions(+), 142 deletions(-)
+
+--- a/util/ras-mc-ctl.in	2021-10-12 13:45:43.260646935 -0400
++++ b/util/ras-mc-ctl.in	2021-10-12 13:46:38.610158949 -0400
+@@ -41,6 +41,16 @@ my $sysconfdir  = "@sysconfdir@";
+ my $dmidecode   = find_prog ("dmidecode");
+ my $modprobe    = find_prog ("modprobe")  or exit (1);
+ 
++my $has_aer = 0;
++my $has_arm = 0;
++my $has_extlog = 0;
++my $has_mce = 0;
++
++@WITH_AER_TRUE@$has_aer = 1;
++@WITH_ARM_TRUE@$has_arm = 1;
++@WITH_EXTLOG_TRUE@$has_extlog = 1;
++@WITH_MCE_TRUE@$has_mce = 1;
++
+ my %conf        = ();
+ my %bus         = ();
+ my %dimm_size   = ();
+@@ -1145,70 +1155,78 @@ sub summary
+     $query_handle->finish;
+ 
+     # PCIe AER aer_event errors
+-    $query = "select err_type, err_msg, count(*) from aer_event group by err_type, err_msg";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($err_type, $msg, $count));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $out .= "\t$count $err_type errors: $msg\n";
+-    }
+-    if ($out ne "") {
+-        print "PCIe AER events summary:\n$out\n";
+-    } else {
+-        print "No PCIe AER errors.\n\n";
++    if ($has_aer == 1) {
++        $query = "select err_type, err_msg, count(*) from aer_event group by err_type, err_msg";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($err_type, $msg, $count));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "\t$count $err_type errors: $msg\n";
++        }
++        if ($out ne "") {
++            print "PCIe AER events summary:\n$out\n";
++        } else {
++            print "No PCIe AER errors.\n\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     # ARM processor arm_event errors
+-    $query = "select affinity, mpidr, count(*) from arm_event group by affinity, mpidr";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($affinity, $mpidr, $count));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $out .= "\t$count errors\n";
+-    }
+-    if ($out ne "") {
+-        print "ARM processor events summary:\n$out\n";
+-    } else {
+-        print "No ARM processor errors.\n\n";
++    if ($has_arm == 1) {
++        $query = "select affinity, mpidr, count(*) from arm_event group by affinity, mpidr";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($affinity, $mpidr, $count));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "\t$count errors\n";
++        }
++        if ($out ne "") {
++            print "ARM processor events summary:\n$out\n";
++        } else {
++            print "No ARM processor errors.\n\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     # extlog errors
+-    $query = "select etype, severity, count(*) from extlog_event group by etype, severity";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($etype, $severity, $count));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $etype_string = get_extlog_type($etype);
+-        $severity_string = get_extlog_severity($severity);
+-        $out .= "\t$count $etype_string $severity_string errors\n";
+-    }
+-    if ($out ne "") {
+-        print "Extlog records summary:\n$out";
+-    } else {
+-        print "No Extlog errors.\n";
++    if ($has_extlog == 1) {
++        $query = "select etype, severity, count(*) from extlog_event group by etype, severity";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($etype, $severity, $count));
++        $out = "";
++        while($query_handle->fetch()) {
++            $etype_string = get_extlog_type($etype);
++            $severity_string = get_extlog_severity($severity);
++            $out .= "\t$count $etype_string $severity_string errors\n";
++        }
++        if ($out ne "") {
++            print "Extlog records summary:\n$out";
++        } else {
++            print "No Extlog errors.\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     # MCE mce_record errors
+-    $query = "select error_msg, count(*) from mce_record group by error_msg";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($msg, $count));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $out .= "\t$count $msg errors\n";
+-    }
+-    if ($out ne "") {
+-        print "MCE records summary:\n$out";
+-    } else {
+-        print "No MCE errors.\n";
++    if ($has_mce == 1) {
++        $query = "select error_msg, count(*) from mce_record group by error_msg";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($msg, $count));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "\t$count $msg errors\n";
++        }
++        if ($out ne "") {
++            print "MCE records summary:\n$out";
++        } else {
++            print "No MCE errors.\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     undef($dbh);
+ }
+@@ -1244,105 +1262,113 @@ sub errors
+     $query_handle->finish;
+ 
+     # PCIe AER aer_event errors
+-    $query = "select id, timestamp, err_type, err_msg from aer_event order by id";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($id, $time, $type, $msg));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $out .= "$id $time $type error: $msg\n";
+-    }
+-    if ($out ne "") {
+-        print "PCIe AER events:\n$out\n";
+-    } else {
+-        print "No PCIe AER errors.\n\n";
++    if ($has_aer == 1) {
++        $query = "select id, timestamp, err_type, err_msg from aer_event order by id";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($id, $time, $type, $msg));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "$id $time $type error: $msg\n";
++        }
++        if ($out ne "") {
++            print "PCIe AER events:\n$out\n";
++        } else {
++            print "No PCIe AER errors.\n\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     # ARM processor arm_event errors
+-    $query = "select id, timestamp, error_count, affinity, mpidr, running_state, psci_state from arm_event order by id";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($id, $timestamp, $error_count, $affinity, $mpidr, $r_state, $psci_state));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $out .= "$id $timestamp error: ";
+-        $out .= "error_count=$error_count, " if ($error_count);
+-        $out .= "affinity_level=$affinity, ";
+-        $out .= sprintf "mpidr=0x%x, ", $mpidr;
+-        $out .= sprintf "running_state=0x%x, ", $r_state;
+-        $out .= sprintf "psci_state=0x%x", $psci_state;
+-        $out .= "\n";
+-    }
+-    if ($out ne "") {
+-        print "ARM processor events:\n$out\n";
+-    } else {
+-        print "No ARM processor errors.\n\n";
++    if ($has_arm == 1) {
++        $query = "select id, timestamp, error_count, affinity, mpidr, running_state, psci_state from arm_event order by id";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($id, $timestamp, $error_count, $affinity, $mpidr, $r_state, $psci_state));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "$id $timestamp error: ";
++            $out .= "error_count=$error_count, " if ($error_count);
++            $out .= "affinity_level=$affinity, ";
++            $out .= sprintf "mpidr=0x%x, ", $mpidr;
++            $out .= sprintf "running_state=0x%x, ", $r_state;
++            $out .= sprintf "psci_state=0x%x", $psci_state;
++            $out .= "\n";
++        }
++        if ($out ne "") {
++            print "ARM processor events:\n$out\n";
++        } else {
++            print "No ARM processor errors.\n\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     # Extlog errors
+-    $query = "select id, timestamp, etype, severity, address, fru_id, fru_text, cper_data from extlog_event order by id";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($id, $timestamp, $etype, $severity, $addr, $fru_id, $fru_text, $cper_data));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $etype_string = get_extlog_type($etype);
+-        $severity_string = get_extlog_severity($severity);
+-        $out .= "$id $timestamp error: ";
+-        $out .= "type=$etype_string, ";
+-        $out .= "severity=$severity_string, ";
+-        $out .= sprintf "address=0x%08x, ", $addr;
+-        $out .= sprintf "fru_id=%s, ", get_uuid_le($fru_id);
+-        $out .= "fru_text='$fru_text', ";
+-        $out .= get_cper_data_text($cper_data) if ($cper_data);
+-        $out .= "\n";
+-    }
+-    if ($out ne "") {
+-        print "Extlog events:\n$out\n";
+-    } else {
+-        print "No Extlog errors.\n\n";
++    if ($has_extlog) {
++        $query = "select id, timestamp, etype, severity, address, fru_id, fru_text, cper_data from extlog_event order by id";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($id, $timestamp, $etype, $severity, $addr, $fru_id, $fru_text, $cper_data));
++        $out = "";
++        while($query_handle->fetch()) {
++            $etype_string = get_extlog_type($etype);
++            $severity_string = get_extlog_severity($severity);
++            $out .= "$id $timestamp error: ";
++            $out .= "type=$etype_string, ";
++            $out .= "severity=$severity_string, ";
++            $out .= sprintf "address=0x%08x, ", $addr;
++            $out .= sprintf "fru_id=%s, ", get_uuid_le($fru_id);
++            $out .= "fru_text='$fru_text', ";
++            $out .= get_cper_data_text($cper_data) if ($cper_data);
++            $out .= "\n";
++        }
++        if ($out ne "") {
++            print "Extlog events:\n$out\n";
++        } else {
++            print "No Extlog errors.\n\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     # MCE mce_record errors
+-    $query = "select id, timestamp, mcgcap, mcgstatus, status, addr, misc, ip, tsc, walltime, cpu, cpuid, apicid, socketid, cs, bank, cpuvendor, bank_name, error_msg, mcgstatus_msg, mcistatus_msg, user_action, mc_location from mce_record order by id";
+-    $query_handle = $dbh->prepare($query);
+-    $query_handle->execute();
+-    $query_handle->bind_columns(\($id, $time, $mcgcap,$mcgstatus, $status, $addr, $misc, $ip, $tsc, $walltime, $cpu, $cpuid, $apicid, $socketid, $cs, $bank, $cpuvendor, $bank_name, $msg, $mcgstatus_msg, $mcistatus_msg, $user_action, $mc_location));
+-    $out = "";
+-    while($query_handle->fetch()) {
+-        $out .= "$id $time error: $msg";
+-	$out .= ", CPU $cpuvendor" if ($cpuvendor);
+-	$out .= ", bank $bank_name" if ($bank_name);
+-	$out .= ", mcg $mcgstatus_msg" if ($mcgstatus_msg);
+-	$out .= ", mci $mcistatus_msg" if ($mcistatus_msg);
+-	$out .= ", $mc_location" if ($mc_location);
+-	$out .= ", $user_action" if ($user_action);
+-	$out .= sprintf ", mcgcap=0x%08x", $mcgcap if ($mcgcap);
+-	$out .= sprintf ", mcgstatus=0x%08x", $mcgstatus if ($mcgstatus);
+-	$out .= sprintf ", status=0x%08x", $status if ($status);
+-	$out .= sprintf ", addr=0x%08x", $addr if ($addr);
+-	$out .= sprintf ", misc=0x%08x", $misc if ($misc);
+-	$out .= sprintf ", ip=0x%08x", $ip if ($ip);
+-	$out .= sprintf ", tsc=0x%08x", $tsc if ($tsc);
+-	$out .= sprintf ", walltime=0x%08x", $walltime if ($walltime);
+-	$out .= sprintf ", cpu=0x%08x", $cpu if ($cpu);
+-	$out .= sprintf ", cpuid=0x%08x", $cpuid if ($cpuid);
+-	$out .= sprintf ", apicid=0x%08x", $apicid if ($apicid);
+-	$out .= sprintf ", socketid=0x%08x", $socketid if ($socketid);
+-	$out .= sprintf ", cs=0x%08x", $cs if ($cs);
+-	$out .= sprintf ", bank=0x%08x", $bank if ($bank);
++    if ($has_mce == 1) {
++        $query = "select id, timestamp, mcgcap, mcgstatus, status, addr, misc, ip, tsc, walltime, cpu, cpuid, apicid, socketid, cs, bank, cpuvendor, bank_name, error_msg, mcgstatus_msg, mcistatus_msg, user_action, mc_location from mce_record order by id";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($id, $time, $mcgcap,$mcgstatus, $status, $addr, $misc, $ip, $tsc, $walltime, $cpu, $cpuid, $apicid, $socketid, $cs, $bank, $cpuvendor, $bank_name, $msg, $mcgstatus_msg, $mcistatus_msg, $user_action, $mc_location));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "$id $time error: $msg";
++        $out .= ", CPU $cpuvendor" if ($cpuvendor);
++        $out .= ", bank $bank_name" if ($bank_name);
++        $out .= ", mcg $mcgstatus_msg" if ($mcgstatus_msg);
++        $out .= ", mci $mcistatus_msg" if ($mcistatus_msg);
++        $out .= ", $mc_location" if ($mc_location);
++        $out .= ", $user_action" if ($user_action);
++        $out .= sprintf ", mcgcap=0x%08x", $mcgcap if ($mcgcap);
++        $out .= sprintf ", mcgstatus=0x%08x", $mcgstatus if ($mcgstatus);
++        $out .= sprintf ", status=0x%08x", $status if ($status);
++        $out .= sprintf ", addr=0x%08x", $addr if ($addr);
++        $out .= sprintf ", misc=0x%08x", $misc if ($misc);
++        $out .= sprintf ", ip=0x%08x", $ip if ($ip);
++        $out .= sprintf ", tsc=0x%08x", $tsc if ($tsc);
++        $out .= sprintf ", walltime=0x%08x", $walltime if ($walltime);
++        $out .= sprintf ", cpu=0x%08x", $cpu if ($cpu);
++        $out .= sprintf ", cpuid=0x%08x", $cpuid if ($cpuid);
++        $out .= sprintf ", apicid=0x%08x", $apicid if ($apicid);
++        $out .= sprintf ", socketid=0x%08x", $socketid if ($socketid);
++        $out .= sprintf ", cs=0x%08x", $cs if ($cs);
++        $out .= sprintf ", bank=0x%08x", $bank if ($bank);
+ 
+-	$out .= "\n";
+-    }
+-    if ($out ne "") {
+-        print "MCE events:\n$out\n";
+-    } else {
+-        print "No MCE errors.\n\n";
++        $out .= "\n";
++        }
++        if ($out ne "") {
++            print "MCE events:\n$out\n";
++        } else {
++            print "No MCE errors.\n\n";
++        }
++        $query_handle->finish;
+     }
+-    $query_handle->finish;
+ 
+     undef($dbh);
+ }
diff --git a/SOURCES/7937f0d6c2aaaed096f3a3d306416743c0dcb7a4.patch b/SOURCES/7937f0d6c2aaaed096f3a3d306416743c0dcb7a4.patch
new file mode 100644
index 0000000..76afc8e
--- /dev/null
+++ b/SOURCES/7937f0d6c2aaaed096f3a3d306416743c0dcb7a4.patch
@@ -0,0 +1,24 @@
+commit 7937f0d6c2aaaed096f3a3d306416743c0dcb7a4
+Author: Muralidhara M K <muralimk@amd.com>
+Date:   Wed Jul 28 01:52:12 2021 -0500
+
+    rasdaemon: Support MCE for AMD CPU family 19h
+    
+    Add support for family 19h x86 CPUs from AMD.
+    
+    Signed-off-by: Muralidhara M K <muralimk@amd.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+diff --git a/ras-mce-handler.c b/ras-mce-handler.c
+index 805004a..f2b53d4 100644
+--- a/ras-mce-handler.c
++++ b/ras-mce-handler.c
+@@ -208,7 +208,7 @@ static int detect_cpu(struct ras_events *ras)
+ 			mce->cputype = CPU_AMD_SMCA;
+ 			goto ret;
+ 		}
+-		if (mce->family > 23) {
++		if (mce->family > 25) {
+ 			log(ALL, LOG_INFO,
+ 			    "Can't parse MCE for this AMD CPU yet %d\n",
+ 			    mce->family);
diff --git a/SOURCES/9acef39f13833f7d53ef96abc5a72e79384260f4.patch b/SOURCES/9acef39f13833f7d53ef96abc5a72e79384260f4.patch
new file mode 100644
index 0000000..c4c8af1
--- /dev/null
+++ b/SOURCES/9acef39f13833f7d53ef96abc5a72e79384260f4.patch
@@ -0,0 +1,230 @@
+commit 9acef39f13833f7d53ef96abc5a72e79384260f4
+Author: Naveen Krishna Chatradhi <nchatrad@amd.com>
+Date:   Tue Jun 1 11:01:17 2021 +0530
+
+    rasdaemon: Add new SMCA bank types with error decoding
+    
+    Upcoming systems with Scalable Machine Check Architecture (SMCA) have
+    new MCA banks added.
+    
+    This patch adds the (HWID, MCATYPE) tuple, name and error decoding for
+    those new SMCA banks.
+    While at it, optimize the string names in smca_bank_name[].
+    
+    Signed-off-by: Muralidhara M K <muralimk@amd.com>
+    Signed-off-by: Naveen Krishna Chatradhi <nchatrad@amd.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+diff --git a/mce-amd-smca.c b/mce-amd-smca.c
+index 7c619fd..e0cf512 100644
+--- a/mce-amd-smca.c
++++ b/mce-amd-smca.c
+@@ -47,7 +47,7 @@
+ /* These may be used by multiple smca_hwid_mcatypes */
+ enum smca_bank_types {
+ 	SMCA_LS = 0,    /* Load Store */
+-	SMCA_LS_V2,	/* Load Store */
++	SMCA_LS_V2,
+ 	SMCA_IF,        /* Instruction Fetch */
+ 	SMCA_L2_CACHE,  /* L2 Cache */
+ 	SMCA_DE,        /* Decoder Unit */
+@@ -56,17 +56,22 @@ enum smca_bank_types {
+ 	SMCA_FP,        /* Floating Point */
+ 	SMCA_L3_CACHE,  /* L3 Cache */
+ 	SMCA_CS,        /* Coherent Slave */
+-	SMCA_CS_V2,     /* Coherent Slave V2 */
++	SMCA_CS_V2,
+ 	SMCA_PIE,       /* Power, Interrupts, etc. */
+ 	SMCA_UMC,       /* Unified Memory Controller */
++	SMCA_UMC_V2,
+ 	SMCA_PB,        /* Parameter Block */
+ 	SMCA_PSP,       /* Platform Security Processor */
+-	SMCA_PSP_V2,    /* Platform Security Processor V2 */
++	SMCA_PSP_V2,
+ 	SMCA_SMU,       /* System Management Unit */
+-	SMCA_SMU_V2,    /* System Management Unit V2 */
++	SMCA_SMU_V2,
+ 	SMCA_MP5,	/* Microprocessor 5 Unit */
+ 	SMCA_NBIO,	/* Northbridge IO Unit */
+ 	SMCA_PCIE,	/* PCI Express Unit */
++	SMCA_PCIE_V2,
++	SMCA_XGMI_PCS,	/* xGMI PCS Unit */
++	SMCA_XGMI_PHY,	/* xGMI PHY Unit */
++	SMCA_WAFL_PHY,	/* WAFL PHY Unit */
+ 	N_SMCA_BANK_TYPES
+ };
+ 
+@@ -237,6 +242,22 @@ static const char * const smca_umc_mce_desc[] = {
+ 	"Command/address parity error",
+ 	"Write data CRC error",
+ };
++
++static const char * const smca_umc2_mce_desc[] = {
++	"DRAM ECC error",
++	"Data poison error",
++	"SDP parity error",
++	"Reserved",
++	"Address/Command parity error",
++	"Write data parity error",
++	"DCQ SRAM ECC error",
++	"Reserved",
++	"Read data parity error",
++	"Rdb SRAM ECC error",
++	"RdRsp SRAM ECC error",
++	"LM32 MP errors",
++};
++
+ /* Parameter Block */
+ static const char * const smca_pb_mce_desc[] = {
+ 	"Parameter Block RAM ECC error",
+@@ -314,6 +335,55 @@ static const char * const smca_pcie_mce_desc[] = {
+ 	"CCIX Non-okay write response with data error",
+ };
+ 
++static const char * const smca_pcie2_mce_desc[] = {
++	"SDP Parity Error logging",
++};
++
++static const char * const smca_xgmipcs_mce_desc[] = {
++	"Data Loss Error",
++	"Training Error",
++	"Flow Control Acknowledge Error",
++	"Rx Fifo Underflow Error",
++	"Rx Fifo Overflow Error",
++	"CRC Error",
++	"BER Exceeded Error",
++	"Tx Vcid Data Error",
++	"Replay Buffer Parity Error",
++	"Data Parity Error",
++	"Replay Fifo Overflow Error",
++	"Replay Fifo Underflow Error",
++	"Elastic Fifo Overflow Error",
++	"Deskew Error",
++	"Flow Control CRC Error",
++	"Data Startup Limit Error",
++	"FC Init Timeout Error",
++	"Recovery Timeout Error",
++	"Ready Serial Timeout Error",
++	"Ready Serial Attempt Error",
++	"Recovery Attempt Error",
++	"Recovery Relock Attempt Error",
++	"Replay Attempt Error",
++	"Sync Header Error",
++	"Tx Replay Timeout Error",
++	"Rx Replay Timeout Error",
++	"LinkSub Tx Timeout Error",
++	"LinkSub Rx Timeout Error",
++	"Rx CMD Pocket Error",
++};
++
++static const char * const smca_xgmiphy_mce_desc[] = {
++	"RAM ECC Error",
++	"ARC instruction buffer parity error",
++	"ARC data buffer parity error",
++	"PHY APB error",
++};
++
++static const char * const smca_waflphy_mce_desc[] = {
++	"RAM ECC Error",
++	"ARC instruction buffer parity error",
++	"ARC data buffer parity error",
++	"PHY APB error",
++};
+ 
+ struct smca_mce_desc {
+ 	const char * const *descs;
+@@ -333,6 +403,7 @@ static struct smca_mce_desc smca_mce_descs[] = {
+ 	[SMCA_CS_V2]    = { smca_cs2_mce_desc,  ARRAY_SIZE(smca_cs2_mce_desc) },
+ 	[SMCA_PIE]      = { smca_pie_mce_desc,  ARRAY_SIZE(smca_pie_mce_desc) },
+ 	[SMCA_UMC]      = { smca_umc_mce_desc,  ARRAY_SIZE(smca_umc_mce_desc) },
++	[SMCA_UMC_V2]	= { smca_umc2_mce_desc,	ARRAY_SIZE(smca_umc2_mce_desc)	},
+ 	[SMCA_PB]       = { smca_pb_mce_desc,   ARRAY_SIZE(smca_pb_mce_desc)  },
+ 	[SMCA_PSP]      = { smca_psp_mce_desc,  ARRAY_SIZE(smca_psp_mce_desc) },
+ 	[SMCA_PSP_V2]   = { smca_psp2_mce_desc, ARRAY_SIZE(smca_psp2_mce_desc)},
+@@ -341,6 +412,10 @@ static struct smca_mce_desc smca_mce_descs[] = {
+ 	[SMCA_MP5]      = { smca_mp5_mce_desc,  ARRAY_SIZE(smca_mp5_mce_desc) },
+ 	[SMCA_NBIO]     = { smca_nbio_mce_desc, ARRAY_SIZE(smca_nbio_mce_desc)},
+ 	[SMCA_PCIE]     = { smca_pcie_mce_desc, ARRAY_SIZE(smca_pcie_mce_desc)},
++	[SMCA_PCIE_V2]	= { smca_pcie2_mce_desc,   ARRAY_SIZE(smca_pcie2_mce_desc)	},
++	[SMCA_XGMI_PCS]	= { smca_xgmipcs_mce_desc, ARRAY_SIZE(smca_xgmipcs_mce_desc)	},
++	[SMCA_XGMI_PHY]	= { smca_xgmiphy_mce_desc, ARRAY_SIZE(smca_xgmiphy_mce_desc)	},
++	[SMCA_WAFL_PHY]	= { smca_waflphy_mce_desc, ARRAY_SIZE(smca_waflphy_mce_desc)	},
+ };
+ 
+ struct smca_hwid {
+@@ -369,6 +444,8 @@ static struct smca_hwid smca_hwid_mcatypes[] = {
+ 
+ 	/* Unified Memory Controller MCA type */
+ 	{ SMCA_UMC,      0x00000096 },
++	/* Heterogeneous systems may have both UMC and UMC_v2 types on the same node. */
++	{ SMCA_UMC_V2,   0x00010096 },
+ 
+ 	/* Parameter Block MCA type */
+ 	{ SMCA_PB,       0x00000005 },
+@@ -389,6 +466,16 @@ static struct smca_hwid smca_hwid_mcatypes[] = {
+ 
+ 	/* PCI Express Unit MCA type */
+ 	{ SMCA_PCIE,     0x00000046 },
++	{ SMCA_PCIE_V2,  0x00010046 },
++
++	/* Ext Global Memory Interconnect PCS MCA type */
++	{ SMCA_XGMI_PCS, 0x00000050 },
++
++	/* Ext Global Memory Interconnect PHY MCA type */
++	{ SMCA_XGMI_PHY, 0x00000259 },
++
++	/* WAFL PHY MCA type */
++	{ SMCA_WAFL_PHY, 0x00000267 },
+ };
+ 
+ struct smca_bank_name {
+@@ -396,27 +483,28 @@ struct smca_bank_name {
+ };
+ 
+ static struct smca_bank_name smca_names[] = {
+-	[SMCA_LS]       = { "Load Store Unit" },
+-	[SMCA_LS_V2]    = { "Load Store Unit" },
+-	[SMCA_IF]       = { "Instruction Fetch Unit" },
+-	[SMCA_L2_CACHE] = { "L2 Cache" },
+-	[SMCA_DE]       = { "Decode Unit" },
+-	[SMCA_RESERVED] = { "Reserved" },
+-	[SMCA_EX]       = { "Execution Unit" },
+-	[SMCA_FP]       = { "Floating Point Unit" },
+-	[SMCA_L3_CACHE] = { "L3 Cache" },
+-	[SMCA_CS]       = { "Coherent Slave" },
+-	[SMCA_CS_V2]    = { "Coherent Slave" },
+-	[SMCA_PIE]      = { "Power, Interrupts, etc." },
+-	[SMCA_UMC]      = { "Unified Memory Controller" },
+-	[SMCA_PB]       = { "Parameter Block" },
+-	[SMCA_PSP]      = { "Platform Security Processor" },
+-	[SMCA_PSP_V2]   = { "Platform Security Processor" },
+-	[SMCA_SMU]      = { "System Management Unit" },
+-	[SMCA_SMU_V2]   = { "System Management Unit" },
+-	[SMCA_MP5]	= { "Microprocessor 5 Unit" },
+-	[SMCA_NBIO]     = { "Northbridge IO Unit" },
+-	[SMCA_PCIE]     = { "PCI Express Unit" },
++	[SMCA_LS ... SMCA_LS_V2]	= { "Load Store Unit" },
++	[SMCA_IF]			= { "Instruction Fetch Unit" },
++	[SMCA_L2_CACHE]			= { "L2 Cache" },
++	[SMCA_DE]			= { "Decode Unit" },
++	[SMCA_RESERVED]			= { "Reserved" },
++	[SMCA_EX]			= { "Execution Unit" },
++	[SMCA_FP]			= { "Floating Point Unit" },
++	[SMCA_L3_CACHE]			= { "L3 Cache" },
++	[SMCA_CS ... SMCA_CS_V2]	= { "Coherent Slave" },
++	[SMCA_PIE]			= { "Power, Interrupts, etc." },
++	[SMCA_UMC]			= { "Unified Memory Controller" },
++	[SMCA_UMC_V2]			= { "Unified Memory Controller V2" },
++	[SMCA_PB]			= { "Parameter Block" },
++	[SMCA_PSP ... SMCA_PSP_V2]	= { "Platform Security Processor" },
++	[SMCA_SMU ... SMCA_SMU_V2]	= { "System Management Unit" },
++	[SMCA_MP5]			= { "Microprocessor 5 Unit" },
++	[SMCA_NBIO]			= { "Northbridge IO Unit" },
++	[SMCA_PCIE ... SMCA_PCIE_V2]	= { "PCI Express Unit" },
++	[SMCA_XGMI_PCS]			= { "Ext Global Memory Interconnect PCS Unit" },
++	[SMCA_XGMI_PHY]			= { "Ext Global Memory Interconnect PHY Unit" },
++	[SMCA_WAFL_PHY]			= { "WAFL PHY Unit" },
++
+ };
+ 
+ static void amd_decode_errcode(struct mce_event *e)
diff --git a/SOURCES/a8c776ed94f68ae31d7b5f74e19545698898c13c.patch b/SOURCES/a8c776ed94f68ae31d7b5f74e19545698898c13c.patch
new file mode 100644
index 0000000..38657d4
--- /dev/null
+++ b/SOURCES/a8c776ed94f68ae31d7b5f74e19545698898c13c.patch
@@ -0,0 +1,138 @@
+commit a8c776ed94f68ae31d7b5f74e19545698898c13c
+Author: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Date:   Tue Aug 14 13:06:27 2018 -0300
+
+    mce-intel-*: fix a warning when using FIELD(<num>, NULL)
+    
+    Internally, FIELD() macro checks the size of an array, by
+    using ARRAY_SIZE. Well, this macro causes a division by zero
+    if NULL is used, as its type is void, as warned:
+    
+            mce-intel-dunnington.c:30:2: note: in expansion of macro ‘FIELD’
+              FIELD(17, NULL),
+              ^~~~~
+            ras-mce-handler.h:28:33: warning: division ‘sizeof (void *) / sizeof (void)’ does not compute the number of array elements [-Wsizeof-pointer-div]
+             #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x)))
+                                             ^
+            bitfield.h:37:51: note: in expansion of macro ‘ARRAY_SIZE’
+             #define FIELD(start_bit, name) { start_bit, name, ARRAY_SIZE(name) }
+                                                               ^~~~~~~~~~
+    
+    While this warning is harmless, it may prevent seeing more serios
+    warnings. So, add a FIELD_NULL(<num>) macro to avoid that.
+    
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+
+diff --git a/bitfield.h b/bitfield.h
+index c7dfeb1..fccbb36 100644
+--- a/bitfield.h
++++ b/bitfield.h
+@@ -35,6 +35,7 @@ struct numfield {
+ };
+ 
+ #define FIELD(start_bit, name) { start_bit, name, ARRAY_SIZE(name) }
++#define FIELD_NULL(start_bit) { start_bit, NULL, 0 }
+ #define SBITFIELD(start_bit, string) { start_bit, ((char * [2]) { NULL, string }), 2 }
+ 
+ #define NUMBER(start, end, name) { start, end, name, "%Lu", 0 }
+diff --git a/mce-intel-dunnington.c b/mce-intel-dunnington.c
+index 4b1c7e3..c695c62 100644
+--- a/mce-intel-dunnington.c
++++ b/mce-intel-dunnington.c
+@@ -27,14 +27,14 @@
+ 
+ static struct field dunnington_bus_status[] = {
+ 	SBITFIELD(16, "Parity error detected during FSB request phase"),
+-	FIELD(17, NULL),
++	FIELD_NULL(17),
+ 	SBITFIELD(20, "Hard Failure response received for a local transaction"),
+ 	SBITFIELD(21, "Parity error on FSB response field detected"),
+ 	SBITFIELD(22, "Parity data error on inbound data detected"),
+-	FIELD(23, NULL),
+-	FIELD(25, NULL),
+-	FIELD(28, NULL),
+-	FIELD(31, NULL),
++	FIELD_NULL(23),
++	FIELD_NULL(25),
++	FIELD_NULL(28),
++	FIELD_NULL(31),
+ 	{}
+ };
+ 
+diff --git a/mce-intel-p4-p6.c b/mce-intel-p4-p6.c
+index 4615e1a..5c6c3ff 100644
+--- a/mce-intel-p4-p6.c
++++ b/mce-intel-p4-p6.c
+@@ -60,7 +60,7 @@ static char *bus_queue_error_type[] = {
+ };
+ 
+ static struct field p6_shared_status[] = {
+-	FIELD(16, NULL),
++	FIELD_NULL(16),
+ 	FIELD(19, bus_queue_req_type),
+ 	FIELD(25, bus_queue_error_type),
+ 	FIELD(25, bus_queue_error_type),
+@@ -68,7 +68,7 @@ static struct field p6_shared_status[] = {
+ 	SBITFIELD(36, "received parity error on response transaction"),
+ 	SBITFIELD(38, "timeout BINIT (ROB timeout)."
+ 		  " No micro-instruction retired for some time"),
+-	FIELD(39, NULL),
++	FIELD_NULL(39),
+ 	SBITFIELD(42, "bus transaction received hard error response"),
+ 	SBITFIELD(43, "failure that caused IERR"),
+ 	/* The following are reserved for Core in the SDM. Let's keep them here anyways*/
+@@ -76,15 +76,15 @@ static struct field p6_shared_status[] = {
+ 	SBITFIELD(45, "uncorrectable ECC error"),
+ 	SBITFIELD(46, "correctable ECC error"),
+ 	/* [47..54]: ECC syndrome */
+-	FIELD(55, NULL),
++	FIELD_NULL(55),
+ 	{},
+ };
+ 
+ static struct field p6old_status[] = {
+ 	SBITFIELD(28, "FRC error"),
+ 	SBITFIELD(29, "BERR on this CPU"),
+-	FIELD(31, NULL),
+-	FIELD(32, NULL),
++	FIELD_NULL(31),
++	FIELD_NULL(32),
+ 	SBITFIELD(35, "BINIT received from external bus"),
+ 	SBITFIELD(37, "Received hard error reponse on split transaction (Bus BINIT)"),
+ 	{}
+@@ -94,9 +94,9 @@ static struct field core2_status[] = {
+ 	SBITFIELD(28, "MCE driven"),
+ 	SBITFIELD(29, "MCE is observed"),
+ 	SBITFIELD(31, "BINIT observed"),
+-	FIELD(32, NULL),
++	FIELD_NULL(32),
+ 	SBITFIELD(34, "PIC or FSB data parity error"),
+-	FIELD(35, NULL),
++	FIELD_NULL(35),
+ 	SBITFIELD(37, "FSB address parity error detected"),
+ 	{}
+ };
+diff --git a/mce-intel-tulsa.c b/mce-intel-tulsa.c
+index 6cea421..e59bf06 100644
+--- a/mce-intel-tulsa.c
++++ b/mce-intel-tulsa.c
+@@ -39,7 +39,7 @@ static struct field tls_bus_status[] = {
+ 	SBITFIELD(16, "Parity error detected during FSB request phase"),
+ 	SBITFIELD(17, "Partity error detected on Core 0 request's address field"),
+ 	SBITFIELD(18, "Partity error detected on Core 1 request's address field"),
+-	FIELD(19, NULL),
++	FIELD_NULL(19),
+ 	SBITFIELD(20, "Parity error on FSB response field detected"),
+ 	SBITFIELD(21, "FSB data parity error on inbound date detected"),
+ 	SBITFIELD(22, "Data parity error on data received from Core 0 detected"),
+@@ -48,8 +48,8 @@ static struct field tls_bus_status[] = {
+ 	SBITFIELD(25, "Data ECC event to error on inbound data correctable or uncorrectable"),
+ 	SBITFIELD(26, "Pad logic detected a data strobe glitch or sequencing error"),
+ 	SBITFIELD(27, "Pad logic detected a request strobe glitch or sequencing error"),
+-	FIELD(28, NULL),
+-	FIELD(31, NULL),
++	FIELD_NULL(28),
++	FIELD_NULL(31),
+ 	{}
+ };
+ 
diff --git a/SOURCES/aecf33aa70331670c06db6b652712b476e24051c.patch b/SOURCES/aecf33aa70331670c06db6b652712b476e24051c.patch
new file mode 100644
index 0000000..fd557ec
--- /dev/null
+++ b/SOURCES/aecf33aa70331670c06db6b652712b476e24051c.patch
@@ -0,0 +1,107 @@
+commit aecf33aa70331670c06db6b652712b476e24051c
+Author: Muralidhara M K <muralimk@amd.com>
+Date:   Mon Jul 12 05:40:46 2021 -0500
+
+    rasdaemon: Enumerate memory on noncpu nodes
+    
+    On newer heterogeneous systems from AMD with GPU nodes (with HBM2 memory
+    banks) connected via xGMI links to the CPUs.
+    
+    The node id information is available in the InstanceHI[47:44] of
+    the IPID register.
+    
+    The UMC Phys on Aldeberan nodes are enumerated as csrow
+    The UMC channels connected to HBMs are enumerated as ranks.
+    
+    Signed-off-by: Muralidhara M K <muralimk@amd.com>
+    Signed-off-by: Naveen Krishna Chatradhi <nchatrad@amd.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+diff --git a/mce-amd-smca.c b/mce-amd-smca.c
+index 3c346f4..f3379fc 100644
+--- a/mce-amd-smca.c
++++ b/mce-amd-smca.c
+@@ -78,6 +78,12 @@ enum smca_bank_types {
+ /* Maximum number of MCA banks per CPU. */
+ #define MAX_NR_BANKS	64
+ 
++/*
++ * On Newer heterogeneous systems from AMD with CPU and GPU nodes connected
++ * via xGMI links, the NON CPU Nodes are enumerated from index 8
++ */
++#define NONCPU_NODE_INDEX	8
++
+ /* SMCA Extended error strings */
+ /* Load Store */
+ static const char * const smca_ls_mce_desc[] = {
+@@ -531,6 +537,26 @@ static int find_umc_channel(struct mce_event *e)
+ {
+ 	return EXTRACT(e->ipid, 0, 31) >> 20;
+ }
++
++/*
++ * The HBM memory managed by the UMCCH of the noncpu node
++ * can be calculated based on the [15:12]bits of IPID
++ */
++static int find_hbm_channel(struct mce_event *e)
++{
++	int umc, tmp;
++
++	umc = EXTRACT(e->ipid, 0, 31) >> 20;
++
++	/*
++	 * The HBM channel managed by the UMC of the noncpu node
++	 * can be calculated based on the [15:12]bits of IPID as follows
++	 */
++	tmp = ((e->ipid >> 12) & 0xf);
++
++	return (umc % 2) ? tmp + 4 : tmp;
++}
++
+ /* Decode extended errors according to Scalable MCA specification */
+ static void decode_smca_error(struct mce_event *e)
+ {
+@@ -539,6 +565,7 @@ static void decode_smca_error(struct mce_event *e)
+ 	unsigned short xec = (e->status >> 16) & 0x3f;
+ 	const struct smca_hwid *s_hwid;
+ 	uint32_t mcatype_hwid = EXTRACT(e->ipid, 32, 63);
++	uint8_t mcatype_instancehi = EXTRACT(e->ipid, 44, 47);
+ 	unsigned int csrow = -1, channel = -1;
+ 	unsigned int i;
+ 
+@@ -548,14 +575,16 @@ static void decode_smca_error(struct mce_event *e)
+ 			bank_type = s_hwid->bank_type;
+ 			break;
+ 		}
++		if (mcatype_instancehi >= NONCPU_NODE_INDEX)
++			bank_type = SMCA_UMC_V2;
+ 	}
+ 
+-	if (i >= ARRAY_SIZE(smca_hwid_mcatypes)) {
++	if (i >= MAX_NR_BANKS) {
+ 		strcpy(e->mcastatus_msg, "Couldn't find bank type with IPID");
+ 		return;
+ 	}
+ 
+-	if (bank_type >= N_SMCA_BANK_TYPES) {
++	if (bank_type >= MAX_NR_BANKS) {
+ 		strcpy(e->mcastatus_msg, "Don't know how to decode this bank");
+ 		return;
+ 	}
+@@ -580,6 +609,16 @@ static void decode_smca_error(struct mce_event *e)
+ 		mce_snprintf(e->mc_location, "memory_channel=%d,csrow=%d",
+ 			     channel, csrow);
+ 	}
++
++	if (bank_type == SMCA_UMC_V2 && xec == 0) {
++		/* The UMCPHY is reported as csrow in case of noncpu nodes */
++		csrow = find_umc_channel(e) / 2;
++		/* UMCCH is managing the HBM memory */
++		channel = find_hbm_channel(e);
++		mce_snprintf(e->mc_location, "memory_channel=%d,csrow=%d",
++			     channel, csrow);
++	}
++
+ }
+ 
+ int parse_amd_smca_event(struct ras_events *ras, struct mce_event *e)
diff --git a/SOURCES/b497a3d6a39d402c41065e9284d49114b97e3bfe.patch b/SOURCES/b497a3d6a39d402c41065e9284d49114b97e3bfe.patch
new file mode 100644
index 0000000..cbecbdc
--- /dev/null
+++ b/SOURCES/b497a3d6a39d402c41065e9284d49114b97e3bfe.patch
@@ -0,0 +1,148 @@
+commit b497a3d6a39d402c41065e9284d49114b97e3bfe
+Author: Shiju Jose <shiju.jose@huawei.com>
+Date:   Mon Mar 8 16:57:28 2021 +0000
+
+    rasdaemon: ras-mc-ctl: Add memory failure events
+    
+    Add supporting memory failure errors (memory_failure_event)
+    to the ras-mc-ctl tool.
+    
+    Sample Log,
+    ras-mc-ctl --summary
+    ...
+    Memory failure events summary:
+            Delayed errors: 4
+            Failed errors: 1
+    ...
+    
+    ras-mc-ctl --errors
+    ...
+    Memory failure events:
+    1 2020-10-28 23:20:41 -0800 error: pfn=0x204000000, page_type=free buddy page, action_result=Delayed
+    2 2020-10-28 23:31:38 -0800 error: pfn=0x204000000, page_type=free buddy page, action_result=Delayed
+    3 2020-10-28 23:54:54 -0800 error: pfn=0x205000000, page_type=free buddy page, action_result=Delayed
+    4 2020-10-29 00:12:25 -0800 error: pfn=0x204000000, page_type=free buddy page, action_result=Delayed
+    5 2020-10-29 00:26:36 -0800 error: pfn=0x204000000, page_type=free buddy page, action_result=Failed
+    
+    Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+---
+ configure.ac       |   11 +++++++++++
+ util/ras-mc-ctl.in |   46 +++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 54 insertions(+), 3 deletions(-)
+
+--- a/util/ras-mc-ctl.in	2021-10-13 13:51:00.887292563 -0400
++++ b/util/ras-mc-ctl.in	2021-10-13 13:51:27.536061894 -0400
+@@ -44,11 +44,13 @@ my $modprobe    = find_prog ("modprobe")
+ my $has_aer = 0;
+ my $has_arm = 0;
+ my $has_extlog = 0;
++my $has_mem_failure = 0;
+ my $has_mce = 0;
+ 
+ @WITH_AER_TRUE@$has_aer = 1;
+ @WITH_ARM_TRUE@$has_arm = 1;
+ @WITH_EXTLOG_TRUE@$has_extlog = 1;
++@WITH_MEMORY_FAILURE_TRUE@$has_mem_failure = 1;
+ @WITH_MCE_TRUE@$has_mce = 1;
+ 
+ my %conf        = ();
+@@ -1132,7 +1134,7 @@ sub summary
+ {
+     require DBI;
+     my ($query, $query_handle, $out);
+-    my ($err_type, $label, $mc, $top, $mid, $low, $count, $msg);
++    my ($err_type, $label, $mc, $top, $mid, $low, $count, $msg, $action_result);
+     my ($etype, $severity, $etype_string, $severity_string);
+     my ($affinity, $mpidr);
+ 
+@@ -1203,9 +1205,27 @@ sub summary
+             $out .= "\t$count $etype_string $severity_string errors\n";
+         }
+         if ($out ne "") {
+-            print "Extlog records summary:\n$out";
++            print "Extlog records summary:\n$out\n";
+         } else {
+-            print "No Extlog errors.\n";
++            print "No Extlog errors.\n\n";
++        }
++        $query_handle->finish;
++    }
++
++    # Memory failure errors
++    if ($has_mem_failure == 1) {
++        $query = "select action_result, count(*) from memory_failure_event group by action_result";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($action_result, $count));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "\t$action_result errors: $count\n";
++        }
++        if ($out ne "") {
++            print "Memory failure events summary:\n$out\n";
++        } else {
++            print "No Memory failure errors.\n\n";
+         }
+         $query_handle->finish;
+     }
+@@ -1238,6 +1258,7 @@ sub errors
+     my ($mcgcap,$mcgstatus, $status, $misc, $ip, $tsc, $walltime, $cpu, $cpuid, $apicid, $socketid, $cs, $bank, $cpuvendor, $bank_name, $mcgstatus_msg, $mcistatus_msg, $user_action, $mc_location);
+     my ($timestamp, $etype, $severity, $etype_string, $severity_string, $fru_id, $fru_text, $cper_data);
+     my ($error_count, $affinity, $mpidr, $r_state, $psci_state);
++    my ($pfn, $page_type, $action_result);
+ 
+     my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", {});
+ 
+@@ -1329,6 +1350,25 @@ $out .= sprintf "address=0x%08x, ", $add
+         }
+         $query_handle->finish;
+     }
++
++    # Memory failure errors
++    if ($has_mem_failure == 1) {
++        $query = "select id, timestamp, pfn, page_type, action_result from memory_failure_event order by id";
++        $query_handle = $dbh->prepare($query);
++        $query_handle->execute();
++        $query_handle->bind_columns(\($id, $timestamp, $pfn, $page_type, $action_result));
++        $out = "";
++        while($query_handle->fetch()) {
++            $out .= "$id $timestamp error: ";
++            $out .= "pfn=$pfn, page_type=$page_type, action_result=$action_result\n";
++        }
++        if ($out ne "") {
++            print "Memory failure events:\n$out\n";
++        } else {
++            print "No Memory failure errors.\n\n";
++        }
++        $query_handle->finish;
++    }
+ 
+     # MCE mce_record errors
+     if ($has_mce == 1) {
+--- a/configure.ac	2018-04-25 06:28:51.000000000 -0400
++++ b/configure.ac	2021-10-13 13:51:00.916292312 -0400
+@@ -80,6 +80,16 @@ AS_IF([test "x$enable_extlog" = "xyes"],
+ ])
+ AM_CONDITIONAL([WITH_EXTLOG], [test x$enable_extlog = xyes])
+ 
++AC_ARG_ENABLE([memory_failure],
++    AS_HELP_STRING([--enable-memory-failure], [enable memory failure events (currently experimental)]))
++
++AS_IF([test "x$enable_memory_failure" = "xyes" || test "x$enable_all" == "xyes"], [
++  AC_DEFINE(HAVE_MEMORY_FAILURE,1,"have memory failure events collect")
++  AC_SUBST([WITH_MEMORY_FAILURE])
++])
++AM_CONDITIONAL([WITH_MEMORY_FAILURE], [test x$enable_memory_failure = xyes || test x$enable_all == xyes])
++AM_COND_IF([WITH_MEMORY_FAILURE], [USE_MEMORY_FAILURE="yes"], [USE_MEMORY_FAILURE="no"])
++
+ AC_ARG_ENABLE([abrt_report],
+     AS_HELP_STRING([--enable-abrt-report], [enable report event to ABRT (currently experimental)]))
+ 
+@@ -127,4 +137,5 @@ compile time options summary
+     ABRT report         : $enable_abrt_report
+     HIP07 SAS HW errors : $enable_hisi_ns_decode
+     ARM events          : $enable_arm
++    Memory Failure      : $USE_MEMORY_FAILURE
+ EOF
diff --git a/SOURCES/ce6e7864f11f709c4f803828fbc8e507d115d03b.patch b/SOURCES/ce6e7864f11f709c4f803828fbc8e507d115d03b.patch
new file mode 100644
index 0000000..e10c156
--- /dev/null
+++ b/SOURCES/ce6e7864f11f709c4f803828fbc8e507d115d03b.patch
@@ -0,0 +1,611 @@
+commit ce6e7864f11f709c4f803828fbc8e507d115d03b
+Author: Greg Edwards <gedwards@ddn.com>
+Date:   Thu Apr 8 15:03:30 2021 -0600
+
+    rasdaemon: Add Ice Lake and Sapphire Rapids MSCOD values
+    
+    Based on mcelog commits:
+    
+      ee90ff20ce6a ("mcelog: Add support for Icelake server, Icelake-D, and Snow Ridge")
+      391abaac9bdf ("mcelog: Add decode for MCi_MISC from 10nm memory controller")
+      59cb7ad4bc72 ("mcelog: i10nm: Fix mapping from bank number to functional unit")
+      c0acd0e6a639 ("mcelog: Add support for Sapphirerapids server.")
+    
+    Signed-off-by: Greg Edwards <gedwards@ddn.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+---
+ Makefile.am       |    3 
+ mce-intel-i10nm.c |  509 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ mce-intel.c       |    5 
+ ras-mce-handler.c |   12 +
+ ras-mce-handler.h |    5 
+ 5 files changed, 533 insertions(+), 1 deletion(-)
+
+--- rasdaemon-0.6.1.orig/Makefile.am	2021-09-17 15:29:45.977790658 -0400
++++ rasdaemon-0.6.1/Makefile.am	2021-09-17 15:29:57.439698580 -0400
+@@ -36,7 +36,8 @@ if WITH_MCE
+ 			mce-intel-dunnington.c mce-intel-tulsa.c \
+ 			mce-intel-sb.c mce-intel-ivb.c mce-intel-haswell.c \
+ 			mce-intel-knl.c mce-intel-broadwell-de.c \
+-			mce-intel-broadwell-epex.c mce-intel-skylake-xeon.c
++			mce-intel-broadwell-epex.c mce-intel-skylake-xeon.c \
++			mce-amd.c mce-amd-smca.c mce-intel-i10nm.c
+ endif
+ if WITH_EXTLOG
+    rasdaemon_SOURCES += ras-extlog-handler.c
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ rasdaemon-0.6.1/mce-intel-i10nm.c	2021-09-17 15:29:45.977790658 -0400
+@@ -0,0 +1,509 @@
++/*
++ * The code below came from Tony Luck's mcelog code,
++ * released under GNU Public General License, v.2
++ *
++ * Copyright (C) 2019 Intel Corporation
++ * Decode Intel 10nm specific machine check errors.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++*/
++
++#include <inttypes.h>
++#include <stdio.h>
++#include <string.h>
++
++#include "ras-mce-handler.h"
++#include "bitfield.h"
++
++static char *pcu_1[] = {
++	[0x0D] = "MCA_LLC_BIST_ACTIVE_TIMEOUT",
++	[0x0E] = "MCA_DMI_TRAINING_TIMEOUT",
++	[0x0F] = "MCA_DMI_STRAP_SET_ARRIVAL_TIMEOUT",
++	[0x10] = "MCA_DMI_CPU_RESET_ACK_TIMEOUT",
++	[0x11] = "MCA_MORE_THAN_ONE_LT_AGENT",
++	[0x14] = "MCA_INCOMPATIBLE_PCH_TYPE",
++	[0x1E] = "MCA_BIOS_RST_CPL_INVALID_SEQ",
++	[0x1F] = "MCA_BIOS_INVALID_PKG_STATE_CONFIG",
++	[0x2D] = "MCA_PCU_PMAX_CALIB_ERROR",
++	[0x2E] = "MCA_TSC100_SYNC_TIMEOUT",
++	[0x3A] = "MCA_GPSB_TIMEOUT",
++	[0x3B] = "MCA_PMSB_TIMEOUT",
++	[0x3E] = "MCA_IOSFSB_PMREQ_CMP_TIMEOUT",
++	[0x40] = "MCA_SVID_VCCIN_VR_ICC_MAX_FAILURE",
++	[0x42] = "MCA_SVID_VCCIN_VR_VOUT_FAILURE",
++	[0x43] = "MCA_SVID_CPU_VR_CAPABILITY_ERROR",
++	[0x44] = "MCA_SVID_CRITICAL_VR_FAILED",
++	[0x45] = "MCA_SVID_SA_ITD_ERROR",
++	[0x46] = "MCA_SVID_READ_REG_FAILED",
++	[0x47] = "MCA_SVID_WRITE_REG_FAILED",
++	[0x4A] = "MCA_SVID_PKGC_REQUEST_FAILED",
++	[0x4B] = "MCA_SVID_IMON_REQUEST_FAILED",
++	[0x4C] = "MCA_SVID_ALERT_REQUEST_FAILED",
++	[0x4D] = "MCA_SVID_MCP_VR_RAMP_ERROR",
++	[0x56] = "MCA_FIVR_PD_HARDERR",
++	[0x58] = "MCA_WATCHDOG_TIMEOUT_PKGC_SLAVE",
++	[0x59] = "MCA_WATCHDOG_TIMEOUT_PKGC_MASTER",
++	[0x5A] = "MCA_WATCHDOG_TIMEOUT_PKGS_MASTER",
++	[0x5B] = "MCA_WATCHDOG_TIMEOUT_MSG_CH_FSM",
++	[0x5C] = "MCA_WATCHDOG_TIMEOUT_BULK_CR_FSM",
++	[0x5D] = "MCA_WATCHDOG_TIMEOUT_IOSFSB_FSM",
++	[0x60] = "MCA_PKGS_SAFE_WP_TIMEOUT",
++	[0x61] = "MCA_PKGS_CPD_UNCPD_TIMEOUT",
++	[0x62] = "MCA_PKGS_INVALID_REQ_PCH",
++	[0x63] = "MCA_PKGS_INVALID_REQ_INTERNAL",
++	[0x64] = "MCA_PKGS_INVALID_RSP_INTERNAL",
++	[0x65 ... 0x7A] = "MCA_PKGS_RESET_PREP_TIMEOUT",
++	[0x7B] = "MCA_PKGS_SMBUS_VPP_PAUSE_TIMEOUT",
++	[0x7C] = "MCA_PKGS_SMBUS_MCP_PAUSE_TIMEOUT",
++	[0x7D] = "MCA_PKGS_SMBUS_SPD_PAUSE_TIMEOUT",
++	[0x80] = "MCA_PKGC_DISP_BUSY_TIMEOUT",
++	[0x81] = "MCA_PKGC_INVALID_RSP_PCH",
++	[0x83] = "MCA_PKGC_WATCHDOG_HANG_CBZ_DOWN",
++	[0x84] = "MCA_PKGC_WATCHDOG_HANG_CBZ_UP",
++	[0x87] = "MCA_PKGC_WATCHDOG_HANG_C2_BLKMASTER",
++	[0x88] = "MCA_PKGC_WATCHDOG_HANG_C2_PSLIMIT",
++	[0x89] = "MCA_PKGC_WATCHDOG_HANG_SETDISP",
++	[0x8B] = "MCA_PKGC_ALLOW_L1_ERROR",
++	[0x90] = "MCA_RECOVERABLE_DIE_THERMAL_TOO_HOT",
++	[0xA0] = "MCA_ADR_SIGNAL_TIMEOUT",
++	[0xA1] = "MCA_BCLK_FREQ_OC_ABOVE_THRESHOLD",
++	[0xB0] = "MCA_DISPATCHER_RUN_BUSY_TIMEOUT",
++};
++
++static char *pcu_2[] = {
++	[0x04] = "Clock/power IP response timeout",
++	[0x05] = "SMBus controller raised SMI",
++	[0x09] = "PM controller received invalid transaction",
++};
++
++static char *pcu_3[] = {
++	[0x01] = "Instruction address out of valid space",
++	[0x02] = "Double bit RAM error on Instruction Fetch",
++	[0x03] = "Invalid OpCode seen",
++	[0x04] = "Stack Underflow",
++	[0x05] = "Stack Overflow",
++	[0x06] = "Data address out of valid space",
++	[0x07] = "Double bit RAM error on Data Fetch",
++};
++
++static struct field pcu1[] = {
++	FIELD(0, pcu_1),
++	{}
++};
++
++static struct field pcu2[] = {
++	FIELD(0, pcu_2),
++	{}
++};
++
++static struct field pcu3[] = {
++	FIELD(0, pcu_3),
++	{}
++};
++
++static struct field upi1[] = {
++	SBITFIELD(22, "Phy Control Error"),
++	SBITFIELD(23, "Unexpected Retry.Ack flit"),
++	SBITFIELD(24, "Unexpected Retry.Req flit"),
++	SBITFIELD(25, "RF parity error"),
++	SBITFIELD(26, "Routeback Table error"),
++	SBITFIELD(27, "Unexpected Tx Protocol flit (EOP, Header or Data)"),
++	SBITFIELD(28, "Rx Header-or-Credit BGF credit overflow/underflow"),
++	SBITFIELD(29, "Link Layer Reset still in progress when Phy enters L0"),
++	SBITFIELD(30, "Link Layer reset initiated while protocol traffic not idle"),
++	SBITFIELD(31, "Link Layer Tx Parity Error"),
++	{}
++};
++
++static char *upi_2[] = {
++	[0x00] = "Phy Initialization Failure (NumInit)",
++	[0x01] = "Phy Detected Drift Buffer Alarm",
++	[0x02] = "Phy Detected Latency Buffer Rollover",
++	[0x10] = "LL Rx detected CRC error: unsuccessful LLR (entered Abort state)",
++	[0x11] = "LL Rx Unsupported/Undefined packet",
++	[0x12] = "LL or Phy Control Error",
++	[0x13] = "LL Rx Parameter Exception",
++	[0x1F] = "LL Detected Control Error",
++	[0x20] = "Phy Initialization Abort",
++	[0x21] = "Phy Inband Reset",
++	[0x22] = "Phy Lane failure, recovery in x8 width",
++	[0x23] = "Phy L0c error corrected without Phy reset",
++	[0x24] = "Phy L0c error triggering Phy reset",
++	[0x25] = "Phy L0p exit error corrected with reset",
++	[0x30] = "LL Rx detected CRC error: successful LLR without Phy Reinit",
++	[0x31] = "LL Rx detected CRC error: successful LLR with Phy Reinit",
++	[0x32] = "Tx received LLR",
++};
++
++static struct field upi2[] = {
++	FIELD(0, upi_2),
++	{}
++};
++
++static struct field m2m[] = {
++	SBITFIELD(16, "MC read data error"),
++	SBITFIELD(17, "Reserved"),
++	SBITFIELD(18, "MC partial write data error"),
++	SBITFIELD(19, "Full write data error"),
++	SBITFIELD(20, "M2M clock-domain-crossing buffer (BGF) error"),
++	SBITFIELD(21, "M2M time out"),
++	SBITFIELD(22, "M2M tracker parity error"),
++	SBITFIELD(23, "fatal Bucket1 error"),
++	{}
++};
++
++static char *imc_0[] = {
++	[0x01] = "Address parity error",
++	[0x02] = "Data parity error",
++	[0x03] = "Data ECC error",
++	[0x04] = "Data byte enable parity error",
++	[0x07] = "Transaction ID parity error",
++	[0x08] = "Corrected patrol scrub error",
++	[0x10] = "Uncorrected patrol scrub error",
++	[0x20] = "Corrected spare error",
++	[0x40] = "Uncorrected spare error",
++	[0x80] = "Corrected read error",
++	[0xA0] = "Uncorrected read error",
++	[0xC0] = "Uncorrected metadata",
++};
++
++static char *imc_1[] = {
++	[0x00] = "WDB read parity error",
++	[0x03] = "RPA parity error",
++	[0x06] = "DDR_T_DPPP data BE error",
++	[0x07] = "DDR_T_DPPP data error",
++	[0x08] = "DDR link failure",
++	[0x11] = "PCLS CAM error",
++	[0x12] = "PCLS data error",
++};
++
++static char *imc_2[] = {
++	[0x00] = "DDR4 command / address parity error",
++	[0x20] = "HBM command / address parity error",
++	[0x21] = "HBM data parity error",
++};
++
++static char *imc_4[] = {
++	[0x00] = "RPQ parity (primary) error",
++};
++
++static char *imc_8[] = {
++	[0x00] = "DDR-T bad request",
++	[0x01] = "DDR Data response to an invalid entry",
++	[0x02] = "DDR data response to an entry not expecting data",
++	[0x03] = "DDR4 completion to an invalid entry",
++	[0x04] = "DDR-T completion to an invalid entry",
++	[0x05] = "DDR data/completion FIFO overflow",
++	[0x06] = "DDR-T ERID correctable parity error",
++	[0x07] = "DDR-T ERID uncorrectable error",
++	[0x08] = "DDR-T interrupt received while outstanding interrupt was not ACKed",
++	[0x09] = "ERID FI FO overflow",
++	[0x0A] = "DDR-T error on FNV write credits",
++	[0x0B] = "DDR-T error on FNV read credits",
++	[0x0C] = "DDR-T scheduler error",
++	[0x0D] = "DDR-T FNV error event",
++	[0x0E] = "DDR-T FNV thermal event",
++	[0x0F] = "CMI packet while idle",
++	[0x10] = "DDR_T_RPQ_REQ_PARITY_ERR",
++	[0x11] = "DDR_T_WPQ_REQ_PARITY_ERR",
++	[0x12] = "2LM_NMFILLWR_CAM_ERR",
++	[0x13] = "CMI_CREDIT_OVERSUB_ERR",
++	[0x14] = "CMI_CREDIT_TOTAL_ERR",
++	[0x15] = "CMI_CREDIT_RSVD_POOL_ERR",
++	[0x16] = "DDR_T_RD_ERROR",
++	[0x17] = "WDB_FIFO_ERR",
++	[0x18] = "CMI_REQ_FIFO_OVERFLOW",
++	[0x19] = "CMI_REQ_FIFO_UNDERFLOW",
++	[0x1A] = "CMI_RSP_FIFO_OVERFLOW",
++	[0x1B] = "CMI_RSP_FIFO_UNDERFLOW",
++	[0x1C] = "CMI _MISC_MC_CRDT_ERRORS",
++	[0x1D] = "CMI_MISC_MC_ARB_ERRORS",
++	[0x1E] = "DDR_T_WR_CMPL_FI FO_OVERFLOW",
++	[0x1F] = "DDR_T_WR_CMPL_FI FO_UNDERFLOW",
++	[0x20] = "CMI_RD_CPL_FIFO_OVERFLOW",
++	[0x21] = "CMI_RD_CPL_FIFO_UNDERFLOW",
++	[0x22] = "TME_KEY_PAR_ERR",
++	[0x23] = "TME_CMI_MISC_ERR",
++	[0x24] = "TME_CMI_OVFL_ERR",
++	[0x25] = "TME_CMI_UFL_ERR",
++	[0x26] = "TME_TEM_SECURE_ERR",
++	[0x27] = "TME_UFILL_PAR_ERR",
++	[0x29] = "INTERNAL_ERR",
++	[0x2A] = "TME_INTEGRITY_ERR",
++	[0x2B] = "TME_TDX_ERR",
++	[0x2C] = "TME_UFILL_TEM_SECURE_ERR",
++	[0x2D] = "TME_KEY_POISON_ERR",
++	[0x2E] = "TME_SECURITY_ENGINE_ERR",
++};
++
++static char *imc_10[] = {
++	[0x08] = "CORR_PATSCRUB_MIRR2ND_ERR",
++	[0x10] = "UC_PATSCRUB_MIRR2ND_ERR",
++	[0x20] = "COR_SPARE_MIRR2ND_ERR",
++	[0x40] = "UC_SPARE_MIRR2ND_ERR",
++	[0x80] = "HA_RD_MIRR2ND_ERR",
++	[0xA0] = "HA_UNCORR_RD_MIRR2ND_ERR",
++};
++
++static struct field imc0[] = {
++	FIELD(0, imc_0),
++	{}
++};
++
++static struct field imc1[] = {
++	FIELD(0, imc_1),
++	{}
++};
++
++static struct field imc2[] = {
++	FIELD(0, imc_2),
++	{}
++};
++
++static struct field imc4[] = {
++	FIELD(0, imc_4),
++	{}
++};
++
++static struct field imc8[] = {
++	FIELD(0, imc_8),
++	{}
++};
++
++static struct field imc10[] = {
++	FIELD(0, imc_10),
++	{}
++};
++
++static void i10nm_imc_misc(struct mce_event *e)
++{
++	uint32_t column = EXTRACT(e->misc, 9, 18) << 2;
++	uint32_t row = EXTRACT(e->misc, 19, 39);
++	uint32_t bank = EXTRACT(e->misc, 42, 43);
++	uint32_t bankgroup = EXTRACT(e->misc, 40, 41) | (EXTRACT(e->misc, 44, 44) << 2);
++	uint32_t fdevice = EXTRACT(e->misc, 46, 51);
++	uint32_t subrank = EXTRACT(e->misc, 52, 55);
++	uint32_t rank = EXTRACT(e->misc, 56, 58);
++	uint32_t eccmode = EXTRACT(e->misc, 59, 62);
++	uint32_t transient = EXTRACT(e->misc, 63, 63);
++
++	mce_snprintf(e->error_msg, "bank: 0x%x bankgroup: 0x%x row: 0x%x column: 0x%x", bank, bankgroup, row, column);
++	if (!transient && !EXTRACT(e->status, 61, 61))
++		mce_snprintf(e->error_msg, "failed device: 0x%x", fdevice);
++	mce_snprintf(e->error_msg, "rank: 0x%x subrank: 0x%x", rank, subrank);
++	mce_snprintf(e->error_msg, "ecc mode: ");
++	switch (eccmode) {
++	case 0: mce_snprintf(e->error_msg, "SDDC memory mode"); break;
++	case 1: mce_snprintf(e->error_msg, "SDDC"); break;
++	case 4: mce_snprintf(e->error_msg, "ADDDC memory mode"); break;
++	case 5: mce_snprintf(e->error_msg, "ADDDC"); break;
++	case 8: mce_snprintf(e->error_msg, "DDRT read"); break;
++	default: mce_snprintf(e->error_msg, "unknown"); break;
++	}
++	if (transient)
++		mce_snprintf(e->error_msg, "transient");
++}
++
++enum banktype {
++	BT_UNKNOWN,
++	BT_PCU,
++	BT_UPI,
++	BT_M2M,
++	BT_IMC,
++};
++
++static enum banktype icelake[32] = {
++	[4]		= BT_PCU,
++	[5]		= BT_UPI,
++	[7 ... 8]	= BT_UPI,
++	[12]		= BT_M2M,
++	[16]		= BT_M2M,
++	[20]		= BT_M2M,
++	[24]		= BT_M2M,
++	[13 ... 15]	= BT_IMC,
++	[17 ... 19]	= BT_IMC,
++	[21 ... 23]	= BT_IMC,
++	[25 ... 27]	= BT_IMC,
++};
++
++static enum banktype icelake_de[32] = {
++	[4]		= BT_PCU,
++	[12]		= BT_M2M,
++	[16]		= BT_M2M,
++	[13 ... 15]	= BT_IMC,
++	[17 ... 19]	= BT_IMC,
++};
++
++static enum banktype tremont[32] = {
++	[4]		= BT_PCU,
++	[12]		= BT_M2M,
++	[13 ... 15]	= BT_IMC,
++};
++
++static enum banktype sapphire[32] = {
++	[4]		= BT_PCU,
++	[5]		= BT_UPI,
++	[12]		= BT_M2M,
++	[13 ... 20]	= BT_IMC,
++};
++
++void i10nm_memerr_misc(struct mce_event *e, int *channel);
++
++void i10nm_decode_model(enum cputype cputype, struct ras_events *ras,
++			struct mce_event *e)
++{
++	enum banktype banktype;
++	uint64_t f, status = e->status;
++	uint32_t mca = status & 0xffff;
++	int channel = -1;
++
++	switch (cputype) {
++	case CPU_ICELAKE_XEON:
++		banktype = icelake[e->bank];
++		break;
++	case CPU_ICELAKE_DE:
++		banktype = icelake_de[e->bank];
++		break;
++	case CPU_TREMONT_D:
++		banktype = tremont[e->bank];
++		break;
++	case CPU_SAPPHIRERAPIDS:
++		banktype = sapphire[e->bank];
++		break;
++	default:
++		return;
++	}
++
++	switch (banktype) {
++	case BT_UNKNOWN:
++		break;
++
++	case BT_PCU:
++		mce_snprintf(e->error_msg, "PCU: ");
++		f = EXTRACT(status, 24, 31);
++		if (f)
++			decode_bitfield(e, f, pcu1);
++		f = EXTRACT(status, 20, 23);
++		if (f)
++			decode_bitfield(e, f, pcu2);
++		f = EXTRACT(status, 16, 19);
++		if (f)
++			decode_bitfield(e, f, pcu3);
++		break;
++
++	case BT_UPI:
++		mce_snprintf(e->error_msg, "UPI: ");
++		f = EXTRACT(status, 22, 31);
++		if (f)
++			decode_bitfield(e, status, upi1);
++		f = EXTRACT(status, 16, 21);
++		decode_bitfield(e, f, upi2);
++		break;
++
++	case BT_M2M:
++		mce_snprintf(e->error_msg, "M2M: ");
++		f = EXTRACT(status, 24, 25);
++		mce_snprintf(e->error_msg, "MscodDDRType=0x%" PRIx64, f);
++		f = EXTRACT(status, 26, 31);
++		mce_snprintf(e->error_msg, "MscodMiscErrs=0x%" PRIx64, f);
++		decode_bitfield(e, status, m2m);
++		break;
++
++	case BT_IMC:
++		mce_snprintf(e->error_msg, "MemCtrl: ");
++		f = EXTRACT(status, 16, 23);
++		switch (EXTRACT(status, 24, 31)) {
++		case 0: decode_bitfield(e, f, imc0); break;
++		case 1: decode_bitfield(e, f, imc1); break;
++		case 2: decode_bitfield(e, f, imc2); break;
++		case 4: decode_bitfield(e, f, imc4); break;
++		case 8: decode_bitfield(e, f, imc8); break;
++		case 0x10: decode_bitfield(e, f, imc10); break;
++		}
++		i10nm_imc_misc(e);
++		break;
++	}
++
++	/*
++	 * Memory error specific code. Returns if the error is not a MC one
++	 */
++
++	/* Check if the error is at the memory controller */
++	if ((mca >> 7) != 1)
++		return;
++
++	/* Ignore unless this is an corrected extended error from an iMC bank */
++	if (banktype != BT_IMC || (status & MCI_STATUS_UC))
++		return;
++
++	/*
++	 * Parse the reported channel
++	 */
++
++	i10nm_memerr_misc(e, &channel);
++	if (channel == -1)
++		return;
++	mce_snprintf(e->mc_location, "memory_channel=%d", channel);
++}
++
++/*
++ * There isn't enough information to identify the DIMM. But
++ * we can derive the channel from the bank number.
++ * There can be four memory controllers with two channels each.
++ */
++void i10nm_memerr_misc(struct mce_event *e, int *channel)
++{
++	uint64_t status = e->status;
++	unsigned int chan, imc;
++
++	/* Check this is a memory error */
++	if (!test_prefix(7, status & 0xefff))
++		return;
++
++	chan = EXTRACT(status, 0, 3);
++	if (chan == 0xf)
++		return;
++
++	switch (e->bank) {
++	case 12: /* M2M 0 */
++	case 13: /* IMC 0, Channel 0 */
++	case 14: /* IMC 0, Channel 1 */
++	case 15: /* IMC 0, Channel 2 */
++		imc = 0;
++		break;
++	case 16: /* M2M 1 */
++	case 17: /* IMC 1, Channel 0 */
++	case 18: /* IMC 1, Channel 1 */
++	case 19: /* IMC 1, Channel 2 */
++		imc = 1;
++		break;
++	case 20: /* M2M 2 */
++	case 21: /* IMC 2, Channel 0 */
++	case 22: /* IMC 2, Channel 1 */
++	case 23: /* IMC 2, Channel 2 */
++		imc = 2;
++		break;
++	case 24: /* M2M 3 */
++	case 25: /* IMC 3, Channel 0 */
++	case 26: /* IMC 3, Channel 1 */
++	case 27: /* IMC 3, Channel 2 */
++		imc = 3;
++		break;
++	default:
++		return;
++	}
++
++	channel[0] = imc * 3 + chan;
++}
+--- rasdaemon-0.6.1.orig/mce-intel.c	2021-09-17 15:29:39.189845188 -0400
++++ rasdaemon-0.6.1/mce-intel.c	2021-09-17 15:29:45.977790658 -0400
+@@ -411,6 +411,11 @@ if (test_prefix(11, (e->status & 0xffffL
+ 	case CPU_SKYLAKE_XEON:
+ 		skylake_s_decode_model(ras, e);
+ 		break;
++	case CPU_ICELAKE_XEON:
++	case CPU_ICELAKE_DE:
++	case CPU_TREMONT_D:
++	case CPU_SAPPHIRERAPIDS:
++		i10nm_decode_model(mce->cputype, ras, e);
+ 	default:
+ 		break;
+ 	}
+--- rasdaemon-0.6.1.orig/ras-mce-handler.c	2021-09-17 15:29:39.189845188 -0400
++++ rasdaemon-0.6.1/ras-mce-handler.c	2021-09-17 15:29:45.977790658 -0400
+@@ -56,6 +56,10 @@ [CPU_XEON75XX] = "Intel Xeon 7500 series
+ 	[CPU_KNIGHTS_MILL] = "Knights Mill",
+ 	[CPU_SKYLAKE_XEON] = "Skylake server",
+ 	[CPU_AMD_SMCA] = "AMD Scalable MCA",
++	[CPU_ICELAKE_XEON] = "Icelake server",
++	[CPU_ICELAKE_DE] = "Icelake server D Family",
++	[CPU_TREMONT_D] = "Tremont microserver",
++	[CPU_SAPPHIRERAPIDS] = "Sapphirerapids server",
+ };
+ 
+ static enum cputype select_intel_cputype(struct ras_events *ras)
+@@ -107,6 +111,14 @@ else if (mce->model == 0x85)
+ 			return CPU_KNIGHTS_MILL;
+ 		else if (mce->model == 0x55)
+ 			return CPU_SKYLAKE_XEON;
++		else if (mce->model == 0x6a)
++			return CPU_ICELAKE_XEON;
++		else if (mce->model == 0x6c)
++                        return CPU_ICELAKE_DE;
++		else if (mce->model == 0x86)
++                        return CPU_TREMONT_D;
++		else if (mce->model == 0x8f)
++                        return CPU_SAPPHIRERAPIDS;
+ 
+ 		if (mce->model > 0x1a) {
+ 			log(ALL, LOG_INFO,
+--- rasdaemon-0.6.1.orig/ras-mce-handler.h	2021-09-17 15:29:39.189845188 -0400
++++ rasdaemon-0.6.1/ras-mce-handler.h	2021-09-17 15:29:45.977790658 -0400
+@@ -51,6 +51,10 @@ enum cputype {
+ 	CPU_KNIGHTS_MILL,
+ 	CPU_SKYLAKE_XEON,
+ 	CPU_AMD_SMCA,
++	CPU_ICELAKE_XEON,
++	CPU_ICELAKE_DE,
++	CPU_TREMONT_D,
++	CPU_SAPPHIRERAPIDS,
+ };
+ 
+ struct mce_event {
+@@ -131,6 +135,7 @@ void tulsa_decode_model(struct mce_event
+ void broadwell_de_decode_model(struct ras_events *ras, struct mce_event *e);
+ void broadwell_epex_decode_model(struct ras_events *ras, struct mce_event *e);
+ void skylake_s_decode_model(struct ras_events *ras, struct mce_event *e);
++void i10nm_decode_model(enum cputype cputype, struct ras_events *ras, struct mce_event *e);
+ 
+ /* AMD error code decode function */
+ void decode_amd_errcode(struct mce_event *e);
diff --git a/SOURCES/rasdaemon-ras-mc-ctl-Fix-script-to-parse-dimm-sizes.patch b/SOURCES/rasdaemon-ras-mc-ctl-Fix-script-to-parse-dimm-sizes.patch
new file mode 100644
index 0000000..c4517a4
--- /dev/null
+++ b/SOURCES/rasdaemon-ras-mc-ctl-Fix-script-to-parse-dimm-sizes.patch
@@ -0,0 +1,47 @@
+From: Muralidhara M K <muralimk@amd.com>
+
+This patch removes trailing spaces at the end of a line from
+file location and fixes --layout option to parse dimm nodes
+to get the size from ras-mc-ctl.
+
+Issue is reported https://github.com/mchehab/rasdaemon/issues/43
+Where '> ras-mc-ctl --layout' reports all 0s
+
+With this change the layout prints the correct dimm sizes
+> sudo ras-mc-ctl --layout
+          +-----------------------------------------------+
+          |                      mc0                      |
+          |  csrow0   |  csrow1   |  csrow2   |  csrow3   |
+----------+-----------------------------------------------+
+...
+channel7: |  16384 MB  |     0 MB  |     0 MB  |     0 MB |
+channel6: |  16384 MB  |     0 MB  |     0 MB  |     0 MB |
+...
+----------+-----------------------------------------------+
+
+Signed-off-by: Muralidhara M K <muralimk@amd.com>
+Signed-off-by: Naveen Krishna Chatradhi <nchatrad@amd.com>
+---
+ util/ras-mc-ctl.in | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in
+index 1e3aeb7..b22dd60 100755
+--- a/util/ras-mc-ctl.in
++++ b/util/ras-mc-ctl.in
+@@ -246,6 +246,7 @@ sub parse_dimm_nodes
+     if (($file =~ /max_location$/)) {
+         open IN, $file;
+         my $location = <IN>;
++        $location =~ s/\s+$//;
+         close IN;
+         my @temp = split(/ /, $location);
+ 
+@@ -288,6 +289,7 @@ sub parse_dimm_nodes
+ 
+         open IN, $file;
+         my $location = <IN>;
++        $location =~ s/\s+$//;
+         close IN;
+ 
+         my @pos;
diff --git a/SPECS/rasdaemon.spec b/SPECS/rasdaemon.spec
index 3c21a31..d4cf19d 100644
--- a/SPECS/rasdaemon.spec
+++ b/SPECS/rasdaemon.spec
@@ -1,6 +1,6 @@
 Name:			rasdaemon
 Version:		0.6.1
-Release:		5.1%{?dist}
+Release:		12%{?dist}
 Summary:		Utility to receive RAS error tracings
 Group:			Applications/System
 License:		GPLv2
@@ -12,6 +12,7 @@ BuildRequires:		gettext-devel
 BuildRequires:		perl-generators
 BuildRequires:		sqlite-devel
 BuildRequires:		systemd
+BuildRequires:		libtool
 Provides:		bundled(kernel-event-lib)
 Requires:		hwdata
 Requires:		perl-DBD-SQLite
@@ -31,6 +32,18 @@ Patch5: 2a1d217660351c08eb2f8bccebf939abba2f7e69.patch
 Patch6: 8704a85d8dc3483423ec2934fee8132f85f8fdb6.patch
 Patch7: cc2ce5c65ed5a42eaa97aa3659854add6d808da5.patch
 Patch8: 854364ba44aee9bc5646f6537fc744b0b54aff37.patch
+Patch9: 9acef39f13833f7d53ef96abc5a72e79384260f4.patch
+Patch10: 28ea956acc2dab7c18b4701f9657afb9ab3ddc79.patch
+Patch11: aecf33aa70331670c06db6b652712b476e24051c.patch
+Patch12: 7937f0d6c2aaaed096f3a3d306416743c0dcb7a4.patch
+Patch13: rasdaemon-ras-mc-ctl-Fix-script-to-parse-dimm-sizes.patch
+Patch14: 0862a096c3a1d0f993703ab3299f1ddfadf53d7f.patch
+Patch15: 546cf713f667437fb6e283cc3dc090679eb47d08.patch
+Patch16: 2290d65b97311dd5736838f1e285355f7f357046.patch
+Patch17: 16d929b024c31d54a7f8a72eab094376c7be27f5.patch
+Patch18: b497a3d6a39d402c41065e9284d49114b97e3bfe.patch
+Patch19: ce6e7864f11f709c4f803828fbc8e507d115d03b.patch
+Patch20: a8c776ed94f68ae31d7b5f74e19545698898c13c.patch
 
 %description
 %{name} is a RAS (Reliability, Availability and Serviceability) logging tool.
@@ -52,12 +65,28 @@ an utility for reporting current error counts from the EDAC sysfs files.
 %patch6 -p1
 %patch7 -p1
 %patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+
+# The tarball is locked in time the first time aclocal was ran and will keep
+# requiring an older version of automake
+autoreconf -vfi
 
 %build
 %ifarch %{arm} aarch64
-%configure --enable-mce --enable-aer --enable-sqlite3 --enable-extlog --enable-abrt-report --enable-non-standard --enable-hisi-ns-decode --enable-arm
+%configure --enable-aer --enable-sqlite3 --enable-abrt-report --enable-non-standard --enable-hisi-ns-decode --enable-arm
 %else
-%configure --enable-mce --enable-aer --enable-sqlite3 --enable-extlog --enable-abrt-report
+%configure --enable-mce --enable-aer --enable-sqlite3 --enable-extlog --enable-abrt-report --enable-memory-failure
 %endif
 make %{?_smp_mflags}
 
@@ -78,8 +107,26 @@ rm INSTALL %{buildroot}/usr/include/*.h
 %{_sysconfdir}/ras/dimm_labels.d
 
 %changelog
-* Wed May 26 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-5.1
-- Add support for AMD SMCA [1975506]
+* Tue Oct 12 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-12
+- Adding missing bits from b497a3d6a39d402c41065e9284d49114b97e3bfe [1923254]
+
+* Tue Oct 12 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-11
+- Removed bits from devlink and diskerrors that aren't used yet [1923254]
+
+* Tue Oct 12 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-10
+- Add miscellaneous patches required by customer [1923254]
+
+* Wed Oct 06 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-9
+- Prevent ras-mc-ctl trying to access extlog and mce tables if rasdaemon was built without support for them [2011404]
+
+* Thu Aug 26 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-8
+- Disable MCE and extlog in arm packages [2009499]
+
+* Thu Aug 26 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-7
+- Add support for AMD SMCA banks for family 19 [1991955]
+
+* Wed May 26 2021 Aristeu Rozanski <aris@redhat.com> 0.6.1-6
+- Add support for AMD SMCA [1965011]
 
 * Wed Apr 08 2020 Aristeu Rozanski <aris@redhat.com> 0.6.1-5
 - Fix high CPU usage when CPUs are offline [1683420]
@@ -178,4 +225,3 @@ rm INSTALL %{buildroot}/usr/include/*.h
 
 * Mon May 20 2013 Mauro Carvalho Chehab <mchehab@redhat.com> 0.3.0-1
 - Package created
-