summaryrefslogtreecommitdiffstats
path: root/src/usr/errl/plugins
diff options
context:
space:
mode:
authorArtem Senichev <a.senichev@yadro.com>2019-09-30 13:41:12 +0300
committerDaniel M Crowell <dcrowell@us.ibm.com>2019-10-03 12:32:06 -0500
commitad8653d6a2db95816c5f36d9bfabad959e8a4427 (patch)
tree9f97083fa0365aaf4e165d1f0702ffcae892876e /src/usr/errl/plugins
parent3e7974342ab8082bc9b5fd6cb6faabc8df67a40e (diff)
downloadtalos-hostboot-ad8653d6a2db95816c5f36d9bfabad959e8a4427.tar.gz
talos-hostboot-ad8653d6a2db95816c5f36d9bfabad959e8a4427.zip
errl: Fix data reading from unaligned pointers
Some architectures (like an ARM used in OpenBMC) do not support unaligned memory access. On these systems, reading an integral value from an unaligned pointer leads to undefined behavior. This patch doesn't change existing functionality, but forces the compiler to generate extra instructions to satisfy architectural alignment requirements. Resolves #185 Signed-off-by: Artem Senichev <a.senichev@yadro.com> Change-Id: I6e75044b93c26cca76336d17bb3886fab403253a Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/84520 Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Christian R Geddes <crgeddes@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/errl/plugins')
-rw-r--r--src/usr/errl/plugins/errludbacktrace.H7
-rw-r--r--src/usr/errl/plugins/errludlogregister.H7
-rw-r--r--src/usr/errl/plugins/errludwofdata.H5
-rwxr-xr-xsrc/usr/errl/plugins/errluserdetails.H91
4 files changed, 99 insertions, 11 deletions
diff --git a/src/usr/errl/plugins/errludbacktrace.H b/src/usr/errl/plugins/errludbacktrace.H
index 898ea8faa..9ecc11511 100644
--- a/src/usr/errl/plugins/errludbacktrace.H
+++ b/src/usr/errl/plugins/errludbacktrace.H
@@ -5,7 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* [+] YADRO */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -113,7 +116,7 @@ public:
for( int i = 0; i < l_count; i++ )
{
// endian convert the stack address
- uint64_t l_addr = ntohll(*p64);
+ uint64_t l_addr = ntohll(UINT64_FROM_PTR(p64));
// get nearest symbol
const char * l_pSymbol = symTab.nearestSymbol( l_addr );
diff --git a/src/usr/errl/plugins/errludlogregister.H b/src/usr/errl/plugins/errludlogregister.H
index b201e05d9..221458022 100644
--- a/src/usr/errl/plugins/errludlogregister.H
+++ b/src/usr/errl/plugins/errludlogregister.H
@@ -8,6 +8,7 @@
/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -79,7 +80,7 @@ public:
{
// first is the HUID
uint32_t *pData = reinterpret_cast<uint32_t *>(pBuf);
- if (ntohl(*pData) == 0xFFFFFFFF)
+ if (ntohl(UINT32_FROM_PTR(pData)) == 0xFFFFFFFF)
{
i_parser.PrintString("LogRegister",
"Target: MASTER_PROCESSOR_CHIP_TARGET_SENTINEL");
@@ -87,7 +88,7 @@ public:
else
{
i_parser.PrintNumber( "LogRegister",
- "Target: HUID = 0x%08X", ntohl(*pData) );
+ "Target: HUID = 0x%08X", ntohl(UINT32_FROM_PTR(pData)) );
}
pData++;
pBuf += sizeof(*pData);
@@ -204,7 +205,7 @@ public:
for (int32_t i = 0;i < numArgs;i++)
{
std::vector<char> l_traceEntry(20);
- sprintf(&(l_traceEntry[0]),"0x%016llX", ntohll(*pData64));
+ sprintf(&(l_traceEntry[0]),"0x%016llX", ntohll(UINT64_FROM_PTR(pData64)));
i_parser.PrintString(addrParams[i], &(l_traceEntry[0]));
pData64++;
diff --git a/src/usr/errl/plugins/errludwofdata.H b/src/usr/errl/plugins/errludwofdata.H
index f792c5485..203a4a14e 100644
--- a/src/usr/errl/plugins/errludwofdata.H
+++ b/src/usr/errl/plugins/errludwofdata.H
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -98,7 +99,7 @@ public:
// addWofCompareDataToErrl() in plat_wof_access.C
if ((NULL != i_pBuffer) && (i_buflen >= sizeof(tableEntries)))
{
- tableEntries = ntohs(*(reinterpret_cast<uint16_t*>(i_pBuffer)));
+ tableEntries = ntohs(UINT16_FROM_PTR(i_pBuffer));
}
// How many entries are really present in this buffer?
diff --git a/src/usr/errl/plugins/errluserdetails.H b/src/usr/errl/plugins/errluserdetails.H
index 917dcf266..eac453505 100755
--- a/src/usr/errl/plugins/errluserdetails.H
+++ b/src/usr/errl/plugins/errluserdetails.H
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -39,6 +40,88 @@ namespace ERRORLOG
{
/**
+ * @struct UnalignedData
+ * @brief Structure used for safe assigment from unaligned pointer, it forces
+ * the compiler to generate extra instructions and satisfy architectural
+ * alignment requirements.
+ */
+template<typename T> struct UnalignedData {
+ T value;
+} __attribute__ ((packed));
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pUint64 - Pointer to uint64_t value
+ *
+ * @return uint64_t value from specified pointer
+ */
+inline uint64_t UINT64_FROM_PTR(const void* i_pUint64)
+{
+ return reinterpret_cast<const UnalignedData<uint64_t>*>(i_pUint64)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pUint32 - Pointer to uint32_t value
+ *
+ * @return uint32_t value from specified pointer
+ */
+inline uint32_t UINT32_FROM_PTR(const void* i_pUint32)
+{
+ return reinterpret_cast<const UnalignedData<uint32_t>*>(i_pUint32)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pUint16 - Pointer to uint16_t value
+ *
+ * @return uint16_t value from specified pointer
+ */
+inline uint16_t UINT16_FROM_PTR(const void* i_pUint16)
+{
+ return reinterpret_cast<const UnalignedData<uint16_t>*>(i_pUint16)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pInt64 - Pointer to int64_t value
+ *
+ * @return int64_t value from specified pointer
+ */
+inline int64_t INT64_FROM_PTR(const void* i_pInt64)
+{
+ return reinterpret_cast<const UnalignedData<int64_t>*>(i_pInt64)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pInt32 - Pointer to int32_t value
+ *
+ * @return int32_t value from specified pointer
+ */
+inline int32_t INT32_FROM_PTR(const void* i_pInt32)
+{
+ return reinterpret_cast<const UnalignedData<int32_t>*>(i_pInt32)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pInt16 - Pointer to int16_t value
+ *
+ * @return int16_t value from specified pointer
+ */
+inline int16_t INT16_FROM_PTR(const void* i_pInt16)
+{
+ return reinterpret_cast<const UnalignedData<int16_t>*>(i_pInt16)->value;
+}
+
+/**
* @brief Returns the uint64_t at the pointed to location in host byte order
*
* @param[in] i_pUint64 Pointer to a uint64_t in network byte order
@@ -47,7 +130,7 @@ namespace ERRORLOG
*/
inline uint64_t NTH_UINT64(const void* i_pUint64)
{
- return (ntohll(*(reinterpret_cast<const uint64_t*>(i_pUint64))));
+ return (ntohll(UINT64_FROM_PTR(i_pUint64)));
}
/**
@@ -59,7 +142,7 @@ inline uint64_t NTH_UINT64(const void* i_pUint64)
*/
inline uint32_t NTH_UINT32(const void* i_pUint32)
{
- return (ntohl(*(reinterpret_cast<const uint32_t*>(i_pUint32))));
+ return (ntohl(UINT32_FROM_PTR(i_pUint32)));
}
/**
@@ -71,7 +154,7 @@ inline uint32_t NTH_UINT32(const void* i_pUint32)
*/
inline uint16_t NTH_UINT16(const void* i_pUint16)
{
- return (ntohs(*(reinterpret_cast<const uint16_t*>(i_pUint16))));
+ return (ntohs(UINT16_FROM_PTR(i_pUint16)));
}
/**
OpenPOWER on IntegriCloud