Attn: Add some sanity checking for TI info pointer

Add some nullptr checks for TI info. An earlier commit should ensure
that this pointer is never null however during debug it proved useful
to verify this in a few places.

Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: Idae4a9dd22d61bbac5e76f0a79059efb69981e03
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
index 34de90d..c41e231 100644
--- a/attn/attn_handler.cpp
+++ b/attn/attn_handler.cpp
@@ -241,6 +241,8 @@
     uint32_t tiInfoLen    = 0;                        // length of TI info data
     pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
 
+    bool tiInfoStatic = false; // assume TI info was provided (not created)
+
     if (attnProc != nullptr)
     {
         // The processor PIB target is required for get TI info chipop
@@ -256,7 +258,8 @@
                 if (tiInfo == nullptr)
                 {
                     trace<level::INFO>("TI info data ptr is null after call");
-                    tiInfo = (uint8_t*)defaultPhypTiInfo;
+                    tiInfo       = (uint8_t*)defaultPhypTiInfo;
+                    tiInfoStatic = true; // using our TI info
                 }
             }
         }
@@ -345,7 +348,7 @@
     }
 
     // release TI data buffer
-    if (nullptr != tiInfo)
+    if ((nullptr != tiInfo) && (false == tiInfoStatic))
     {
         free(tiInfo);
     }
diff --git a/attn/attn_handler.hpp b/attn/attn_handler.hpp
index 8923387..ad3181d 100644
--- a/attn/attn_handler.hpp
+++ b/attn/attn_handler.hpp
@@ -14,6 +14,13 @@
     RC_CFAM_ERROR
 };
 
+/** @brief Attention handler return codes */
+enum AttnCodes
+{
+    ATTN_NO_ERROR  = 0,
+    ATTN_INFO_NULL = 1
+};
+
 /** @brief Attention global status bits */
 constexpr uint32_t SBE_ATTN       = 0x00000002;
 constexpr uint32_t CHECKSTOP_ATTN = 0x40000000;
diff --git a/attn/attn_logging.cpp b/attn/attn_logging.cpp
index f50aba5..f8a34b1 100644
--- a/attn/attn_logging.cpp
+++ b/attn/attn_logging.cpp
@@ -329,7 +329,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)
+        if ((true == tiEvent) && (0 != pelId))
         {
             // get file descriptor and size of information PEL
             int pelFd = getPel(pelId);
@@ -375,22 +375,27 @@
 void eventTerminate(std::map<std::string, std::string> i_additionalData,
                     char* i_tiInfoData)
 {
-    uint32_t tiInfoSize = 56; // assume not hypervisor TI
 
-    uint8_t subsystem = std::stoi(i_additionalData["Subsystem"]);
+    uint32_t tiInfoSize = 0; // assume TI info was not available
 
-    // If hypervisor
-    if (static_cast<uint8_t>(pel::SubsystemID::hypervisor) == subsystem)
+    if (nullptr != i_tiInfoData)
     {
-        tiInfoSize = 1024; // assume hypervisor max
+        tiInfoSize = 56; // assume not hypervisor TI
 
-        // hypervisor may just want some of the data
-        if (0 == (*(i_tiInfoData + 0x09) & 0x01))
+        uint8_t subsystem = std::stoi(i_additionalData["Subsystem"]);
+
+        // If hypervisor
+        if (static_cast<uint8_t>(pel::SubsystemID::hypervisor) == subsystem)
         {
-            uint32_t* additionalLength = (uint32_t*)(i_tiInfoData + 0x50);
-            uint32_t tiAdditional      = be32toh(*additionalLength);
+            tiInfoSize = 1024; // assume hypervisor max
 
-            tiInfoSize = std::min(tiInfoSize, (84 + tiAdditional));
+            // hypervisor may just want some of the data
+            if (0 == (*(i_tiInfoData + 0x09) & 0x01))
+            {
+                uint32_t* additionalLength = (uint32_t*)(i_tiInfoData + 0x50);
+                uint32_t tiAdditional      = be32toh(*additionalLength);
+                tiInfoSize = std::min(tiInfoSize, (84 + tiAdditional));
+            }
         }
     }
 
diff --git a/attn/ti_handler.cpp b/attn/ti_handler.cpp
index 77b1df7..f04f111 100644
--- a/attn/ti_handler.cpp
+++ b/attn/ti_handler.cpp
@@ -43,10 +43,10 @@
     }
     else
     {
-        // TI data was not available, assume PHYP TI for now. When a host state
-        // management interface becomes availabe we may be able to make a more
-        // informed decision here.
-        handlePhypTi(i_tiDataArea);
+        // TI data was not available This should not happen since we provide
+        // a default TI info in the case where get TI info was not successful.
+        eventAttentionFail(ATTN_INFO_NULL);
+        rc = RC_NOT_HANDLED;
     }
 
     return rc;
@@ -83,19 +83,26 @@
     if (nullptr != i_tiDataArea)
     {
         parsePhypOpalTiInfo(tiAdditionalData, i_tiDataArea);
+
+        tiAdditionalData["Subsystem"] =
+            std::to_string(static_cast<uint8_t>(pel::SubsystemID::hypervisor));
+
+        // copy ascii src chars to additional data
+        char srcChar[9]; // 8 char src + null term
+        memcpy(srcChar, &(i_tiDataArea->asciiData0), 4);
+        memcpy(&srcChar[4], &(i_tiDataArea->asciiData1), 4);
+        srcChar[8]                   = 0;
+        tiAdditionalData["SrcAscii"] = std::string{srcChar};
+
+        // TI event
+        eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
     }
-
-    tiAdditionalData["Subsystem"] =
-        std::to_string(static_cast<uint8_t>(pel::SubsystemID::hypervisor));
-
-    // copy ascii src chars to additional data
-    char srcChar[9]; // 8 char src + null term
-    memcpy(srcChar, &(i_tiDataArea->asciiData0), 4);
-    memcpy(&srcChar[4], &(i_tiDataArea->asciiData1), 4);
-    srcChar[8]                   = 0;
-    tiAdditionalData["SrcAscii"] = std::string{srcChar};
-
-    eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
+    else
+    {
+        // TI data was not available This should not happen since we provide
+        // a default TI info in the case where get TI info was not successful.
+        eventAttentionFail(ATTN_INFO_NULL);
+    }
 }
 
 /**
@@ -231,19 +238,25 @@
     if (nullptr != i_tiDataArea)
     {
         parseHbTiInfo(tiAdditionalData, i_tiDataArea);
+
+        if (true == generatePel)
+        {
+            tiAdditionalData["Subsystem"] = std::to_string(
+                static_cast<uint8_t>(pel::SubsystemID::hostboot));
+
+            char srcChar[8];
+            memcpy(srcChar, &(i_tiDataArea->srcWord12HbWord0), 4);
+            memcpy(&srcChar[4], &(i_tiDataArea->asciiData1), 4);
+            tiAdditionalData["SrcAscii"] = std::string{srcChar};
+
+            eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
+        }
     }
-
-    if (true == generatePel)
+    else
     {
-        tiAdditionalData["Subsystem"] =
-            std::to_string(static_cast<uint8_t>(pel::SubsystemID::hostboot));
-
-        char srcChar[8];
-        memcpy(srcChar, &(i_tiDataArea->srcWord12HbWord0), 4);
-        memcpy(&srcChar[4], &(i_tiDataArea->asciiData1), 4);
-        tiAdditionalData["SrcAscii"] = std::string{srcChar};
-
-        eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
+        // TI data was not available This should not happen since we provide
+        // a default TI info in the case where get TI info was not successful.
+        eventAttentionFail(ATTN_INFO_NULL);
     }
 }