summaryrefslogtreecommitdiffstats
path: root/src/usr/runtime/populate_hbruntime.C
diff options
context:
space:
mode:
authorIlya Smirnov <ismirno@us.ibm.com>2018-01-26 12:10:24 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-02-14 15:01:31 -0500
commitd9c127dca8312f119b379c83b361216b910f6748 (patch)
tree8d37e7926981c115092a558daf36d8d02d405ae2 /src/usr/runtime/populate_hbruntime.C
parentddfe08755562f0bd6b2ec445972f4b2c751a5f80 (diff)
downloadtalos-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.C74
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;
OpenPOWER on IntegriCloud