summaryrefslogtreecommitdiffstats
path: root/src/usr/initservice/istepdispatcher
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2017-07-11 20:40:01 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-07-26 14:46:07 -0400
commit306c98095f0f5f9f15c4e33840e4c9fa4303c3b1 (patch)
tree88a2f12269928145dadb5da357b1f4eb44bc65e1 /src/usr/initservice/istepdispatcher
parentdee7ffab5ecdfcccd643125d9d5c94e1479d63a2 (diff)
downloadtalos-hostboot-306c98095f0f5f9f15c4e33840e4c9fa4303c3b1.tar.gz
talos-hostboot-306c98095f0f5f9f15c4e33840e4c9fa4303c3b1.zip
Prevent skipping isteps/substeps in secure mode
When using istep mode to execute isteps/substeps out of order, we must prevent any istep from excuting before any previous isteps have executed at least once. After each istep has successfully executed once, hostboot behaves as before. Change-Id: If830dbf0a033eaab9ec14a3f5790bcf92307237f RTC:163084 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43013 Reviewed-by: Nicholas E. Bofferding <bofferdn@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: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/initservice/istepdispatcher')
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C120
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H24
2 files changed, 131 insertions, 13 deletions
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index c365978e8..2444b98ad 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -78,7 +78,7 @@
#include <initservice/bootconfigif.H>
#include <trace/trace.H>
#include <util/utilmbox_scratch.H>
-
+#include <secureboot/service.H>
namespace ISTEPS_TRACE
{
@@ -114,6 +114,8 @@ IStepDispatcher::IStepDispatcher() :
iv_syncPointReached(false),
iv_istepModulesLoaded(0),
iv_progressThreadStarted(false),
+ iv_highestIStepDone(0),
+ iv_highestSubstepDone(0),
iv_curIStep(0),
iv_curSubStep(0),
iv_pIstepMsg(NULL),
@@ -720,6 +722,8 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
// Get the Task Info for this step
const TaskInfo * theStep = findTaskInfo(i_istep, i_substep);
+ do {
+
// If the step has valid work to be done, then execute it.
if(NULL != theStep)
{
@@ -730,15 +734,58 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
TRACFCOMP(g_trac_initsvc,ENTER_MRK"doIstep: step %d, substep %d, "
"task %s", i_istep, i_substep, theStep->taskname);
+ #ifdef CONFIG_SECUREBOOT
+ if (SECUREBOOT::enabled())
+ {
+ auto nextIStepAllowed = iv_highestIStepDone;
+ auto nextSubstepAllowed = iv_highestSubstepDone;
+ auto rc = getNextIStep(nextIStepAllowed, nextSubstepAllowed);
+ if (rc && (i_istep > nextIStepAllowed ||
+ (i_istep == nextIStepAllowed &&
+ i_substep > nextSubstepAllowed))
+ )
+ {
+ TRACFCOMP(g_trac_initsvc,
+ ERR_MRK"doIstep: failed on requested step %d,"
+ " and substep %d, next allowed by secure boot is "
+ "step %d and substep %d", i_istep, i_substep,
+ nextIStepAllowed, nextSubstepAllowed);
+
+ /*@
+ * @errortype
+ * @reasoncode ISTEP_SKIP_ATTEMPTED
+ * @moduleid ISTEP_INITSVC_MOD_ID
+ * @userdata1[00:31] istep requested
+ * @userdata1[32:64] substep requested
+ * @userdata2[00:31] highest istep allowed
+ * @userdata2[32:64] highest substep allowed
+ * @devdesc Istep skip prevented in secure mode
+ * @custdesc An internal firmware error occured
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ ISTEP_INITSVC_MOD_ID,
+ ISTEP_SKIP_ATTEMPTED,
+ TWO_UINT32_TO_UINT64(
+ i_istep,
+ i_substep),
+ TWO_UINT32_TO_UINT64(
+ nextIStepAllowed,
+ nextSubstepAllowed));
+ break;
+ }
+ }
+ #endif // CONFIG_SECUREBOOT
+
+ // Record current IStep, SubStep
+ mutex_lock(&iv_mutex);
+ iv_curIStep = i_istep;
+ iv_curSubStep = i_substep;
+ mutex_unlock(&iv_mutex);
+
// Send progress codes if in run-all mode
if (!iv_istepMode)
{
- mutex_lock(&iv_mutex);
- // Record current IStep, SubStep
- iv_curIStep = i_istep;
- iv_curSubStep = i_substep;
- mutex_unlock(&iv_mutex);
-
// If a shutdown request has been received
if (isShutdownRequested())
{
@@ -928,6 +975,27 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
INFO_MRK"doIstep: Empty Istep, nothing to do!" );
}
+ } while (0); // if there was an error break here
+
+ if (!err && theStep)
+ {
+ // update high watermark for istep and substep but don't ever
+ // decrease it. Note: this code assumes you were allowed to execute
+ // the istep (we just got done with it after all).
+ if (i_substep > iv_highestSubstepDone &&
+ i_istep == iv_highestIStepDone)
+ {
+ iv_highestSubstepDone = i_substep;
+ }
+ else if (i_istep > iv_highestIStepDone)
+ {
+ iv_highestIStepDone = i_istep;
+ iv_highestSubstepDone = i_substep;
+ }
+ // else we do nothing, because we just did an istep that is lower
+ // than the watermark
+ }
+
return err;
}
@@ -1671,8 +1739,6 @@ void IStepDispatcher::handleIStepRequestMsg(msg_t * & io_pMsg)
// IStep doesn't return (start_payload), it will call sendIstepCompleteMsg
// which will respond to iv_pIstepMsg
mutex_lock(&iv_mutex);
- iv_curIStep = istep;
- iv_curSubStep = substep;
iv_pIstepMsg = io_pMsg;
io_pMsg = NULL;
l_acceptMessages = iv_acceptIstepMessages;
@@ -1697,8 +1763,8 @@ void IStepDispatcher::handleIStepRequestMsg(msg_t * & io_pMsg)
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
ISTEP_INITSVC_MOD_ID,
ISTEP_NON_MASTER_NODE_MSG,
- iv_curIStep,
- iv_curSubStep);
+ istep,
+ substep);
}
// If there was no IStep error, but something happened that requires a
@@ -2496,4 +2562,36 @@ void IStepDispatcher::istepPauseSet(uint8_t i_step, uint8_t i_substep)
}
}
+int IStepDispatcher::getNextIStep(uint8_t& io_istep, uint8_t& io_substep)
+{
+ int rc = 0; // defaults to failure
+
+ do
+ {
+ rc = 0; // defaults to failure again unless a valid istep/substep
+ // is found
+ uint8_t l_numSubsteps = g_isteps[io_istep].numitems;
+
+ if (l_numSubsteps != 0 &&
+ (io_substep + 1u) < l_numSubsteps)
+ {
+ io_substep++;
+ rc = 1;
+ }
+ else if ((io_istep + 1u) < MaxISteps)
+ {
+ io_substep = 0;
+ io_istep++;
+ rc = 1;
+ }
+ else
+ {
+ // avoid infinite loop scenario
+ break;
+ }
+ } while (nullptr == findTaskInfo(io_istep, io_substep));
+
+ return rc;
+}
+
}; // namespace
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index 2ef7c75a8..cd3c26dcb 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -86,7 +86,7 @@ const uint64_t MAX_RCL_TESTS = 5;
* @brief detached task (daemon) to handle communication from
* VPO / Simics user console.
*
- * param[in,out] - pointer to any args
+ * @param[in,out] - pointer to any args
*
* @return NULL
*/
@@ -221,6 +221,24 @@ public:
void requestReboot();
#endif
+ /**
+ * @brief For a given istep/substep combo, calculate (destructively)
+ * the next istep/substep.
+ *
+ * @param[in,out] io_istep The istep to be used as input to destructively
+ * calculate the istep for the next istep/substep
+ * combo and returned as the istep output
+ * parameter.
+ *
+ * @param[in,out] io_substep The substep to be used as input to
+ * destructively calculate the substep for the
+ * next istep/substep combo and returned as the
+ * substep output paremeter.
+ *
+ * @return 0 indicates there were no more isteps
+ * 1 indicates istep successfully incremented
+ */
+ int getNextIStep(uint8_t& io_istep, uint8_t& io_substep);
protected:
@@ -424,6 +442,8 @@ private:
// Used in only one thread, mutex protection not needed
uint32_t iv_istepModulesLoaded;
bool iv_progressThreadStarted;
+ uint8_t iv_highestIStepDone;
+ uint8_t iv_highestSubstepDone;
// Used in multiple threads, mutex protection needed
uint8_t iv_curIStep; // Current Step
OpenPOWER on IntegriCloud