summaryrefslogtreecommitdiffstats
path: root/src/usr/initservice/istepdispatcher
diff options
context:
space:
mode:
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