diff options
author | Artem Senichev <a.senichev@yadro.com> | 2019-09-30 13:41:12 +0300 |
---|---|---|
committer | Daniel M Crowell <dcrowell@us.ibm.com> | 2019-10-03 12:32:06 -0500 |
commit | ad8653d6a2db95816c5f36d9bfabad959e8a4427 (patch) | |
tree | 9f97083fa0365aaf4e165d1f0702ffcae892876e /src/usr/errl/plugins | |
parent | 3e7974342ab8082bc9b5fd6cb6faabc8df67a40e (diff) | |
download | talos-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.H | 7 | ||||
-rw-r--r-- | src/usr/errl/plugins/errludlogregister.H | 7 | ||||
-rw-r--r-- | src/usr/errl/plugins/errludwofdata.H | 5 | ||||
-rwxr-xr-x | src/usr/errl/plugins/errluserdetails.H | 91 |
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))); } /** |