Attn: On TI with recoverable errors call analyzer
While servicing a TI attention handler will check if recoverable
error attentions are present and if so it will call the analyzer.
Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: I60f0d32932f678ddee894d9424b16409e60bdbd4
diff --git a/attn/attn_common.cpp b/attn/attn_common.cpp
index 0b9061d..d387b4f 100644
--- a/attn/attn_common.cpp
+++ b/attn/attn_common.cpp
@@ -1,6 +1,7 @@
#include <libpdbg.h>
#include <attn/attn_common.hpp>
+#include <attn/attn_handler.hpp>
#include <attn/attn_logging.hpp>
#include <sdbusplus/bus.hpp>
#include <util/pdbg.hpp>
@@ -89,4 +90,71 @@
} // end addHbStatusRegs
+/** @brief Check for recoverable errors present */
+bool recoverableErrors()
+{
+ bool recoverableErrors = false; // assume no recoverable attentions
+
+ pdbg_target* target;
+ pdbg_for_each_class_target("proc", target)
+ {
+ if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
+ {
+ auto proc = pdbg_target_index(target); // get processor number
+
+ // Use PIB target to determine if a processor is enabled
+ char path[16];
+ sprintf(path, "/proc%d/pib", proc);
+ pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
+
+ // sanity check
+ if (nullptr == pibTarget)
+ {
+ trace<level::INFO>("pib path or target not found");
+ continue;
+ }
+
+ // check if pib target is enabled - indicates proc is enabled
+ if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
+ {
+ // The processor FSI target is required for CFAM read
+ sprintf(path, "/proc%d/fsi", proc);
+ pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
+
+ // sanity check
+ if (nullptr == fsiTarget)
+ {
+ trace<level::INFO>("fsi path or target not found");
+ continue;
+ }
+
+ uint32_t isr_val = 0xffffffff; // invalid isr value
+
+ // get active attentions on processor
+ if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
+ {
+ // log cfam read error
+ trace<level::ERROR>("Error! cfam read 0x1007 FAILED");
+ eventAttentionFail((int)AttnSection::attnHandler |
+ ATTN_PDBG_CFAM);
+ }
+ // check for invalid/stale value
+ else if (0xffffffff == isr_val)
+ {
+ trace<level::ERROR>("Error! cfam read 0x1007 INVALID");
+ continue;
+ }
+ // check recoverable error status bit
+ else if (0 != (isr_val & RECOVERABLE_ATTN))
+ {
+ recoverableErrors = true;
+ break;
+ }
+ } // fsi target enabled
+ } // pib target enabled
+ } // next processor
+
+ return recoverableErrors;
+}
+
} // namespace attn
diff --git a/attn/attn_common.hpp b/attn/attn_common.hpp
index 6f4428d..938af36 100644
--- a/attn/attn_common.hpp
+++ b/attn/attn_common.hpp
@@ -45,4 +45,11 @@
*/
void addHbStatusRegs();
+/**
+ * @brief Check for recoverable errors present
+ *
+ * @return true if any recoverable errors are present, else false
+ */
+bool recoverableErrors();
+
} // namespace attn
diff --git a/attn/attn_dump.hpp b/attn/attn_dump.hpp
index 04c51e7..d7cdfac 100644
--- a/attn/attn_dump.hpp
+++ b/attn/attn_dump.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include <cstdint>
namespace attn
{
diff --git a/attn/attn_handler.hpp b/attn/attn_handler.hpp
index 41ed409..90e60d5 100644
--- a/attn/attn_handler.hpp
+++ b/attn/attn_handler.hpp
@@ -6,9 +6,10 @@
{
/** @brief Attention global status bits */
-constexpr uint32_t SBE_ATTN = 0x00000002;
-constexpr uint32_t CHECKSTOP_ATTN = 0x40000000;
-constexpr uint32_t SPECIAL_ATTN = 0x20000000;
+constexpr uint32_t SBE_ATTN = 0x00000002;
+constexpr uint32_t CHECKSTOP_ATTN = 0x40000000;
+constexpr uint32_t SPECIAL_ATTN = 0x20000000;
+constexpr uint32_t RECOVERABLE_ATTN = 0x10000000;
// Need to add defaultOpalTiInfo with SRC BB821410 (ascii)
diff --git a/attn/attn_logging.cpp b/attn/attn_logging.cpp
index 55c782b..3fb0572 100644
--- a/attn/attn_logging.cpp
+++ b/attn/attn_logging.cpp
@@ -1,5 +1,6 @@
#include <unistd.h>
+#include <analyzer/analyzer_main.hpp>
#include <attn/attn_common.hpp>
#include <attn/attn_dbus.hpp>
#include <attn/attn_dump.hpp>
@@ -195,7 +196,7 @@
* here contains data to be committed to the PEL and it can also be used to
* create the PEL as it contains needed information.
*
- * @param i_buffer - buffer containing a raw PEL
+ * @param i_rawPel - buffer containing a raw PEL
* @param i_additional - additional data to be added to the new PEL
*/
void createPelCustom(std::vector<uint8_t>& i_rawPel,
@@ -211,6 +212,19 @@
uint8_t subsystem = std::stoi(i_additional["Subsystem"]);
tiPel->setSubsystem(subsystem);
+ // If recoverable attentions are active we will call the analyzer and
+ // then link the custom pel to analyzer pel.
+ std::map<std::string, std::string>::iterator it;
+ it = i_additional.find("recoverables");
+ if (it != i_additional.end() && "true" == it->second)
+ {
+ DumpParameters dumpParameters;
+ if (analyzer::analyzeHardware(dumpParameters))
+ {
+ tiPel->setPlid(dumpParameters.logId);
+ }
+ }
+
if (static_cast<uint8_t>(pel::SubsystemID::hypervisor) == subsystem)
{
// populate hypervisor SRC words
@@ -382,7 +396,7 @@
// If this is a TI event we will create an additional PEL that is
// specific to the subsystem that generated the TI.
- if ((true == tiEvent) && (0 != pelId))
+ if ((0 != pelId) && (true == tiEvent))
{
// get file descriptor and size of information PEL
int pelFd = getPel(pelId);
diff --git a/attn/pel/pel_minimal.cpp b/attn/pel/pel_minimal.cpp
index 11f589f..e245671 100644
--- a/attn/pel/pel_minimal.cpp
+++ b/attn/pel/pel_minimal.cpp
@@ -104,5 +104,10 @@
_eh->setSymptomId(symptomId);
}
+void PelMinimal::setPlid(uint32_t plid)
+{
+ _ph->setPlid(plid);
+}
+
} // namespace pel
} // namespace attn
diff --git a/attn/pel/pel_minimal.hpp b/attn/pel/pel_minimal.hpp
index ad07ab3..fb2da90 100644
--- a/attn/pel/pel_minimal.hpp
+++ b/attn/pel/pel_minimal.hpp
@@ -121,6 +121,11 @@
*/
void setSymptomId(const std::string& symptomId);
+ /**
+ * @brief Update the PLID
+ */
+ void setPlid(uint32_t plid);
+
private:
/**
* @brief Maximum PEL size
diff --git a/attn/pel/private_header.cpp b/attn/pel/private_header.cpp
index a610594..c724317 100644
--- a/attn/pel/private_header.cpp
+++ b/attn/pel/private_header.cpp
@@ -34,5 +34,10 @@
_sectionCount = sectionCount;
}
+void PrivateHeader::setPlid(uint32_t plid)
+{
+ _plid = plid;
+}
+
} // namespace pel
} // namespace attn
diff --git a/attn/pel/private_header.hpp b/attn/pel/private_header.hpp
index 6d447ee..d6739c7 100644
--- a/attn/pel/private_header.hpp
+++ b/attn/pel/private_header.hpp
@@ -104,6 +104,13 @@
*/
void setSectionCount(uint8_t sectionCount);
+ /**
+ * @brief Set the plid in this PEL
+ *
+ * @param[in] plid - platform log ID
+ */
+ void setPlid(uint32_t plid);
+
private:
/**
* @brief The creation time timestamp
diff --git a/attn/ti_handler.cpp b/attn/ti_handler.cpp
index 5e9f7a4..6d28458 100644
--- a/attn/ti_handler.cpp
+++ b/attn/ti_handler.cpp
@@ -74,6 +74,9 @@
// gather additional data for PEL
std::map<std::string, std::string> tiAdditionalData;
+ // make note of recoverable errors present
+ tiAdditionalData["recoverables"] = recoverableErrors() ? "true" : "false";
+
if (nullptr != i_tiDataArea)
{
parsePhypOpalTiInfo(tiAdditionalData, i_tiDataArea);
@@ -166,6 +169,10 @@
// gather additional data for PEL
std::map<std::string, std::string> tiAdditionalData;
+ // make note of recoverable errors present
+ tiAdditionalData["recoverables"] =
+ recoverableErrors() ? "true" : "false";
+
parseHbTiInfo(tiAdditionalData, i_tiDataArea);
tiAdditionalData["Subsystem"] = std::to_string(