diff options
author | Ilya Smirnov <ismirno@us.ibm.com> | 2018-09-26 10:35:24 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-11-13 13:23:59 -0600 |
commit | 1aae1ba2930ceb5d72b9855c8003c1d8371c0791 (patch) | |
tree | 4da3ed64fb3558db00e68b659c9bfdde79d26258 /src | |
parent | de9ec8dc9ca52d350d02c0862409fba939692c1e (diff) | |
download | talos-hostboot-1aae1ba2930ceb5d72b9855c8003c1d8371c0791.tar.gz talos-hostboot-1aae1ba2930ceb5d72b9855c8003c1d8371c0791.zip |
Move HOMER BAR to Secure Memory in SMF Mode
This commits enables HOMER BAR to point to the top
of the secure memory on SMF-enabled systems. Consequently,
the HOMER image and hostboot reserved memory will
be moved to the secure memory if SMF is enabled.
Change-Id: I37c7527b06688a41e57f14b4107ff53a507ffae8
RTC: 198825
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66702
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@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/include/usr/isteps/istep15list.H | 1 | ||||
-rw-r--r-- | src/include/usr/isteps/mem_utils.H | 103 | ||||
-rw-r--r-- | src/include/usr/secureboot/secure_reasoncodes.H | 2 | ||||
-rw-r--r-- | src/include/usr/secureboot/smf_utils.H | 62 | ||||
-rw-r--r-- | src/include/usr/targeting/common/util.H | 26 | ||||
-rw-r--r-- | src/include/usr/targeting/targplatutil.H | 14 | ||||
-rw-r--r-- | src/makefile | 1 | ||||
-rw-r--r-- | src/usr/isteps/istep07/call_mss_attr_update.C | 2 | ||||
-rw-r--r-- | src/usr/isteps/istep14/call_proc_exit_cache_contained.C | 2 | ||||
-rw-r--r-- | src/usr/isteps/istep15/host_build_stop_image.C | 53 | ||||
-rw-r--r-- | src/usr/isteps/istep15/makefile | 2 | ||||
-rw-r--r-- | src/usr/isteps/makefile | 1 | ||||
-rw-r--r-- | src/usr/isteps/mem_utils.C | 216 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 5 | ||||
-rw-r--r-- | src/usr/secureboot/common/common.mk | 3 | ||||
-rw-r--r-- | src/usr/secureboot/makefile | 1 | ||||
-rw-r--r-- | src/usr/secureboot/smf/makefile | 32 | ||||
-rw-r--r-- | src/usr/secureboot/smf/smf_utils.C | 110 | ||||
-rw-r--r-- | src/usr/targeting/common/util.C | 108 | ||||
-rw-r--r-- | src/usr/testcore/rtloader/loader.H | 3 |
20 files changed, 562 insertions, 185 deletions
diff --git a/src/include/usr/isteps/istep15list.H b/src/include/usr/isteps/istep15list.H index f7bc1470c..d32145d0c 100644 --- a/src/include/usr/isteps/istep15list.H +++ b/src/include/usr/isteps/istep15list.H @@ -141,6 +141,7 @@ const DepModInfo g_istep15Dependancies = { DEP_LIB(libpm.so), DEP_LIB(libimageprocs.so), DEP_LIB(libisteps_mss.so), + DEP_LIB(libsmf.so), NULL } }; diff --git a/src/include/usr/isteps/mem_utils.H b/src/include/usr/isteps/mem_utils.H new file mode 100644 index 000000000..2ab47d052 --- /dev/null +++ b/src/include/usr/isteps/mem_utils.H @@ -0,0 +1,103 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/isteps/mem_utils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __MEM_UTILS_H +#define __MEM_UTILS_H + +#include <errl/errlentry.H> + +namespace ISTEP +{ + +/** + * @brief Utility function to obtain the highest known address in the system + * + * @return The highest address in the system in bytes + */ +uint64_t get_top_mem_addr(); + +/** + * @brief Utility function to obtain the highest known address in a given proc + * + * @param[in] i_proc: Proc that we want to calculate the top address for; + * must not be nullptr or the func will assert + * must be of TYPE_PROC or the func will assert + * + * @return The highest address in the given proc (in bytes) + */ +uint64_t get_top_mem_addr(const TARGETING::Target* i_proc); + +/** + * @brief Utility function to obtain the lowest known address in the system + * + * @return the lowest know address in the system + */ +uint64_t get_bottom_mem_addr(); + +/** + * @brief Utility function to obtain the lowest known address in a given proc + * + * @param[in] i_proc: Proc that we want to calculate the bottom address for; + * must not be nullptr or the func will assert + * must be of TYPE_PROC or the func will assert + * + * @return the lowest know address on the specified proc + */ +uint64_t get_bottom_mem_addr(const TARGETING::Target* i_proc); + +/** + * @brief Utility function to obtain the highest known SMF base address on + * the system. + * + * @return: the address (in bytes) of the top SMF memory + * + */ +uint64_t get_top_smf_mem_addr(); + +/** + * @brief Utility function to obtain the SMF base address on the given proc + * + * @param[in] i_proc: Proc to fetch the SMF BAR from; + * must not be nullptr or the func will assert + * must be of TYPE_PROC or the func will assert + * + * + * @return The SMF BAR of the given proc (in bytes) + */ +uint64_t get_top_smf_mem_addr(const TARGETING::Target* i_proc); + +/** + * @brief Utility function to fetch the top of the HOMER memory + * + * @return the address of the HOMER mem + * + * @note When SMF is enabled, the highest available SMF BAR will be returned; + * when SMF is disabled, the function behaves exactly like + * get_top_mem_addr + */ +uint64_t get_top_homer_mem_addr(); + +} //namespace ISTEP + +#endif diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H index 2f2ec75ef..7188b4e4f 100644 --- a/src/include/usr/secureboot/secure_reasoncodes.H +++ b/src/include/usr/secureboot/secure_reasoncodes.H @@ -50,6 +50,7 @@ namespace SECUREBOOT MOD_SECURE_VALIDATE_ECID_COUNT = 0x10, MOD_LOCK_ABUS_SEC_MAILBOXES = 0x11, MOD_SECURE_LOG_PLAT_SECURITY_CONFIG = 0x12, + MOD_CHECK_RISK_LEVEL_FOR_SMF = 0x13, // Use 0x20-0x2F range for Node Communications MOD_NCDD_CHECK_FOR_ERRORS = 0x20, @@ -89,6 +90,7 @@ namespace SECUREBOOT RC_INVALID_ECID_COUNT = SECURE_COMP_ID | 0x13, RC_LOCK_MAILBOXES_FAILED = SECURE_COMP_ID | 0x14, RC_SECURE_LOG_PLAT_SECURITY_CONFIG = SECURE_COMP_ID | 0x15, + RC_RISK_LEVEL_TOO_LOW = SECURE_COMP_ID | 0x16, // Use 0x20-0x2F range for Node Communications RC_NCDD_HW_ERROR_FOUND = SECURE_COMP_ID | 0x20, diff --git a/src/include/usr/secureboot/smf_utils.H b/src/include/usr/secureboot/smf_utils.H new file mode 100644 index 000000000..554f8affe --- /dev/null +++ b/src/include/usr/secureboot/smf_utils.H @@ -0,0 +1,62 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/secureboot/smf_utils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __SMF_UTILS_H +#define __SMF_UTILS_H + +#include <stdint.h> +#include <errl/errlentry.H> + +namespace SECUREBOOT +{ + +namespace SMF +{ + +// HW limitations dictate that SMF memory needs to be a power-of-two +// multiple of 256MB starting with 256MB. +extern const uint64_t MIN_SMF_MEMORY_AMT; + +/** + * @brief Checks whether SMF mode is enabled on the system + * + * @return true: SMF is enabled; false: SMF is disabled. + */ +bool isSmfEnabled(); + +/** + * @brief Checks whether the system has the correct risk level to + * support SMF: SMF is supported on Axone by default or on + * NIMBUS or CUMULUS with risk level >= 4. + * + * @return nullptr: the current system supports SMF + * non-nullptr: an internal error occurred or the system + * does not support SMF + */ +errlHndl_t checkRiskLevelForSmf(); + +} // namespace SMF + +} // namespace SECUREBOOT +#endif diff --git a/src/include/usr/targeting/common/util.H b/src/include/usr/targeting/common/util.H index 479cdfa75..68b61b1f1 100644 --- a/src/include/usr/targeting/common/util.H +++ b/src/include/usr/targeting/common/util.H @@ -156,30 +156,6 @@ bool is_sapphire_load(void); bool is_avp_load(void); /** - * @brief Utility function to obtain the highest known address in the system - */ -uint64_t get_top_mem_addr(); - -/** - * @brief Utility function to obtain the highest known address in a given proc - * - * @param[in] i_proc: Proc that we want to calculate the top address for - */ -uint64_t get_top_mem_addr(Target* i_proc); - -/** - * @brief Utility function to obtain the lowest known address in the system - */ -uint64_t get_bottom_mem_addr(); - -/** - * @brief Utility function to obtain the lowest known address in a given proc - * - * @param[in] i_proc: Proc that we want to calculate the bottom address for - */ -uint64_t get_bottom_mem_addr(Target* i_proc); - -/** * Order two processor targets by NODE_ID then CHIP_ID. * @param[in] First processor target * @param[in] Second processor target @@ -196,6 +172,6 @@ bool orderByNodeAndPosition( Target* i_firstProc, */ uint8_t is_fused_mode( ); -} +} // TARGETING #endif // __TARGETING_COMMON_UTIL_H diff --git a/src/include/usr/targeting/targplatutil.H b/src/include/usr/targeting/targplatutil.H index c13f1a0a8..34d8bebc0 100644 --- a/src/include/usr/targeting/targplatutil.H +++ b/src/include/usr/targeting/targplatutil.H @@ -58,6 +58,20 @@ namespace UTIL // is reserved for invalid sensor static const uint16_t INVALID_IPMI_SENSOR = 0xFF; + // WARNING: addition of risk levels that don't support SMF will have a + // significant effect on the behavior of SMF code. Please ensure that + // (at least) src/usr/secureboot/smf/smf_utils.C is updated + // accordingly! + typedef enum + { + P9N22_P9C12_RUGBY_FAVOR_SECURITY = 0x00, + P9N22_P9C12_RUGBY_FAVOR_PERFORMANCE = 0x01, + P9N22_NO_RUGBY_MITIGATIONS = 0x02, + P9N22_P9N23_JAVA_PERF = 0x03, + P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_SECURITY = 0x04, + P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_PERFORMANCE = 0x05, + } Risk_level; + /** * @brief Creates a standard error log of tracing type * diff --git a/src/makefile b/src/makefile index c2e48e6d6..d4a22f2df 100644 --- a/src/makefile +++ b/src/makefile @@ -213,6 +213,7 @@ EXTENDED_MODULES += node_comm EXTENDED_MODULES += $(if $(CONFIG_NVDIMM),nvdimm) EXTENDED_MODULES += $(if $(CONFIG_FSP_BUILD),,nvram) EXTENDED_MODULES += mmio +EXTENDED_MODULES += smf #*************************************** # Working test modules diff --git a/src/usr/isteps/istep07/call_mss_attr_update.C b/src/usr/isteps/istep07/call_mss_attr_update.C index 4ebd3d099..4e015d7b8 100644 --- a/src/usr/isteps/istep07/call_mss_attr_update.C +++ b/src/usr/isteps/istep07/call_mss_attr_update.C @@ -70,6 +70,8 @@ //HRMOR #include <sys/misc.h> +#include <isteps/mem_utils.H> + namespace ISTEP_07 { diff --git a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C index a5cc132c1..92cbc8fe5 100644 --- a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C +++ b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C @@ -58,6 +58,8 @@ #include <scom/centaurScomCache.H> #endif +#include <isteps/mem_utils.H> + using namespace ISTEP; using namespace ISTEP_ERROR; using namespace ERRORLOG; diff --git a/src/usr/isteps/istep15/host_build_stop_image.C b/src/usr/isteps/istep15/host_build_stop_image.C index 36b8c2304..d40125b95 100644 --- a/src/usr/isteps/istep15/host_build_stop_image.C +++ b/src/usr/isteps/istep15/host_build_stop_image.C @@ -69,6 +69,9 @@ #include <p9_xip_section_append.H> #include <p9n2_quad_scom_addresses_fld.H> +#include <secureboot/smf_utils.H> +#include <isteps/mem_utils.H> + using namespace ERRORLOG; using namespace ISTEP; using namespace ISTEP_ERROR; @@ -173,62 +176,18 @@ errlHndl_t applyHcodeGenCpuRegs( TARGETING::Target *i_procChipTarg, uint64_t l_msrVal = cpu_spr_value(CPU_SPR_MSR); uint64_t l_lpcrVal = cpu_spr_value(CPU_SPR_LPCR); - uint8_t l_smfEnabled = 0; - fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SMF_ENABLED, - FAPI_SYSTEM, - l_smfEnabled)); - - if(l_smfEnabled) + if(SECUREBOOT::SMF::isSmfEnabled()) { - uint8_t l_riskLevel = 0; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_RISK_LEVEL, - FAPI_SYSTEM, - l_riskLevel)); - TARGETING::Target* l_pMasterProc = nullptr; - l_errl = TARGETING::targetService() - .queryMasterProcChipTargetHandle(l_pMasterProc); + l_errl = SECUREBOOT::SMF::checkRiskLevelForSmf(); if(l_errl) { break; } - auto l_masterProcModel =l_pMasterProc->getAttr<TARGETING::ATTR_MODEL>(); - - // SMF is enabled by default on Axone, so need to check the risk level - // only on P9C/P9N. - if(l_riskLevel < 4 && - ((l_masterProcModel == TARGETING::MODEL_CUMULUS) || - (l_masterProcModel == TARGETING::MODEL_NIMBUS))) - { - /*@ - * @errortype - * @reasoncode ISTEP::RC_RISK_LEVEL_TOO_LOW - * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE - * @moduleid ISTEP::MOD_APPLY_HCODE_GEN_CPU_REGS - * @userdata1 Current risk level of the system - * @devdesc SMF is enabled on the system of incorrect risk level - * @custdesc A problem occurred during the IPL of the system. - */ - l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - ISTEP::MOD_APPLY_HCODE_GEN_CPU_REGS, - ISTEP::RC_RISK_LEVEL_TOO_LOW, - l_riskLevel, - 0, - ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); - break; - } - // Set the secure bit (41) on if SMF is enabled l_msrVal |= MSR_SMF_MASK; } - if(l_errl) - { -fapi_try_exit: - break; - } - // See LPCR def, PECE "reg" in Power ISA AS Version: Power8 June 27, 2012 // and 23.7.3.5 - 6 in Murano Book 4 l_lpcrVal &= ~(0x0000000000002000) ; @@ -482,7 +441,7 @@ void* host_build_stop_image (void *io_pArgs) //If running Sapphire need to place this at the top of memory instead if(is_sapphire_load()) { - l_memBase = get_top_mem_addr(); + l_memBase = get_top_homer_mem_addr(); assert (l_memBase != 0, "host_build_stop_image: Top of memory was 0!"); l_memBase -= VMM_ALL_HOMER_OCC_MEMORY_SIZE; diff --git a/src/usr/isteps/istep15/makefile b/src/usr/isteps/istep15/makefile index fedb5b0a0..90b6e25bf 100644 --- a/src/usr/isteps/istep15/makefile +++ b/src/usr/isteps/istep15/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2015,2017 +# Contributors Listed Below - COPYRIGHT 2015,2018 # [+] International Business Machines Corp. # # diff --git a/src/usr/isteps/makefile b/src/usr/isteps/makefile index 920eae593..e5aa9935d 100644 --- a/src/usr/isteps/makefile +++ b/src/usr/isteps/makefile @@ -65,6 +65,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/ +OBJS += mem_utils.o OBJS += hwpisteperror.o OBJS += hwpistepud.o OBJS += istepHelperFuncs.o diff --git a/src/usr/isteps/mem_utils.C b/src/usr/isteps/mem_utils.C new file mode 100644 index 000000000..89961ef5e --- /dev/null +++ b/src/usr/isteps/mem_utils.C @@ -0,0 +1,216 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/mem_utils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include <isteps/mem_utils.H> +#include <targeting/common/target.H> +#include <targeting/common/utilFilter.H> +#include <errl/hberrltypes.H> +#include <secureboot/smf_utils.H> +#include <stdint.h> + +namespace ISTEP +{ + +/** + * @brief Utility function to obtain the highest known address in the system + */ +uint64_t get_top_mem_addr() +{ + uint64_t l_top_addr = 0; + + do + { + // Get all functional proc chip targets + TARGETING::TargetHandleList l_cpuTargetList; + TARGETING::getAllChips(l_cpuTargetList, TARGETING::TYPE_PROC); + assert(l_cpuTargetList.size() != 0, "Empty proc list returned!"); + + for (auto l_pProc : l_cpuTargetList) + { + l_top_addr = std::max(l_top_addr, get_top_mem_addr(l_pProc)); + } + + } while(0); + + return l_top_addr; +} + +/** + * @brief Utility function to obtain the highest known address in a given proc + */ +uint64_t get_top_mem_addr(const TARGETING::Target* i_proc) +{ + uint64_t l_top_addr = 0; + + assert(i_proc, "nullptr passed to get_top_mem_addr"); + assert(i_proc->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_PROC, + "Invalid target passed to get_top_mem_addr (need TYPE_PROC)"); + + //Not checking success here as fail results in no change to + // top_addr + uint64_t l_mem_bases[8] = {0,}; + uint64_t l_mem_sizes[8] = {0,}; + i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_mem_bases); + i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>(l_mem_sizes); + + for (size_t i=0; i< 8; i++) + { + if(l_mem_sizes[i]) //non zero means that there is memory present + { + l_top_addr = std::max(l_top_addr, + l_mem_bases[i] + l_mem_sizes[i]); + } + } + + return l_top_addr; +} + +/** + * @brief Utility function to obtain the lowest known address in the system + */ +uint64_t get_bottom_mem_addr() +{ + uint64_t l_bottom_addr = UINT64_MAX; + + do + { + // Get all functional proc chip targets + TARGETING::TargetHandleList l_cpuTargetList; + TARGETING::getAllChips(l_cpuTargetList, TARGETING::TYPE_PROC); + + for (const auto l_pProc : l_cpuTargetList) + { + l_bottom_addr =std::min(l_bottom_addr,get_bottom_mem_addr(l_pProc)); + } + }while(0); + + // There's no reason the lowest address should be the largest + // 64 bit value + assert(l_bottom_addr < UINT64_MAX, + "Lowest address is maximum 64-bit value, probably have no memory"); + + return l_bottom_addr; +} + +/** + * @brief Utility function to obtain the lowest known address in a given proc + */ +uint64_t get_bottom_mem_addr(const TARGETING::Target* i_proc) +{ + uint64_t l_bottom_addr = UINT64_MAX; + + assert(i_proc, "nullptr passed to get_bottom_mem_addr"); + assert(i_proc->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_PROC, + "Invalid target passed to get_bottom_mem_addr (need TYPE_PROC)"); + + uint64_t l_mem_bases[8] = {}; + uint64_t l_mem_sizes[8] = {}; + assert(i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_mem_bases), + "Unable to get ATTR_PROC_MEM_BASES attribute"); + + assert(i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>(l_mem_sizes), + "Unable to get ATTR_PROC_MEM_SIZES attribute"); + + for (size_t i=0; i< 8; i++) + { + if(l_mem_sizes[i]) //non zero means that there is memory present + { + l_bottom_addr = std::min(l_bottom_addr, l_mem_bases[i]); + } + } + + return l_bottom_addr; +} + +/** + * @brief Utility function to obtain the highest known SMF base address on + * the system + */ +uint64_t get_top_smf_mem_addr() +{ + uint64_t l_top_addr = 0; + // Get all functional proc chip targets + TARGETING::TargetHandleList l_cpuTargetList; + TARGETING::getAllChips(l_cpuTargetList, TARGETING::TYPE_PROC); + assert(l_cpuTargetList.size() != 0, "Empty proc list returned!"); + + for (const auto l_pProc : l_cpuTargetList) + { + l_top_addr = std::max(l_top_addr, get_top_smf_mem_addr(l_pProc)); + } + + return l_top_addr; +} + +/** + * @brief Utility function to obtain the highest SMF base address on the + * given proc + */ +uint64_t get_top_smf_mem_addr(const TARGETING::Target* i_proc) +{ + uint64_t l_top_addr = 0; + + assert(i_proc, "nullptr passed to get_top_smf_mem_addr"); + assert(i_proc->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_PROC, + "Invalid target passed to get_top_smf_mem_addr (need TYPE_PROC)"); + + auto l_smf_bar = + i_proc->getAttr<TARGETING::ATTR_PROC_SMF_BAR_BASE_ADDR>(); + auto l_smf_size = + i_proc->getAttr<TARGETING::ATTR_PROC_SMF_BAR_SIZE>(); + + l_top_addr = l_smf_bar + l_smf_size; + + return l_top_addr; +} + +/** + * @brief Utility function to fetch the top of the HOMER memory; + * when SMF is enabled, the function will return the highest + * available SMF BAR on a proc, so the top of the HOMER memory + * will be pointed to the top of SMF memory, and all of the + * contents will be put in secure memory space. When SMF is not + * enabled, the function will return the highest known address + * on the system. + */ +uint64_t get_top_homer_mem_addr() +{ + uint64_t l_top_homer_addr = 0; + do + { + if(SECUREBOOT::SMF::isSmfEnabled()) + { + l_top_homer_addr = get_top_smf_mem_addr(); + } + else + { + l_top_homer_addr = get_top_mem_addr(); + } + + }while(0); + + return l_top_homer_addr; +} + +} // namespace ISTEP diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index 340ee3de7..5c0596f35 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -80,6 +80,7 @@ #include <errno.h> #include <vmmconst.h> #include <runtime/customize_attrs_for_payload.H> +#include <isteps/mem_utils.H> namespace RUNTIME { @@ -1171,7 +1172,7 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node) // "supported offset values are all values of the // form i x 2 exp `r`, where 0 <= i <= 2 exp `j`, and j and r are // implementation-dependent values having the properties that - // 12 <= r <= 26". (Texted quoted from PowerISA Doc) + // 12 <= r <= 26". (Texted quoted from PowerISA Doc) // Basis the above, value of r is 26, which sets the offset // granularity to 64MB, therefore value of i is '2', which makes the // offset to 128MB. @@ -1201,7 +1202,7 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node) } } // Opal data goes at top_of_mem - l_topMemAddr = TARGETING::get_top_mem_addr(); + l_topMemAddr = ISTEP::get_top_mem_addr(); assert (l_topMemAddr != 0, "populate_HbRsvMem: Top of memory was 0!"); diff --git a/src/usr/secureboot/common/common.mk b/src/usr/secureboot/common/common.mk index 06f7a0bae..e077bbf05 100644 --- a/src/usr/secureboot/common/common.mk +++ b/src/usr/secureboot/common/common.mk @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2016,2017 +# Contributors Listed Below - COPYRIGHT 2016,2018 # [+] International Business Machines Corp. # # @@ -27,3 +27,4 @@ SECUREBOOT_COMMON_OBJS += securetrace.o SECUREBOOT_COMMON_OBJS += errlud_secure.o SECUREBOOT_COMMON_OBJS += containerheader.o + diff --git a/src/usr/secureboot/makefile b/src/usr/secureboot/makefile index c9a6a91b8..eacbf9354 100644 --- a/src/usr/secureboot/makefile +++ b/src/usr/secureboot/makefile @@ -29,5 +29,6 @@ SUBDIRS += ext.d SUBDIRS += trusted.d SUBDIRS += runtime.d SUBDIRS += node_comm.d +SUBDIRS += smf.d include ${ROOTPATH}/config.mk diff --git a/src/usr/secureboot/smf/makefile b/src/usr/secureboot/smf/makefile new file mode 100644 index 000000000..14b7203fb --- /dev/null +++ b/src/usr/secureboot/smf/makefile @@ -0,0 +1,32 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/secureboot/smf/makefile $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2018 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +ROOTPATH = ../../../.. + +MODULE = smf + +OBJS += smf_utils.o + +include ${ROOTPATH}/config.mk + diff --git a/src/usr/secureboot/smf/smf_utils.C b/src/usr/secureboot/smf/smf_utils.C new file mode 100644 index 000000000..e8bca1fff --- /dev/null +++ b/src/usr/secureboot/smf/smf_utils.C @@ -0,0 +1,110 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/smf/smf_utils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include <secureboot/smf_utils.H> +#include <targeting/common/target.H> +#include <targeting/common/targetservice.H> +#include <targeting/targplatutil.H> +#include <secureboot/secure_reasoncodes.H> +#include <assert.h> +#include <limits.h> + +namespace SECUREBOOT +{ + +namespace SMF +{ + +const uint64_t MIN_SMF_MEMORY_AMT = 256 * MEGABYTE; + +bool isSmfEnabled() +{ + uint8_t l_smfEnabled = true; + + TARGETING::Target* l_sys = nullptr; + TARGETING::targetService().getTopLevelTarget(l_sys); + crit_assert(l_sys != nullptr); + l_smfEnabled = l_sys->getAttr<TARGETING::ATTR_SMF_ENABLED>(); + return l_smfEnabled; +} + +errlHndl_t checkRiskLevelForSmf() +{ + errlHndl_t l_errl = nullptr; + + do { + + TARGETING::Target* l_sys = nullptr; + TARGETING::targetService().getTopLevelTarget(l_sys); + crit_assert(l_sys); + auto l_riskLevel = l_sys->getAttr<TARGETING::ATTR_RISK_LEVEL>(); + + TARGETING::Target* l_pMasterProc = nullptr; + l_errl = TARGETING::targetService() + .queryMasterProcChipTargetHandle(l_pMasterProc); + if(l_errl) + { + break; + } + + auto l_masterProcModel = l_pMasterProc->getAttr<TARGETING::ATTR_MODEL>(); + + // SMF is enabled by default on Axone, so need to check the risk level + // only on P9C/P9N. + // WARNING: If more risk levels are added in the future that don't + // support SMF, the below check needs to be altered accordingly. + if(l_riskLevel <TARGETING::UTIL::P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_SECURITY + && ( + (l_masterProcModel == TARGETING::MODEL_CUMULUS) || + (l_masterProcModel == TARGETING::MODEL_NIMBUS) + ) + ) + { + /*@ + * @errortype + * @reasoncode SECUREBOOT::RC_RISK_LEVEL_TOO_LOW + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_CHECK_RISK_LEVEL_FOR_SMF + * @userdata1 Current risk level of the system + * @userdata2 Minimum risk level required + * @devdesc SMF is enabled on the system of incorrect risk level + * @custdesc A problem occurred during the IPL of the system. + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_CHECK_RISK_LEVEL_FOR_SMF, + SECUREBOOT::RC_RISK_LEVEL_TOO_LOW, + l_riskLevel, + TARGETING::UTIL::P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_SECURITY, + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + break; + } + + } while(0); + + return l_errl; +} + +} // namespace SMF + +} // namespace SECUREBOOT diff --git a/src/usr/targeting/common/util.C b/src/usr/targeting/common/util.C index 26b63966e..c8b8c7c5f 100644 --- a/src/usr/targeting/common/util.C +++ b/src/usr/targeting/common/util.C @@ -201,114 +201,6 @@ bool is_no_load(void) return (PAYLOAD_KIND_NONE == sys->getAttr<TARGETING::ATTR_PAYLOAD_KIND>()); } -/** - * @brief Utility function to obtain the highest known address in the system - */ -uint64_t get_top_mem_addr(void) -{ - uint64_t top_addr = 0; - - do - { - // Get all functional proc chip targets - TARGETING::TargetHandleList l_cpuTargetList; - TARGETING::getAllChips(l_cpuTargetList, TYPE_PROC); - - for ( size_t proc = 0; proc < l_cpuTargetList.size(); proc++ ) - { - TARGETING::Target * l_pProc = l_cpuTargetList[proc]; - top_addr = std::max(top_addr,get_top_mem_addr(l_pProc)); - } - - } while(0); - - return top_addr; -} - -/** - * @brief Utility function to obtain the highest known address in a given proc - */ -uint64_t get_top_mem_addr(TargetHandle_t i_proc) -{ - uint64_t top_addr = 0; - - //Not checking success here as fail results in no change to - // top_addr - uint64_t l_mem_bases[8] = {0,}; - uint64_t l_mem_sizes[8] = {0,}; - i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_mem_bases); - i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>(l_mem_sizes); - - for (size_t i=0; i< 8; i++) - { - if(l_mem_sizes[i]) //non zero means that there is memory present - { - top_addr = std::max(top_addr, - l_mem_bases[i] + l_mem_sizes[i]); - } - } - - return top_addr; -} - -/** - * @brief Utility function to obtain the lowest known address in the system - */ -uint64_t get_bottom_mem_addr(void) -{ - uint64_t bottom_addr = UINT64_MAX; - - do - { - // Get all functional proc chip targets - TARGETING::TargetHandleList l_cpuTargetList; - TARGETING::getAllChips(l_cpuTargetList, TYPE_PROC); - - for ( size_t proc = 0; proc < l_cpuTargetList.size(); proc++ ) - { - TARGETING::Target * l_pProc = l_cpuTargetList[proc]; - bottom_addr = std::min(bottom_addr, get_bottom_mem_addr(l_pProc)); - } - }while(0); - - // There's no reason the lowest address should be the largest - // 64 bit value - TARG_ASSERT( - bottom_addr < UINT64_MAX, - "Lowest address is maximum 64-bit value, probably have no memory"); - - return bottom_addr; -} - - -/** - * @brief Utility function to obtain the lowest known address in a given proc - */ -uint64_t get_bottom_mem_addr(TargetHandle_t i_proc) -{ - uint64_t bottom_addr = UINT64_MAX; - - uint64_t l_mem_bases[8] = {}; - uint64_t l_mem_sizes[8] = {}; - TARG_ASSERT( - i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_mem_bases), - "Unable to get ATTR_PROC_MEM_BASES attribute"); - - TARG_ASSERT( - i_proc->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>(l_mem_sizes), - "Unable to get ATTR_PROC_MEM_SIZES attribute"); - - for (size_t i=0; i< 8; i++) - { - if(l_mem_sizes[i]) //non zero means that there is memory present - { - bottom_addr = std::min(bottom_addr, l_mem_bases[i]); - } - } - - return bottom_addr; -} - bool orderByNodeAndPosition( Target* i_firstProc, Target* i_secondProc) { diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H index f79cf5f1a..377f933ac 100644 --- a/src/usr/testcore/rtloader/loader.H +++ b/src/usr/testcore/rtloader/loader.H @@ -48,6 +48,7 @@ #include <util/utilrsvdmem.H> #include <sys/misc.h> #include <errno.h> +#include <isteps/mem_utils.H> trace_desc_t* g_trac_hbrt = NULL; @@ -656,7 +657,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite } } - cv_comm_phys_addr = TARGETING::get_top_mem_addr(); + cv_comm_phys_addr = ISTEP::get_top_mem_addr(); assert (cv_comm_phys_addr != 0, "rt_get_comm: Top of memory was 0!"); |