summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-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
-rwxr-xr-xsrc/usr/fapi2/platCreateHwpErrParser.pl8
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/xmltohb.pl25
6 files changed, 117 insertions, 26 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)));
}
/**
diff --git a/src/usr/fapi2/platCreateHwpErrParser.pl b/src/usr/fapi2/platCreateHwpErrParser.pl
index e54f26a13..84fc84316 100755
--- a/src/usr/fapi2/platCreateHwpErrParser.pl
+++ b/src/usr/fapi2/platCreateHwpErrParser.pl
@@ -9,6 +9,7 @@
# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] Google Inc.
# [+] International Business Machines Corp.
+# [+] YADRO
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -78,13 +79,14 @@ print TGFILE "// This file is generated by perl script platCreateHwpErrParser.pl
print TGFILE "#ifndef HBFWPLATHWPERRPARSER_H_\n";
print TGFILE "#define HBFWPLATHWPERRPARSER_H_\n\n";
print TGFILE "#if defined(PARSER) || defined(LOGPARSER)\n\n";
+print TGFILE "#include \"errluserdetails.H\"\n\n";
print TGFILE "namespace fapi2\n";
print TGFILE "{\n\n";
print TGFILE "void hbfwParseHwpRc(ErrlUsrParser & i_parser,\n";
print TGFILE " void * i_pBuffer,\n";
print TGFILE " const uint32_t i_buflen)\n";
print TGFILE "{\n";
-print TGFILE " uint32_t l_rc = ntohl(*(static_cast<uint32_t *>(i_pBuffer)));\n";
+print TGFILE " uint32_t l_rc = ntohl(ERRORLOG::UINT32_FROM_PTR(i_pBuffer));\n";
print TGFILE " switch(l_rc)\n";
print TGFILE " {\n";
@@ -244,7 +246,7 @@ print TGFILE " uint8_t * l_pBuffer = static_cast<uint8_t *>(i_pBuffer);\n";
print TGFILE " uint32_t l_buflen = i_buflen;\n\n";
print TGFILE " // The first uint32_t is the FFDC ID\n";
print TGFILE " uint32_t * l_pFfdcId = static_cast<uint32_t *>(i_pBuffer);\n";
-print TGFILE " uint32_t l_ffdcId = ntohl(*l_pFfdcId);\n";
+print TGFILE " uint32_t l_ffdcId = ntohl(ERRORLOG::UINT32_FROM_PTR(l_pFfdcId));\n";
print TGFILE " l_pBuffer += sizeof(l_ffdcId);\n";
print TGFILE " l_buflen -= sizeof(l_ffdcId);\n";
print TGFILE " switch(l_ffdcId)\n";
@@ -365,7 +367,7 @@ foreach my $argnum (1 .. $#ARGV)
print TGFILE " if (l_buflen >= POS_LEN)\n";
print TGFILE " {\n";
print TGFILE " uint32_t * l_pBufferTemp = reinterpret_cast<uint32_t *>(l_pBuffer);\n";
- print TGFILE " i_parser.PrintNumber(\"Chip Position:\",\"%X\",ntohl(*l_pBufferTemp));\n";
+ print TGFILE " i_parser.PrintNumber(\"Chip Position:\",\"%X\",ntohl(ERRORLOG::UINT32_FROM_PTR(l_pBufferTemp)));\n";
print TGFILE " l_pBufferTemp = NULL;\n";
print TGFILE " l_pBuffer+= POS_LEN;\n";
print TGFILE " l_buflen -= POS_LEN;\n";
diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl
index 58a5261da..339c26960 100755
--- a/src/usr/targeting/common/xmltohb/xmltohb.pl
+++ b/src/usr/targeting/common/xmltohb/xmltohb.pl
@@ -8,6 +8,7 @@
#
# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
+# [+] YADRO
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -2980,7 +2981,7 @@ sub writeAttrErrlHFile {
print $outFile " for (; (l_ptr + sizeof(uint32_t)) <= ((uint8_t*)i_pBuffer + i_buflen); )\n";
print $outFile " {\n";
print $outFile " // first 4 bytes is the attr enum\n";
- print $outFile " uint32_t attrEnum = ntohl(*(uint32_t *)l_ptr);\n";
+ print $outFile " uint32_t attrEnum = ntohl(UINT32_FROM_PTR(l_ptr));\n";
print $outFile " l_ptr += sizeof(attrEnum);\n";
print $outFile " char* tmplabel = NULL;\n";
print $outFile "\n";
@@ -3112,21 +3113,21 @@ sub writeAttrErrlHFile {
elsif (exists $attribute->{simpleType}->{uint16_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 7);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(*(((uint16_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(UINT16_FROM_PTR(reinterpret_cast<const uint16_t*>(l_ptr) + i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(uint16_t);\n";
}
elsif (exists $attribute->{simpleType}->{uint32_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 11);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(*(((uint32_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(UINT32_FROM_PTR(reinterpret_cast<const uint32_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(uint32_t);\n";
}
elsif (exists $attribute->{simpleType}->{uint64_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 19);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(*(((uint64_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(UINT64_FROM_PTR(reinterpret_cast<const uint64_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(uint64_t);\n";
}
@@ -3140,21 +3141,21 @@ sub writeAttrErrlHFile {
elsif (exists $attribute->{simpleType}->{int16_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 7);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(*(((int16_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(INT16_FROM_PTR(reinterpret_cast<const int16_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(int16_t);\n";
}
elsif (exists $attribute->{simpleType}->{int32_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 11);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(*(((int32_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(INT32_FROM_PTR(reinterpret_cast<const int32_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(int32_t);\n";
}
elsif (exists $attribute->{simpleType}->{int64_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 19);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(*(((int64_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(INT64_FROM_PTR(reinterpret_cast<const int64_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(int64_t);\n";
}
@@ -3950,11 +3951,11 @@ sub writeTargetErrlHFile {
print $outFile " // first 4 are always the same\n";
print $outFile " if ((l_ptr32 + 4) <= (uint32_t *)((uint8_t*)i_pBuffer + i_buflen)) {\n";
- print $outFile " i_parser.PrintNumber( l_label, \"HUID = 0x%08X\", ntohl(*l_ptr32) );\n";
+ print $outFile " i_parser.PrintNumber( l_label, \"HUID = 0x%08X\", ntohl(UINT32_FROM_PTR(l_ptr32)) );\n";
print $outFile " l_ptr32++;\n";
# find CLASS
- print $outFile " switch (ntohl(*l_ptr32)) { // CLASS\n";
+ print $outFile " switch (ntohl(UINT32_FROM_PTR(l_ptr32))) { // CLASS\n";
foreach my $enumerationType (@{$attributes->{enumerationType}})
{
if( $enumerationType->{id} eq "CLASS" ) {
@@ -3973,7 +3974,7 @@ sub writeTargetErrlHFile {
print $outFile " l_ptr32++;\n";
# find TYPE
- print $outFile " switch (ntohl(*l_ptr32)) { // TYPE\n";
+ print $outFile " switch (ntohl(UINT32_FROM_PTR(l_ptr32))) { // TYPE\n";
foreach my $enumerationType (@{$attributes->{enumerationType}})
{
if( $enumerationType->{id} eq "TYPE" ) {
@@ -3992,7 +3993,7 @@ sub writeTargetErrlHFile {
print $outFile " l_ptr32++;\n";
# find MODEL
- print $outFile " switch (ntohl(*l_ptr32)) { // MODEL\n";
+ print $outFile " switch (ntohl(UINT32_FROM_PTR(l_ptr32))) { // MODEL\n";
foreach my $enumerationType (@{$attributes->{enumerationType}})
{
if( $enumerationType->{id} eq "MODEL" ) {
@@ -4030,7 +4031,7 @@ sub writeTargetErrlHFile {
}
}
- print $outFile " uint32_t l_pathType = ntohl(*l_ptr32);\n";
+ print $outFile " uint32_t l_pathType = ntohl(UINT32_FROM_PTR(l_ptr32));\n";
print $outFile " if ((l_pathType == $attrPhysPath) || // ATTR_PHYS_PATH\n";
print $outFile " (l_pathType == $attrAffinityPath)) // ATTR_AFFINITY_PATH\n";
print $outFile " {\n";
OpenPOWER on IntegriCloud