diff options
author | Ilya Smirnov <ismirno@us.ibm.com> | 2018-01-26 12:10:24 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-02-14 15:01:31 -0500 |
commit | d9c127dca8312f119b379c83b361216b910f6748 (patch) | |
tree | 8d37e7926981c115092a558daf36d8d02d405ae2 /src/usr/runtime/populate_hbruntime.C | |
parent | ddfe08755562f0bd6b2ec445972f4b2c751a5f80 (diff) | |
download | talos-hostboot-d9c127dca8312f119b379c83b361216b910f6748.tar.gz talos-hostboot-d9c127dca8312f119b379c83b361216b910f6748.zip |
Error when hb tries to access reserved memory past limit
An issue has recently occurred when hb reserved memory past
the allowed limit (256M-4K) and overwrote some of the PHYP
memory, which caused bugs that were difficult to debug. This
change is to check the memory address we are trying to reserve
and throw an error if the address is at or above the allowed
limit. We only execute this check if PHYP is running and only
on components not belonging to PHYP (PHYP components may be
placed outside of the limit).
Change-Id: Ic62a7b724abc3b29b7872d0af47de8c68cde2ea8
RTC:186332
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/52850
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@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>
Reviewed-by: Michael Baiocchi <mbaiocch@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/runtime/populate_hbruntime.C')
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 74 |
1 files changed, 69 insertions, 5 deletions
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index d8faf94dd..66806d87a 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -77,6 +77,7 @@ #include <runtime/common/runtime_utils.H> #include <limits.h> #include <errno.h> +#include <vmmconst.h> namespace RUNTIME { @@ -88,6 +89,15 @@ const uint16_t TPM_REQUIRED_BIT = 0x8000; //leftmost bit of uint16_t set to 1 const uint8_t BITS_PER_BYTE = 8; +// The upper limit of the hostboot reserved memory. Only applies to PHYP. +// The lower limit is Hostboot HRMOR + 64MB; 4KB is the PHYP component's +// secure header. +const uint64_t HB_RES_MEM_UPPER_LIMIT = 256*MEGABYTE - 4*KILOBYTE; + +// The lower limit of the hostboot reserved memory. Do not allow to reserve +// any memory below this limit. +const uint64_t HB_RES_MEM_LOWER_LIMIT = VMM_MEMORY_SIZE + VMM_HRMOR_OFFSET; + trace_desc_t *g_trac_runtime = nullptr; TRAC_INIT(&g_trac_runtime, RUNTIME_COMP_NAME, KILOBYTE); @@ -250,17 +260,69 @@ void traceHbRsvMemRange(hdatMsVpdRhbAddrRange_t* & i_rngPtr ) i_rngPtr->hdatRhbPermission); } +errlHndl_t checkHbResMemLimit(const uint64_t i_addr, const uint64_t i_size) +{ + errlHndl_t l_errl = nullptr; + // Only check if PHYP is running or if running in standalone. + if(TARGETING::is_phyp_load() || TARGETING::is_no_load()) + { + if((i_addr < HB_RES_MEM_LOWER_LIMIT) or + ((i_addr + i_size - 1) > HB_RES_MEM_UPPER_LIMIT)) + { + TRACFCOMP(g_trac_runtime, "checkHbResMemLimit> Attempt to write" + " to hostboot reserved memory outside of allowed hostboot address" + " range. Start addresss - 0x%08x end address - 0x%08x;" + " bottom limit - 0x%08x top limit - 0x%08x.", + i_addr, i_addr + i_size - 1, + HB_RES_MEM_LOWER_LIMIT, HB_RES_MEM_UPPER_LIMIT); + + /*@ + * @errortype + * @moduleid RUNTIME::MOD_CHECK_HB_RES_MEM_LIMIT + * @reasoncode RUNTIME::RC_HB_RES_MEM_EXCEEDED + * @userdata1 Starting address + * @userdata2 Size of the section + * @devdesc Hostboot attempted to reserve memory past allowed + * range. Bottom limit = Hostboot HRMOR + 64M, top + * limit = 256M - 4K. + * @custdesc Hostboot attempted to reserve memory outside of + * allowed range. + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_CHECK_HB_RES_MEM_LIMIT, + RUNTIME::RC_HB_RES_MEM_EXCEEDED, + i_addr, + i_size, + true /*Add HB Software Callout*/); + l_errl->collectTrace(RUNTIME_COMP_NAME,KILOBYTE); + } + } + return l_errl; +} + errlHndl_t setNextHbRsvMemEntry(const HDAT::hdatMsVpdRhbAddrRangeType i_type, const uint16_t i_rangeId, const uint64_t i_startAddr, const uint64_t i_size, const char* i_label, - const HDAT::hdatRhbPermType i_permission) + const HDAT::hdatRhbPermType i_permission, + const bool i_checkMemoryLimit) { errlHndl_t l_elog = nullptr; do { + // Check whether hostboot is trying to access memory outside of its allowed + // range. + if(i_checkMemoryLimit) + { + l_elog = checkHbResMemLimit(i_startAddr, i_size); + if(l_elog) + { + break; + } + } + // Get a pointer to the next available HDAT HB Rsv Mem entry hdatMsVpdRhbAddrRange_t* l_rngPtr = nullptr; l_elog = getNextRhbAddrRange(l_rngPtr); @@ -813,10 +875,12 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node) uint64_t l_hbAddr = cpu_spr_value(CPU_SPR_HRMOR) - VMM_HRMOR_OFFSET; l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_PRIMARY, - i_nodeId, - l_hbAddr, - VMM_HB_RSV_MEM_SIZE, - HBRT_RSVD_MEM__PRIMARY); + i_nodeId, + l_hbAddr, + VMM_HB_RSV_MEM_SIZE, + HBRT_RSVD_MEM__PRIMARY, + HDAT::RHB_READ_WRITE, + false); if(l_elog != nullptr) { break; |