diff --git a/SOURCES/0065-rasdaemon-Update-DIMM-labels-for-Dell-Servers.patch b/SOURCES/0065-rasdaemon-Update-DIMM-labels-for-Dell-Servers.patch new file mode 100644 index 0000000..4c08707 --- /dev/null +++ b/SOURCES/0065-rasdaemon-Update-DIMM-labels-for-Dell-Servers.patch @@ -0,0 +1,142 @@ +--- + labels/dell | 96 +++++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 56 insertions(+), 40 deletions(-) + +--- rasdaemon-0.4.1.orig/labels/dell 2017-08-23 16:14:36.086652150 -0400 ++++ rasdaemon-0.4.1/labels/dell 2017-08-23 16:16:59.091057241 -0400 +@@ -4,23 +4,35 @@ + # labels are found from the silk screen on the motherboard. + # + #Vendor: <vendor-name> ++# Product: <product-name> + # Model: <model-name> + # <label>: <mc>.<top>.<mid>.<low> + # + + Vendor: Dell Inc. +-#### 11G #### ++# 1-socket ++ Product: PowerEdge R220, PowerEdge R330, PowerEdge T330, PowerEdge R230, PowerEdge T130, PowerEdge T30 ++ DIMM_A1: 0.0.0; DIMM_A2: 0.0.1; ++ DIMM_A3: 0.1.0; DIMM_A4: 0.1.1; ++ ++ Product: PowerEdge T110 II, PowerEdge T20 ++ DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; ++ ++ DIMM_B1: 0.0.1; DIMM_B2: 0.1.1; ++ ++ Product: PowerEdge R320, PowerEdge T320 ++ DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; ++ DIMM_A4: 0.0.1; DIMM_A5: 0.1.1; DIMM_A6: 0.2.1; ++ + # 2-socket +-# PowerEdge R610 +- Model: 0K399H, 0F0XJ6 ++ Product: PowerEdge R610 + DIMM_A1: 0.0.0; DIMM_A2: 0.0.1; DIMM_A3: 0.0.2; + DIMM_A4: 0.1.0; DIMM_A5: 0.1.1; DIMM_A6: 0.1.2; + + DIMM_B1: 1.0.0; DIMM_B2: 1.0.1; DIMM_B3: 1.0.2; + DIMM_B4: 1.1.0; DIMM_B5: 1.1.1; DIMM_B6: 1.1.2; + +-# PowerEdge T710 R710 +- Model: 01CTXG, 0N0H4P, 0MD99X, 0N047H, 0PV9DG ++ Product: PowerEdge T710, PowerEdge R710 + DIMM_A3: 0.0.0; DIMM_A2: 0.1.0; DIMM_A1: 0.2.0; + DIMM_A6: 0.0.1; DIMM_A5: 0.1.1; DIMM_A4: 0.2.1; + DIMM_A9: 0.0.2; DIMM_A8: 0.1.2; DIMM_A7: 0.2.2; +@@ -29,27 +41,7 @@ DIMM_B3: 1.0.0; DIMM_B2: 1.1.0; DIMM_B1 + DIMM_B6: 1.0.1; DIMM_B5: 1.1.1; DIMM_B4: 1.2.1; + DIMM_B9: 1.0.2; DIMM_B8: 1.1.2; DIMM_B7: 1.2.2; + +-#### 12/13G #### +-# 1-socket +-# PowerEdge R220 +- Model: 081N4V +- DIMM_A1: 0.0.0; DIMM_A2: 0.0.1; +- DIMM_A3: 0.1.0; DIMM_A4: 0.1.1; +- +-#PowerEdge T110 II, T20 +- Model: 0PC2WT, 0PM2CW, 015TH9, 0MDHN4, 0VD5HY +- DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; +- +- DIMM_B1: 0.0.1; DIMM_B2: 0.1.1; +- +-#PowerEdge R320 T320 +- Model: 0YCV59, 0Y97HY, 07DKYR, 0VJ84C, 07MYHN, 04DMNN, 0W7H8C, 0K20G5, 0V719V, 0FDT3J +- DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; +- DIMM_A4: 0.0.1; DIMM_A5: 0.1.1; DIMM_A6: 0.2.1; +- +-# 2-socket +-# PowerEdge R620/T620 R720/xd R730/xd T630 R730 R630 T620 M620, FC620 +- Model: 0VWT90, 07NDJ2, 0F5XM3, 0PXXHP, 0X3D66, 061P35, 0H5J4J, 00W9X3, 0599V5, 0W9WXC, 0599V5, 0H21J3, 0CNCJW, 02CD1V, 0T5TFW, 0F5XM3, 0G1CNH, 05YV77, 0PDCCX, 093MW8, 0NJVT7 ++ Product: PowerEdge R620, PowerEdge T620, PowerEdge R720xd, PowerEdge R730xd, PowerEdge T630, PowerEdge R730, PowerEdge R630, PowerEdge T620, PowerEdge M620, PowerEdge FC620, PowerEdge M630, PowerEdge FC630 + DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; DIMM_A4: 0.3.0; + DIMM_A5: 0.0.1; DIMM_A6: 0.1.1; DIMM_A7: 0.2.1; DIMM_A8: 0.3.1; + DIMM_A9: 0.0.2; DIMM_A10: 0.1.2; DIMM_A11: 0.2.2; DIMM_A12: 0.3.2; +@@ -58,23 +50,38 @@ DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_ + DIMM_B5: 1.0.1; DIMM_B6: 1.1.1; DIMM_B7: 1.2.1; DIMM_B8: 1.3.1; + DIMM_B9: 1.0.2; DIMM_B10: 1.1.2; DIMM_B11: 1.2.2; DIMM_B12: 1.3.2; + +-# PowerEdge M520 R420 T420 +- Model: 0NRG83, 0DW6GX, 03WPHJ, 06HTRX, 0H1Y24, 02T9N6, 0TT5P2, 0CPKXG, 03015M, 061VPC, 0PC9H0, 0K3G34, 0PC0V5, 08NVYK +- DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; +- DIMM_A4: 0.0.1; DIMM_A5: 0.1.1; DIMM_A6: 0.2.1; +- +- DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_B3: 1.2.0; +- DIMM_B4: 1.0.1; DIMM_B5: 1.1.1; DIMM_B6: 1.2.1; +- +-#PowerEdge FC420, M420 +- Model: 0DPJGD, 068CTP, 0MN3VC, 0417VP +- DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; ++ Product: PowerEdge M520, PowerEdge R420, PowerEdge T420 ++ DIMM_A1: 0.1.0; DIMM_A2: 0.2.0; DIMM_A3: 0.3.0; ++ DIMM_A4: 0.1.1; DIMM_A5: 0.2.1; DIMM_A6: 0.3.1; ++ ++ DIMM_B1: 1.1.0; DIMM_B2: 1.2.0; DIMM_B3: 1.3.0; ++ DIMM_B4: 1.1.1; DIMM_B5: 1.2.1; DIMM_B6: 1.3.1; + +- DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_B3: 1.2.0; ++ Product: PowerEdge FC420, PowerEdge M420 ++ DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; ++ ++ DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_B3: 1.2.0; ++ ++ Product: PowerEdge C6320, PowerEdge C4130 ++ DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; DIMM_A4: 0.3.0; ++ DIMM_A5: 0.0.1; DIMM_A6: 0.1.1; DIMM_A7: 0.2.1; DIMM_A8: 0.3.1; ++ ++ DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_B3: 1.2.0; DIMM_B4: 1.3.0; ++ DIMM_B5: 1.0.1; DIMM_B6: 1.1.1; DIMM_B7: 1.2.1; DIMM_B8: 1.3.1; ++ ++ Product: PowerEdge R430, PowerEdge T430, PowerEdge R530 ++ DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; DIMM_A4: 0.3.0; ++ DIMM_A5: 0.0.1; DIMM_A6: 0.1.1; DIMM_A7: 0.2.1; DIMM_A8: 0.3.1; ++ ++ DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_B3: 1.2.0; DIMM_B4: 1.3.0; ++ ++ Product: PowerEdge FC430 ++ DIMM_A1: 0.1.0; DIMM_A2: 0.0.0; DIMM_A3: 0.2.0; DIMM_A4: 0.3.0; ++ ++ DIMM_B1: 1.1.0; DIMM_B2: 1.0.0; DIMM_B3: 1.2.0; DIMM_B4: 1.3.0; + + # 4-socket +-# # PowerEdge M820 +- Model: 0RN9TC, 0YWR73, 066N7P, 0PFG1N, 0JC2W3 ++ Product: PowerEdge M820, PowerEdge R830, PowerEdge M830, PowerEdge R930, PowerEdge FC830 + DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; DIMM_A4: 0.3.0; + DIMM_A5: 0.0.1; DIMM_A6: 0.1.1; DIMM_A7: 0.2.1; DIMM_A8: 0.3.1; + DIMM_A9: 0.0.2; DIMM_A10: 0.1.2; DIMM_A11: 0.2.2; DIMM_A12: 0.3.2; +@@ -90,3 +97,12 @@ DIMM_C9: 2.0.2; DIMM_C10: 2.1.2; + DIMM_D1: 3.0.0; DIMM_D2: 3.1.0; DIMM_D3: 3.2.0; DIMM_D4: 3.3.0; + DIMM_D5: 3.0.1; DIMM_D6: 3.1.1; DIMM_D7: 3.2.1; DIMM_D8: 3.3.1; + DIMM_D9: 3.0.2; DIMM_D10: 3.1.2; DIMM_D11: 3.2.2; DIMM_D12: 3.3.2; ++ ++ Product: PowerEdge FM120x4 ++ DIMM_A_A1: 0.1.0; DIMM_A_A2: 0.2.0; ++ ++ DIMM_B_A1: 1.1.0; DIMM_B_A2: 1.2.0; ++ ++ DIMM_C_A1: 2.1.0; DIMM_C_A2: 2.2.0; ++ ++ DIMM_D_A1: 3.1.0; DIMM_D_A2: 3.2.0; diff --git a/SOURCES/0066-rasdaemon-Update-DIMM-labels-for-Intel-Skylake-serve.patch b/SOURCES/0066-rasdaemon-Update-DIMM-labels-for-Intel-Skylake-serve.patch new file mode 100644 index 0000000..73a73b5 --- /dev/null +++ b/SOURCES/0066-rasdaemon-Update-DIMM-labels-for-Intel-Skylake-serve.patch @@ -0,0 +1,69 @@ +From 993b8c40bd0c09a177d52c4f41b09ef2c969fa8d Mon Sep 17 00:00:00 2001 +From: "Charles.Rose@dell.com" <Charles.Rose@dell.com> +Date: Fri, 11 Aug 2017 20:09:10 +0000 +Subject: [PATCH] rasdaemon: Update DIMM labels for Intel Skylake servers + +Update labels for Intel Skylake based Dell PowerEdge servers. + +Signed-off-by: Charles Rose <charles_rose@dell.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +--- + labels/dell | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/labels/dell b/labels/dell +index 5abcd90..58455df 100644 +--- a/labels/dell ++++ b/labels/dell +@@ -50,6 +50,13 @@ Vendor: Dell Inc. + DIMM_B5: 1.0.1; DIMM_B6: 1.1.1; DIMM_B7: 1.2.1; DIMM_B8: 1.3.1; + DIMM_B9: 1.0.2; DIMM_B10: 1.1.2; DIMM_B11: 1.2.2; DIMM_B12: 1.3.2; + ++ Product: PowerEdge R640, PowerEdge R740, PowerEdge R740xd ++ A1: 0.0.0; A2: 0.1.0; A3: 0.2.0; A4: 1.0.0; A5: 1.1.0; A6: 1.2.0; ++ A7: 0.0.1; A8: 0.1.1; A9: 0.2.1; A10: 1.0.1; A11: 1.1.1; A12: 1.2.1; ++ ++ B1: 2.0.0; B2: 2.1.0; B3: 2.2.0; B4: 3.0.0; B5: 3.1.0; B6: 3.2.0; ++ B7: 2.0.1; B8: 2.1.1; B9: 2.2.1; B10: 3.0.1; B11: 3.1.1; B12: 3.2.1; ++ + Product: PowerEdge M520, PowerEdge R420, PowerEdge T420 + DIMM_A1: 0.1.0; DIMM_A2: 0.2.0; DIMM_A3: 0.3.0; + DIMM_A4: 0.1.1; DIMM_A5: 0.2.1; DIMM_A6: 0.3.1; +@@ -69,6 +76,17 @@ Vendor: Dell Inc. + DIMM_B1: 1.0.0; DIMM_B2: 1.1.0; DIMM_B3: 1.2.0; DIMM_B4: 1.3.0; + DIMM_B5: 1.0.1; DIMM_B6: 1.1.1; DIMM_B7: 1.2.1; DIMM_B8: 1.3.1; + ++ Product: PowerEdge C6320p ++ A1: 0.0.0; B1: 0.1.0; C1: 0.2.0; ++ D1: 1.0.0; E1: 1.1.0; F1: 1.2.0; ++ ++ Product: PowerEdge C6420 ++ A1: 0.0.0; A2: 0.1.0; A3: 0.2.0; A4: 1.0.0; A5: 1.1.0; A6: 1.2.0; ++ A7: 0.0.1; A8: 1.0.1; ++ ++ B1: 2.0.0; B2: 2.1.0; B3: 2.2.0; B4: 3.0.0; B5: 3.1.0; B6: 3.2.0; ++ B7: 2.0.1; B8: 3.0.1; ++ + Product: PowerEdge R430, PowerEdge T430, PowerEdge R530 + DIMM_A1: 0.0.0; DIMM_A2: 0.1.0; DIMM_A3: 0.2.0; DIMM_A4: 0.3.0; + DIMM_A5: 0.0.1; DIMM_A6: 0.1.1; DIMM_A7: 0.2.1; DIMM_A8: 0.3.1; +@@ -106,3 +124,16 @@ Vendor: Dell Inc. + DIMM_C_A1: 2.1.0; DIMM_C_A2: 2.2.0; + + DIMM_D_A1: 3.1.0; DIMM_D_A2: 3.2.0; ++ ++ Product: PowerEdge R940 ++ A1: 0.0.0; A2: 0.1.0; A3: 0.2.0; A4: 1.0.0; A5: 1.1.0; A6: 1.2.0; ++ A7: 0.0.1; A8: 0.1.1; A9: 0.2.1; A10: 1.0.1; A11: 1.1.1; A12: 1.2.1; ++ ++ B1: 2.0.0; B2: 2.1.0; B3: 2.2.0; B4: 3.0.0; B5: 3.1.0; B6: 3.2.0; ++ B7: 2.0.1; B8: 2.1.1; B9: 2.2.1; B10: 3.0.1; B11: 3.1.1; B12: 3.2.1; ++ ++ C1: 4.0.0; C2: 4.1.0; C3: 4.2.0; C4: 5.0.0; C5: 5.1.0; C6: 5.2.0; ++ C7: 4.0.1; C8: 4.1.1; C9: 4.2.1; C10: 5.0.1; C11: 5.1.1; C12: 5.2.1; ++ ++ D1: 6.0.0; D2: 6.1.0; D3: 6.2.0; D4: 7.0.0; D5: 7.1.0; D6: 7.2.0; ++ D7: 6.0.1; D8: 6.1.1; D9: 6.2.1; D10: 7.0.1; D11: 7.1.1; D12: 7.2.1; +-- +1.8.3.1 + diff --git a/SOURCES/0067-rasdaemon-add-support-for-non-standard-CPER-section-.patch b/SOURCES/0067-rasdaemon-add-support-for-non-standard-CPER-section-.patch new file mode 100644 index 0000000..088d0f3 --- /dev/null +++ b/SOURCES/0067-rasdaemon-add-support-for-non-standard-CPER-section-.patch @@ -0,0 +1,601 @@ +From 624d8a1d99a2f3bd06cbc537aff3cc30201ba7c2 Mon Sep 17 00:00:00 2001 +From: Tyler Baicar <tbaicar@codeaurora.org> +Date: Mon, 12 Jun 2017 16:16:04 -0600 +Subject: [PATCH 1/2] rasdaemon: add support for non standard CPER section + events + +Add support to handle the non standard CPER section kernel trace +events which cover RAS errors who's section type is unknown. + +Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +--- + Makefile.am | 3 + + configure.ac | 9 +++ + ras-events.c | 15 +++++ + ras-events.h | 8 +++ + ras-non-standard-handler.c | 147 +++++++++++++++++++++++++++++++++++++++++++++ + ras-non-standard-handler.h | 26 ++++++++ + ras-record.c | 59 ++++++++++++++++++ + ras-record.h | 15 +++++ + ras-report.c | 80 ++++++++++++++++++++++++ + ras-report.h | 18 +++++- + 10 files changed, 379 insertions(+), 1 deletion(-) + create mode 100644 ras-non-standard-handler.c + create mode 100644 ras-non-standard-handler.h + +diff --git a/Makefile.am b/Makefile.am +index a10e4b3..c5811e8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -24,6 +24,9 @@ endif + if WITH_AER + rasdaemon_SOURCES += ras-aer-handler.c + endif ++if WITH_NON_STANDARD ++ rasdaemon_SOURCES += ras-non-standard-handler.c ++endif + if WITH_MCE + rasdaemon_SOURCES += ras-mce-handler.c mce-intel.c mce-amd-k8.c \ + mce-intel-p4-p6.c mce-intel-nehalem.c \ +diff --git a/configure.ac b/configure.ac +index 5af5227..31bf6bd 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -44,6 +44,15 @@ AS_IF([test "x$enable_aer" = "xyes"], [ + ]) + AM_CONDITIONAL([WITH_AER], [test x$enable_aer = xyes]) + ++AC_ARG_ENABLE([non_standard], ++ AS_HELP_STRING([--enable-non-standard], [enable NON_STANDARD events (currently experimental)])) ++ ++AS_IF([test "x$enable_non_standard" = "xyes"], [ ++ AC_DEFINE(HAVE_NON_STANDARD,1,"have UNKNOWN_SEC events collect") ++ AC_SUBST([WITH_NON_STANDARD]) ++]) ++AM_CONDITIONAL([WITH_NON_STANDARD], [test x$enable_non_standard = xyes]) ++ + AC_ARG_ENABLE([mce], + AS_HELP_STRING([--enable-mce], [enable MCE events (currently experimental)])) + +diff --git a/ras-events.c b/ras-events.c +index 0be7c3f..96aa6f1 100644 +--- a/ras-events.c ++++ b/ras-events.c +@@ -29,6 +29,7 @@ + #include "libtrace/event-parse.h" + #include "ras-mc-handler.h" + #include "ras-aer-handler.h" ++#include "ras-non-standard-handler.h" + #include "ras-mce-handler.h" + #include "ras-extlog-handler.h" + #include "ras-record.h" +@@ -208,6 +209,10 @@ int toggle_ras_mc_event(int enable) + rc |= __toggle_ras_mc_event(ras, "ras", "extlog_mem_event", enable); + #endif + ++#ifdef HAVE_NON_STANDARD ++ rc |= __toggle_ras_mc_event(ras, "ras", "non_standard_event", enable); ++#endif ++ + free_ras: + free(ras); + return rc; +@@ -676,6 +681,16 @@ int handle_ras_events(int record_events) + "ras", "aer_event"); + #endif + ++#ifdef HAVE_NON_STANDARD ++ rc = add_event_handler(ras, pevent, page_size, "ras", "non_standard_event", ++ ras_non_standard_event_handler); ++ if (!rc) ++ num_events++; ++ else ++ log(ALL, LOG_ERR, "Can't get traces from %s:%s\n", ++ "ras", "non_standard_event"); ++#endif ++ + cpus = get_num_cpus(ras); + + #ifdef HAVE_MCE +diff --git a/ras-events.h b/ras-events.h +index 64e045a..3e1008f 100644 +--- a/ras-events.h ++++ b/ras-events.h +@@ -68,6 +68,14 @@ enum hw_event_mc_err_type { + HW_EVENT_ERR_INFO, + }; + ++/* Should match the code at Kernel's include/acpi/ghes.h */ ++enum ghes_severity { ++ GHES_SEV_NO, ++ GHES_SEV_CORRECTED, ++ GHES_SEV_RECOVERABLE, ++ GHES_SEV_PANIC, ++}; ++ + /* Function prototypes */ + int toggle_ras_mc_event(int enable); + int handle_ras_events(int record_events); +diff --git a/ras-non-standard-handler.c b/ras-non-standard-handler.c +new file mode 100644 +index 0000000..4c154e5 +--- /dev/null ++++ b/ras-non-standard-handler.c +@@ -0,0 +1,147 @@ ++/* ++ * Copyright (c) 2016, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ ++ * 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 <unistd.h> ++#include "libtrace/kbuffer.h" ++#include "ras-non-standard-handler.h" ++#include "ras-record.h" ++#include "ras-logger.h" ++#include "ras-report.h" ++ ++void print_le_hex(struct trace_seq *s, const uint8_t *buf, int index) { ++ trace_seq_printf(s, "%02x%02x%02x%02x", buf[index+3], buf[index+2], buf[index+1], buf[index]); ++} ++ ++static char *uuid_le(const char *uu) ++{ ++ static char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]; ++ char *p = uuid; ++ int i; ++ static const unsigned char le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15}; ++ ++ for (i = 0; i < 16; i++) { ++ p += sprintf(p, "%.2x", uu[le[i]]); ++ switch (i) { ++ case 3: ++ case 5: ++ case 7: ++ case 9: ++ *p++ = '-'; ++ break; ++ } ++ } ++ ++ *p = 0; ++ ++ return uuid; ++} ++ ++int ras_non_standard_event_handler(struct trace_seq *s, ++ struct pevent_record *record, ++ struct event_format *event, void *context) ++{ ++ int len, i, line_count; ++ unsigned long long val; ++ struct ras_events *ras = context; ++ time_t now; ++ struct tm *tm; ++ struct ras_non_standard_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, "sev", record, &val, 1) < 0) ++ return -1; ++ switch (val) { ++ case GHES_SEV_NO: ++ ev.severity = "Informational"; ++ break; ++ case GHES_SEV_CORRECTED: ++ ev.severity = "Corrected"; ++ break; ++ case GHES_SEV_RECOVERABLE: ++ ev.severity = "Recoverable"; ++ break; ++ default: ++ case GHES_SEV_PANIC: ++ ev.severity = "Fatal"; ++ } ++ trace_seq_printf(s, "\n %s", ev.severity); ++ ++ ev.sec_type = pevent_get_field_raw(s, event, "sec_type", record, &len, 1); ++ if(!ev.sec_type) ++ return -1; ++ trace_seq_printf(s, "\n section type: %s", uuid_le(ev.sec_type)); ++ ev.fru_text = pevent_get_field_raw(s, event, "fru_text", ++ record, &len, 1); ++ ev.fru_id = pevent_get_field_raw(s, event, "fru_id", ++ record, &len, 1); ++ trace_seq_printf(s, " fru text: %s fru id: %s ", ++ ev.fru_text, ++ uuid_le(ev.fru_id)); ++ ++ if (pevent_get_field_val(s, event, "len", record, &val, 1) < 0) ++ return -1; ++ ev.length = val; ++ trace_seq_printf(s, "\n length: %d\n", ev.length); ++ ++ ev.error = pevent_get_field_raw(s, event, "buf", record, &len, 1); ++ if(!ev.error) ++ return -1; ++ len = ev.length; ++ i = 0; ++ line_count = 0; ++ trace_seq_printf(s, " error:\n %08x: ", i); ++ while(len >= 4) { ++ print_le_hex(s, ev.error, i); ++ i+=4; ++ len-=4; ++ if(++line_count == 4) { ++ trace_seq_printf(s, "\n %08x: ", i); ++ line_count = 0; ++ } else ++ trace_seq_printf(s, " "); ++ } ++ ++ /* Insert data into the SGBD */ ++#ifdef HAVE_SQLITE3 ++ ras_store_non_standard_record(ras, &ev); ++#endif ++ ++#ifdef HAVE_ABRT_REPORT ++ /* Report event to ABRT */ ++ ras_report_non_standard_event(ras, &ev); ++#endif ++ ++ return 0; ++} +diff --git a/ras-non-standard-handler.h b/ras-non-standard-handler.h +new file mode 100644 +index 0000000..2b5ac35 +--- /dev/null ++++ b/ras-non-standard-handler.h +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (c) 2016, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ ++ * 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_NON_STANDARD_HANDLER_H ++#define __RAS_NON_STANDARD_HANDLER_H ++ ++#include "ras-events.h" ++#include "libtrace/event-parse.h" ++ ++int ras_non_standard_event_handler(struct trace_seq *s, ++ struct pevent_record *record, ++ struct event_format *event, void *context); ++ ++void print_le_hex(struct trace_seq *s, const uint8_t *buf, int index); ++ ++#endif +diff --git a/ras-record.c b/ras-record.c +index 3dc4493..357ab61 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 2013 Mauro Carvalho Chehab <mchehab@redhat.com> ++ * Copyright (c) 2016, The Linux Foundation. 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 +@@ -157,6 +158,57 @@ int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) + } + #endif + ++/* ++ * Table and functions to handle ras:non standard ++ */ ++ ++#ifdef HAVE_NON_STANDARD ++static const struct db_fields non_standard_event_fields[] = { ++ { .name="id", .type="INTEGER PRIMARY KEY" }, ++ { .name="timestamp", .type="TEXT" }, ++ { .name="sec_type", .type="BLOB" }, ++ { .name="fru_id", .type="BLOB" }, ++ { .name="fru_text", .type="TEXT" }, ++ { .name="severity", .type="TEXT" }, ++ { .name="error", .type="BLOB" }, ++}; ++ ++static const struct db_table_descriptor non_standard_event_tab = { ++ .name = "non_standard_event", ++ .fields = non_standard_event_fields, ++ .num_fields = ARRAY_SIZE(non_standard_event_fields), ++}; ++ ++int ras_store_non_standard_record(struct ras_events *ras, struct ras_non_standard_event *ev) ++{ ++ int rc; ++ struct sqlite3_priv *priv = ras->db_priv; ++ ++ if (!priv || !priv->stmt_non_standard_record) ++ return 0; ++ log(TERM, LOG_INFO, "non_standard_event store: %p\n", priv->stmt_non_standard_record); ++ ++ sqlite3_bind_text (priv->stmt_non_standard_record, 1, ev->timestamp, -1, NULL); ++ sqlite3_bind_blob (priv->stmt_non_standard_record, 2, ev->sec_type, -1, NULL); ++ sqlite3_bind_blob (priv->stmt_non_standard_record, 3, ev->fru_id, 16, NULL); ++ sqlite3_bind_text (priv->stmt_non_standard_record, 4, ev->fru_text, -1, NULL); ++ sqlite3_bind_text (priv->stmt_non_standard_record, 5, ev->severity, -1, NULL); ++ sqlite3_bind_blob (priv->stmt_non_standard_record, 6, ev->error, ev->length, NULL); ++ ++ rc = sqlite3_step(priv->stmt_non_standard_record); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed to do non_standard_event step on sqlite: error = %d\n", rc); ++ rc = sqlite3_reset(priv->stmt_non_standard_record); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed reset non_standard_event on sqlite: error = %d\n", rc); ++ log(TERM, LOG_INFO, "register inserted at db\n"); ++ ++ return rc; ++} ++#endif ++ + #ifdef HAVE_EXTLOG + static const struct db_fields extlog_event_fields[] = { + { .name="id", .type="INTEGER PRIMARY KEY" }, +@@ -450,6 +502,13 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + &mce_record_tab); + #endif + ++#ifdef HAVE_NON_STANDARD ++ rc = ras_mc_create_table(priv, &non_standard_event_tab); ++ if (rc == SQLITE_OK) ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_non_standard_record, ++ &non_standard_event_tab); ++#endif ++ + ras->db_priv = priv; + return 0; + } +diff --git a/ras-record.h b/ras-record.h +index 5d84297..473ae40 100644 +--- a/ras-record.h ++++ b/ras-record.h +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 2013 Mauro Carvalho Chehab <mchehab@redhat.com> ++ * Copyright (c) 2016, The Linux Foundation. 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 +@@ -56,9 +57,18 @@ struct ras_extlog_event { + unsigned short cper_data_length; + }; + ++struct ras_non_standard_event { ++ char timestamp[64]; ++ const char *sec_type, *fru_id, *fru_text; ++ const char *severity; ++ const uint8_t *error; ++ uint32_t length; ++}; ++ + struct ras_mc_event; + struct ras_aer_event; + struct ras_extlog_event; ++struct ras_non_standard_event; + struct mce_event; + + #ifdef HAVE_SQLITE3 +@@ -77,6 +87,9 @@ struct sqlite3_priv { + #ifdef HAVE_EXTLOG + sqlite3_stmt *stmt_extlog_record; + #endif ++#ifdef HAVE_NON_STANDARD ++ sqlite3_stmt *stmt_non_standard_record; ++#endif + }; + + int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras); +@@ -84,6 +97,7 @@ int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev); + int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev); + int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev); + 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); + + #else + static inline int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) { return 0; }; +@@ -91,6 +105,7 @@ static inline int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event + static inline int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) { return 0; }; + static inline int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev) { return 0; }; + 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; }; + + #endif + +diff --git a/ras-report.c b/ras-report.c +index 0a05732..1eb9f79 100644 +--- a/ras-report.c ++++ b/ras-report.c +@@ -1,3 +1,16 @@ ++/* ++ * Copyright (c) 2016, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ ++ * 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 <string.h> + #include <unistd.h> +@@ -196,6 +209,25 @@ static int set_aer_event_backtrace(char *buf, struct ras_aer_event *ev){ + return 0; + } + ++static int set_non_standard_event_backtrace(char *buf, struct ras_non_standard_event *ev){ ++ char bt_buf[MAX_BACKTRACE_SIZE]; ++ ++ if(!buf || !ev) ++ return -1; ++ ++ sprintf(bt_buf, "BACKTRACE=" \ ++ "timestamp=%s\n" \ ++ "severity=%s\n" \ ++ "length=%d\n", \ ++ ev->timestamp, \ ++ ev->severity, \ ++ ev->length); ++ ++ 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; +@@ -218,6 +250,9 @@ static int commit_report_backtrace(int sockfd, int type, void *ev){ + case MCE_EVENT: + rc = set_mce_event_backtrace(buf, (struct mce_event *)ev); + break; ++ case NON_STANDARD_EVENT: ++ rc = set_non_standard_event_backtrace(buf, (struct ras_non_standard_event *)ev); ++ break; + default: + return -1; + } +@@ -345,6 +380,51 @@ aer_fail: + } + } + ++int ras_report_non_standard_event(struct ras_events *ras, struct ras_non_standard_event *ev){ ++ char buf[MAX_MESSAGE_SIZE]; ++ int sockfd = 0; ++ int rc = -1; ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ sockfd = setup_report_socket(); ++ if(sockfd < 0){ ++ return rc; ++ } ++ ++ rc = commit_report_basic(sockfd); ++ if(rc < 0){ ++ goto non_standard_fail; ++ } ++ ++ rc = commit_report_backtrace(sockfd, NON_STANDARD_EVENT, ev); ++ if(rc < 0){ ++ goto non_standard_fail; ++ } ++ ++ sprintf(buf, "ANALYZER=%s", "rasdaemon-non-standard"); ++ rc = write(sockfd, buf, strlen(buf) + 1); ++ if(rc < strlen(buf) + 1){ ++ goto non_standard_fail; ++ } ++ ++ sprintf(buf, "REASON=%s", "Unknown CPER section problem"); ++ rc = write(sockfd, buf, strlen(buf) + 1); ++ if(rc < strlen(buf) + 1){ ++ goto non_standard_fail; ++ } ++ ++ rc = 0; ++ ++non_standard_fail: ++ ++ if(sockfd > 0){ ++ close(sockfd); ++ } ++ ++ return rc; ++} ++ + int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev){ + char buf[MAX_MESSAGE_SIZE]; + int sockfd = 0; +diff --git a/ras-report.h b/ras-report.h +index 7920cdf..c2fcf42 100644 +--- a/ras-report.h ++++ b/ras-report.h +@@ -1,3 +1,16 @@ ++/* ++ * Copyright (c) 2016, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ ++ * 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_REPORT_H + #define __RAS_REPORT_H + +@@ -19,7 +32,8 @@ + enum { + MC_EVENT, + MCE_EVENT, +- AER_EVENT ++ AER_EVENT, ++ NON_STANDARD_EVENT + }; + + #ifdef HAVE_ABRT_REPORT +@@ -27,12 +41,14 @@ enum { + int ras_report_mc_event(struct ras_events *ras, struct ras_mc_event *ev); + int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev); + 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); + + #else + + static inline int ras_report_mc_event(struct ras_events *ras, struct ras_mc_event *ev) { return 0; }; + static inline int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev) { return 0; }; + 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; }; + + #endif + +-- +1.8.3.1 + diff --git a/SOURCES/0068-rasdaemon-add-support-for-non-standard-error-decoder.patch b/SOURCES/0068-rasdaemon-add-support-for-non-standard-error-decoder.patch new file mode 100644 index 0000000..91a6cc2 --- /dev/null +++ b/SOURCES/0068-rasdaemon-add-support-for-non-standard-error-decoder.patch @@ -0,0 +1,150 @@ +From 873e88d6ba1ce5ec97f5cc0f4f0b45dfd2026b9f Mon Sep 17 00:00:00 2001 +From: "shiju.jose@huawei.com" <shiju.jose@huawei.com> +Date: Wed, 4 Oct 2017 10:11:08 +0100 +Subject: [PATCH] rasdaemon:add support for non-standard error decoder + +This patch add support to decode the non-standard +error information. + +Signed-off-by: Shiju Jose <shiju.jose@huawei.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +--- + ras-non-standard-handler.c | 62 +++++++++++++++++++++++++++++++++++++++++++++- + ras-non-standard-handler.h | 10 ++++++++ + 2 files changed, 71 insertions(+), 1 deletion(-) + +diff --git a/ras-non-standard-handler.c b/ras-non-standard-handler.c +index 4c154e5..21e6a76 100644 +--- a/ras-non-standard-handler.c ++++ b/ras-non-standard-handler.c +@@ -13,6 +13,7 @@ + + #include <stdio.h> + #include <stdlib.h> ++#include <stdbool.h> + #include <string.h> + #include <unistd.h> + #include "libtrace/kbuffer.h" +@@ -21,6 +22,31 @@ + #include "ras-logger.h" + #include "ras-report.h" + ++static p_ns_dec_tab * ns_dec_tab; ++static size_t dec_tab_count; ++ ++int register_ns_dec_tab(const p_ns_dec_tab tab) ++{ ++ ns_dec_tab = (p_ns_dec_tab *)realloc(ns_dec_tab, ++ (dec_tab_count + 1) * sizeof(tab)); ++ if (ns_dec_tab == NULL) { ++ printf("%s p_ns_dec_tab malloc failed", __func__); ++ return -1; ++ } ++ ns_dec_tab[dec_tab_count] = tab; ++ dec_tab_count++; ++ return 0; ++} ++ ++void unregister_ns_dec_tab(void) ++{ ++ if (ns_dec_tab) { ++ free(ns_dec_tab); ++ ns_dec_tab = NULL; ++ dec_tab_count = 0; ++ } ++} ++ + void print_le_hex(struct trace_seq *s, const uint8_t *buf, int index) { + trace_seq_printf(s, "%02x%02x%02x%02x", buf[index+3], buf[index+2], buf[index+1], buf[index]); + } +@@ -49,16 +75,32 @@ static char *uuid_le(const char *uu) + return uuid; + } + ++static int uuid_le_cmp(const char *sec_type, const char *uuid2) ++{ ++ static char uuid1[32]; ++ char *p = uuid1; ++ int i; ++ static const unsigned char le[16] = { ++ 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}; ++ ++ for (i = 0; i < 16; i++) ++ p += sprintf(p, "%.2x", sec_type[le[i]]); ++ *p = 0; ++ return strncmp(uuid1, uuid2, 32); ++} ++ + int ras_non_standard_event_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) + { +- int len, i, line_count; ++ int len, i, line_count, count; + unsigned long long val; + struct ras_events *ras = context; + time_t now; + struct tm *tm; + struct ras_non_standard_event ev; ++ p_ns_dec_tab dec_tab; ++ bool dec_done = false; + + /* + * Newer kernels (3.10-rc1 or upper) provide an uptime clock. +@@ -133,6 +175,18 @@ int ras_non_standard_event_handler(struct trace_seq *s, + trace_seq_printf(s, " "); + } + ++ for (count = 0; count < dec_tab_count && !dec_done; count++) { ++ dec_tab = ns_dec_tab[count]; ++ for (i = 0; i < dec_tab[0].len; i++) { ++ if (uuid_le_cmp(ev.sec_type, ++ dec_tab[i].sec_type) == 0) { ++ dec_tab[i].decode(s, ev.error); ++ dec_done = true; ++ break; ++ } ++ } ++ } ++ + /* Insert data into the SGBD */ + #ifdef HAVE_SQLITE3 + ras_store_non_standard_record(ras, &ev); +@@ -145,3 +199,9 @@ int ras_non_standard_event_handler(struct trace_seq *s, + + return 0; + } ++ ++__attribute__((destructor)) ++static void ns_exit(void) ++{ ++ unregister_ns_dec_tab(); ++} +diff --git a/ras-non-standard-handler.h b/ras-non-standard-handler.h +index 2b5ac35..a183d1a 100644 +--- a/ras-non-standard-handler.h ++++ b/ras-non-standard-handler.h +@@ -17,10 +17,20 @@ + #include "ras-events.h" + #include "libtrace/event-parse.h" + ++typedef struct ras_ns_dec_tab { ++ const char *sec_type; ++ int (*decode)(struct trace_seq *s, const void *err); ++ size_t len; ++} *p_ns_dec_tab; ++ + int ras_non_standard_event_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context); + + void print_le_hex(struct trace_seq *s, const uint8_t *buf, int index); + ++int register_ns_dec_tab(const p_ns_dec_tab tab); ++ ++void unregister_ns_dec_tab(void); ++ + #endif +-- +1.8.3.1 + diff --git a/SOURCES/0069-rasdaemon-add-support-for-ARM-events.patch b/SOURCES/0069-rasdaemon-add-support-for-ARM-events.patch new file mode 100644 index 0000000..c2c915b --- /dev/null +++ b/SOURCES/0069-rasdaemon-add-support-for-ARM-events.patch @@ -0,0 +1,489 @@ +From 5662e5376adcc45da43d7818c8ac1882883c18ac Mon Sep 17 00:00:00 2001 +From: Tyler Baicar <tbaicar@codeaurora.org> +Date: Tue, 12 Sep 2017 14:58:25 -0600 +Subject: [PATCH 1/2] rasdaemon: add support for ARM events + +Add support to handle the ARM kernel trace events +which cover RAS ARM processor errors. + +[V4]: fix arm_event_tab usage + +Change-Id: Ife99c97042498d5fad4d9b8e873ecfba6a47947d +Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +--- + Makefile.am | 3 ++ + configure.ac | 9 ++++++ + ras-arm-handler.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ras-arm-handler.h | 24 +++++++++++++++ + ras-events.c | 15 ++++++++++ + ras-record.c | 59 ++++++++++++++++++++++++++++++++++++ + ras-record.h | 16 ++++++++++ + ras-report.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ + ras-report.h | 5 +++- + 9 files changed, 295 insertions(+), 1 deletion(-) + create mode 100644 ras-arm-handler.c + create mode 100644 ras-arm-handler.h + +diff --git a/Makefile.am b/Makefile.am +index 2500772..4aa5543 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -27,6 +27,9 @@ endif + if WITH_NON_STANDARD + rasdaemon_SOURCES += ras-non-standard-handler.c + endif ++if WITH_ARM ++ rasdaemon_SOURCES += ras-arm-handler.c ++endif + if WITH_MCE + rasdaemon_SOURCES += ras-mce-handler.c mce-intel.c mce-amd-k8.c \ + mce-intel-p4-p6.c mce-intel-nehalem.c \ +diff --git a/configure.ac b/configure.ac +index ecd4b2f..14fc2f2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -53,6 +53,15 @@ AS_IF([test "x$enable_non_standard" = "xyes"], [ + ]) + AM_CONDITIONAL([WITH_NON_STANDARD], [test x$enable_non_standard = xyes]) + ++AC_ARG_ENABLE([arm], ++ AS_HELP_STRING([--enable-arm], [enable ARM events (currently experimental)])) ++ ++AS_IF([test "x$enable_arm" = "xyes"], [ ++ AC_DEFINE(HAVE_ARM,1,"have ARM events collect") ++ AC_SUBST([WITH_ARM]) ++]) ++AM_CONDITIONAL([WITH_ARM], [test x$enable_arm = xyes]) ++ + AC_ARG_ENABLE([mce], + AS_HELP_STRING([--enable-mce], [enable MCE events (currently experimental)])) + +diff --git a/ras-arm-handler.c b/ras-arm-handler.c +new file mode 100644 +index 0000000..a76470d +--- /dev/null ++++ b/ras-arm-handler.c +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2016, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ ++ * 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 <unistd.h> ++#include "libtrace/kbuffer.h" ++#include "ras-arm-handler.h" ++#include "ras-record.h" ++#include "ras-logger.h" ++#include "ras-report.h" ++ ++int ras_arm_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_arm_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\n", ev.timestamp); ++ ++ if (pevent_get_field_val(s, event, "affinity", record, &val, 1) < 0) ++ return -1; ++ ev.affinity = val; ++ trace_seq_printf(s, " affinity: %d", ev.affinity); ++ ++ if (pevent_get_field_val(s, event, "mpidr", record, &val, 1) < 0) ++ return -1; ++ ev.mpidr = val; ++ trace_seq_printf(s, "\n MPIDR: 0x%llx", (unsigned long long)ev.mpidr); ++ ++ if (pevent_get_field_val(s, event, "midr", record, &val, 1) < 0) ++ return -1; ++ ev.midr = val; ++ trace_seq_printf(s, "\n MIDR: 0x%llx", (unsigned long long)ev.midr); ++ ++ if (pevent_get_field_val(s, event, "running_state", record, &val, 1) < 0) ++ return -1; ++ ev.running_state = val; ++ trace_seq_printf(s, "\n running_state: %d", ev.running_state); ++ ++ if (pevent_get_field_val(s, event, "psci_state", record, &val, 1) < 0) ++ return -1; ++ ev.psci_state = val; ++ trace_seq_printf(s, "\n psci_state: %d", ev.psci_state); ++ ++ /* Insert data into the SGBD */ ++#ifdef HAVE_SQLITE3 ++ ras_store_arm_record(ras, &ev); ++#endif ++ ++#ifdef HAVE_ABRT_REPORT ++ /* Report event to ABRT */ ++ ras_report_arm_event(ras, &ev); ++#endif ++ ++ return 0; ++} +diff --git a/ras-arm-handler.h b/ras-arm-handler.h +new file mode 100644 +index 0000000..eae10ec +--- /dev/null ++++ b/ras-arm-handler.h +@@ -0,0 +1,24 @@ ++/* ++ * Copyright (c) 2016, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ ++ * 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_ARM_HANDLER_H ++#define __RAS_ARM_HANDLER_H ++ ++#include "ras-events.h" ++#include "libtrace/event-parse.h" ++ ++int ras_arm_event_handler(struct trace_seq *s, ++ struct pevent_record *record, ++ struct event_format *event, void *context); ++ ++#endif +diff --git a/ras-events.c b/ras-events.c +index 96aa6f1..812d712 100644 +--- a/ras-events.c ++++ b/ras-events.c +@@ -30,6 +30,7 @@ + #include "ras-mc-handler.h" + #include "ras-aer-handler.h" + #include "ras-non-standard-handler.h" ++#include "ras-arm-handler.h" + #include "ras-mce-handler.h" + #include "ras-extlog-handler.h" + #include "ras-record.h" +@@ -213,6 +214,10 @@ int toggle_ras_mc_event(int enable) + rc |= __toggle_ras_mc_event(ras, "ras", "non_standard_event", enable); + #endif + ++#ifdef HAVE_ARM ++ rc |= __toggle_ras_mc_event(ras, "ras", "arm_event", enable); ++#endif ++ + free_ras: + free(ras); + return rc; +@@ -691,6 +696,16 @@ int handle_ras_events(int record_events) + "ras", "non_standard_event"); + #endif + ++#ifdef HAVE_ARM ++ rc = add_event_handler(ras, pevent, page_size, "ras", "arm_event", ++ ras_arm_event_handler); ++ if (!rc) ++ num_events++; ++ else ++ log(ALL, LOG_ERR, "Can't get traces from %s:%s\n", ++ "ras", "arm_event"); ++#endif ++ + cpus = get_num_cpus(ras); + + #ifdef HAVE_MCE +diff --git a/ras-record.c b/ras-record.c +index 357ab61..c3644cb 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -209,6 +209,58 @@ int ras_store_non_standard_record(struct ras_events *ras, struct ras_non_standar + } + #endif + ++/* ++ * Table and functions to handle ras:arm ++ */ ++ ++#ifdef HAVE_ARM ++static const struct db_fields arm_event_fields[] = { ++ { .name="id", .type="INTEGER PRIMARY KEY" }, ++ { .name="timestamp", .type="TEXT" }, ++ { .name="error_count", .type="INTEGER" }, ++ { .name="affinity", .type="INTEGER" }, ++ { .name="mpidr", .type="INTEGER" }, ++ { .name="running_state", .type="INTEGER" }, ++ { .name="psci_state", .type="INTEGER" }, ++}; ++ ++static const struct db_table_descriptor arm_event_tab = { ++ .name = "arm_event", ++ .fields = arm_event_fields, ++ .num_fields = ARRAY_SIZE(arm_event_fields), ++}; ++ ++int ras_store_arm_record(struct ras_events *ras, struct ras_arm_event *ev) ++{ ++ int rc; ++ struct sqlite3_priv *priv = ras->db_priv; ++ ++ if (!priv || !priv->stmt_arm_record) ++ return 0; ++ log(TERM, LOG_INFO, "arm_event store: %p\n", priv->stmt_arm_record); ++ ++ sqlite3_bind_text (priv->stmt_arm_record, 1, ev->timestamp, -1, NULL); ++ sqlite3_bind_int (priv->stmt_arm_record, 2, ev->error_count); ++ sqlite3_bind_int (priv->stmt_arm_record, 3, ev->affinity); ++ sqlite3_bind_int (priv->stmt_arm_record, 4, ev->mpidr); ++ sqlite3_bind_int (priv->stmt_arm_record, 5, ev->running_state); ++ sqlite3_bind_int (priv->stmt_arm_record, 6, ev->psci_state); ++ ++ rc = sqlite3_step(priv->stmt_arm_record); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed to do arm_event step on sqlite: error = %d\n", rc); ++ rc = sqlite3_reset(priv->stmt_arm_record); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed reset arm_event on sqlite: error = %d\n", ++ rc); ++ log(TERM, LOG_INFO, "register inserted at db\n"); ++ ++ return rc; ++} ++#endif ++ + #ifdef HAVE_EXTLOG + static const struct db_fields extlog_event_fields[] = { + { .name="id", .type="INTEGER PRIMARY KEY" }, +@@ -509,6 +561,13 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + &non_standard_event_tab); + #endif + ++#ifdef HAVE_ARM ++ rc = ras_mc_create_table(priv, &arm_event_tab); ++ if (rc == SQLITE_OK) ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_arm_record, ++ &arm_event_tab); ++#endif ++ + ras->db_priv = priv; + return 0; + } +diff --git a/ras-record.h b/ras-record.h +index 473ae40..12c2218 100644 +--- a/ras-record.h ++++ b/ras-record.h +@@ -65,10 +65,21 @@ struct ras_non_standard_event { + uint32_t length; + }; + ++struct ras_arm_event { ++ char timestamp[64]; ++ int32_t error_count; ++ int8_t affinity; ++ int64_t mpidr; ++ int64_t midr; ++ int32_t running_state; ++ int32_t psci_state; ++}; ++ + struct ras_mc_event; + struct ras_aer_event; + struct ras_extlog_event; + struct ras_non_standard_event; ++struct ras_arm_event; + struct mce_event; + + #ifdef HAVE_SQLITE3 +@@ -90,6 +101,9 @@ struct sqlite3_priv { + #ifdef HAVE_NON_STANDARD + sqlite3_stmt *stmt_non_standard_record; + #endif ++#ifdef HAVE_ARM ++ sqlite3_stmt *stmt_arm_record; ++#endif + }; + + int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras); +@@ -98,6 +112,7 @@ int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev); + int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev); + 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); + + #else + static inline int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) { return 0; }; +@@ -106,6 +121,7 @@ static inline int ras_store_aer_event(struct ras_events *ras, struct ras_aer_eve + static inline int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev) { return 0; }; + 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; }; + + #endif + +diff --git a/ras-report.c b/ras-report.c +index 1eb9f79..d4beee0 100644 +--- a/ras-report.c ++++ b/ras-report.c +@@ -228,6 +228,33 @@ static int set_non_standard_event_backtrace(char *buf, struct ras_non_standard_e + return 0; + } + ++static int set_arm_event_backtrace(char *buf, struct ras_arm_event *ev){ ++ char bt_buf[MAX_BACKTRACE_SIZE]; ++ ++ if(!buf || !ev) ++ return -1; ++ ++ sprintf(bt_buf, "BACKTRACE=" \ ++ "timestamp=%s\n" \ ++ "error_count=%d\n" \ ++ "affinity=%d\n" \ ++ "mpidr=0x%lx\n" \ ++ "midr=0x%lx\n" \ ++ "running_state=%d\n" \ ++ "psci_state=%d\n", \ ++ ev->timestamp, \ ++ ev->error_count, \ ++ ev->affinity, \ ++ ev->mpidr, \ ++ ev->midr, \ ++ ev->running_state, \ ++ ev->psci_state); ++ ++ 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; +@@ -253,6 +280,9 @@ static int commit_report_backtrace(int sockfd, int type, void *ev){ + case NON_STANDARD_EVENT: + rc = set_non_standard_event_backtrace(buf, (struct ras_non_standard_event *)ev); + break; ++ case ARM_EVENT: ++ rc = set_arm_event_backtrace(buf, (struct ras_arm_event *)ev); ++ break; + default: + return -1; + } +@@ -425,6 +455,51 @@ non_standard_fail: + return rc; + } + ++int ras_report_arm_event(struct ras_events *ras, struct ras_arm_event *ev){ ++ char buf[MAX_MESSAGE_SIZE]; ++ int sockfd = 0; ++ int rc = -1; ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ sockfd = setup_report_socket(); ++ if(sockfd < 0){ ++ return rc; ++ } ++ ++ rc = commit_report_basic(sockfd); ++ if(rc < 0){ ++ goto arm_fail; ++ } ++ ++ rc = commit_report_backtrace(sockfd, ARM_EVENT, ev); ++ if(rc < 0){ ++ goto arm_fail; ++ } ++ ++ sprintf(buf, "ANALYZER=%s", "rasdaemon-arm"); ++ rc = write(sockfd, buf, strlen(buf) + 1); ++ if(rc < strlen(buf) + 1){ ++ goto arm_fail; ++ } ++ ++ sprintf(buf, "REASON=%s", "ARM CPU report problem"); ++ rc = write(sockfd, buf, strlen(buf) + 1); ++ if(rc < strlen(buf) + 1){ ++ goto arm_fail; ++ } ++ ++ rc = 0; ++ ++arm_fail: ++ ++ if(sockfd > 0){ ++ close(sockfd); ++ } ++ ++ return rc; ++} ++ + int ras_report_mce_event(struct ras_events *ras, struct mce_event *ev){ + char buf[MAX_MESSAGE_SIZE]; + int sockfd = 0; +diff --git a/ras-report.h b/ras-report.h +index c2fcf42..6c466f5 100644 +--- a/ras-report.h ++++ b/ras-report.h +@@ -33,7 +33,8 @@ enum { + MC_EVENT, + MCE_EVENT, + AER_EVENT, +- NON_STANDARD_EVENT ++ NON_STANDARD_EVENT, ++ ARM_EVENT + }; + + #ifdef HAVE_ABRT_REPORT +@@ -42,6 +43,7 @@ int ras_report_mc_event(struct ras_events *ras, struct ras_mc_event *ev); + int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev); + 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); + + #else + +@@ -49,6 +51,7 @@ static inline int ras_report_mc_event(struct ras_events *ras, struct ras_mc_even + static inline int ras_report_aer_event(struct ras_events *ras, struct ras_aer_event *ev) { return 0; }; + 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; }; + + #endif + +-- +1.8.3.1 + diff --git a/SOURCES/0070-rasdaemon-ARM-fully-initialize-ras_arm_event.patch b/SOURCES/0070-rasdaemon-ARM-fully-initialize-ras_arm_event.patch new file mode 100644 index 0000000..34a7d34 --- /dev/null +++ b/SOURCES/0070-rasdaemon-ARM-fully-initialize-ras_arm_event.patch @@ -0,0 +1,27 @@ +commit 1b23bf7d97bacd1d00adb4404dfc5004df394358 +Author: Aristeu Rozanski <arozansk@redhat.com> +Date: Fri Feb 2 10:15:25 2018 -0500 + + ARM: initialize with 0 unused ras_arm_event members + + Issue found by covscan: + + 1. rasdaemon-0.4.1/ras-arm-handler.c:32: var_decl: Declaring variable "ev" without initializer. + 16. rasdaemon-0.4.1/ras-arm-handler.c:81: uninit_use_in_call: Using uninitialized value "ev.error_count" when calling "ras_store_arm_record". + 23. rasdaemon-0.4.1/ras-record.c:243:2: read_parm_fld: Reading a parameter field. + + Signed-off-by: Aristeu Rozanski <arozansk@redhat.com> + +diff --git a/ras-arm-handler.c b/ras-arm-handler.c +index a76470d..2f170e2 100644 +--- a/ras-arm-handler.c ++++ b/ras-arm-handler.c +@@ -31,6 +31,8 @@ int ras_arm_event_handler(struct trace_seq *s, + struct tm *tm; + struct ras_arm_event ev; + ++ memset(&ev, 0, sizeof(ev)); ++ + /* + * Newer kernels (3.10-rc1 or upper) provide an uptime clock. + * On previous kernels, the way to properly generate an event would diff --git a/SPECS/rasdaemon.spec b/SPECS/rasdaemon.spec index 19b23cc..6a72dfb 100644 --- a/SPECS/rasdaemon.spec +++ b/SPECS/rasdaemon.spec @@ -2,11 +2,11 @@ Name: rasdaemon Version: 0.4.1 -Release: 28%{?dist} +Release: 32%{?dist} Summary: Utility to receive RAS error tracings Group: Applications/System License: GPLv2 -URL: https://git.fedorahosted.org/git/rasdaemon.git +URL: https://pagure.io/rasdaemon Source0: http://mchehab.fedorapeople.org/%{name}-%{version}.tar.bz2 ExclusiveArch: %{ix86} x86_64 aarch64 %{power64} @@ -79,6 +79,12 @@ Patch52: 0062-Add-Broadwell-EP-EX-MSCOD-values.patch Patch53: rasdaemon-dont_use_memerror_log_enable_on_knl.patch Patch54: 0063-add_support_for_knights_mill.patch Patch55: 0064-add_support_for_skylake.patch +Patch56: 0065-rasdaemon-Update-DIMM-labels-for-Dell-Servers.patch +Patch57: 0066-rasdaemon-Update-DIMM-labels-for-Intel-Skylake-serve.patch +Patch58: 0067-rasdaemon-add-support-for-non-standard-CPER-section-.patch +Patch59: 0068-rasdaemon-add-support-for-non-standard-error-decoder.patch +Patch60: 0069-rasdaemon-add-support-for-ARM-events.patch +Patch61: 0070-rasdaemon-ARM-fully-initialize-ras_arm_event.patch %description %{name} is a RAS (Reliability, Availability and Serviceability) logging tool. @@ -147,10 +153,16 @@ an utility for reporting current error counts from the EDAC sysfs files. %patch53 -p1 %patch54 -p1 %patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 %build autoreconf -vfi -%configure --enable-mce --enable-aer --enable-sqlite3 --enable-extlog +%configure --enable-mce --enable-aer --enable-sqlite3 --enable-extlog --enable-arm make %{?_smp_mflags} %install @@ -174,6 +186,18 @@ rm -rf %{buildroot} %{_sysconfdir}/ras/dimm_labels.d %changelog +* Fri Feb 02 2018 Aristeu Rozanski <aris@redhat.com> 0.4.1-32.el7 +- Fixed covscan error [1520602] + +* Wed Jan 24 2018 Aristeu Rozanski <aris@redhat.com> 0.4.1-31.el7 +- Added ARM support [1520602] + +* Thu Oct 19 2017 Aristeu Rozanski <aris@redhat.com> 0.4.1-30.el7 +- Updated project url [1502400] + +* Wed Aug 23 2017 Aristeu Rozanski <aris@redhat.com> 0.4.1-29.el7 +- Updating Dell labels [1458938] + * Tue May 30 2017 Aristeu Rozanski <aris@redhat.com> 0.4.1-28.el7 - Bump release [1448113]