summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2017-07-21 11:15:42 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-07-28 10:43:42 -0400
commitf54d606af645343351d086b1de237f021f38cb21 (patch)
tree5f0a86acb216888dc0f15e71c6032c0d795b444e
parent481baf1c81c945ce3d354097a6452cb8ecba38d6 (diff)
downloadtalos-hostboot-f54d606af645343351d086b1de237f021f38cb21.tar.gz
talos-hostboot-f54d606af645343351d086b1de237f021f38cb21.zip
Secure Boot: Shutdown after key transition
- Fence off istep path after istep dispatcher stops - Automatically power off after a key transition has completed - Added IPMI API to power off system Change-Id: I74eaec08e86d0cbc46db6aa1674845c53bcf14d4 RTC: 174017 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43436 Tested-by: Jenkins Server <pfd-jenkins+hostboot@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> 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: Stephen M. Cprek <smcprek@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
-rw-r--r--src/include/usr/initservice/initsvcreasoncodes.H1
-rw-r--r--src/include/usr/initservice/istepdispatcherif.H14
-rw-r--r--src/include/usr/ipmi/ipmiif.H34
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C65
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H7
-rw-r--r--src/usr/ipmi/ipmirp.C34
-rw-r--r--src/usr/ipmi/ipmirp.H16
-rw-r--r--src/usr/sbe/sbe_update.C69
8 files changed, 187 insertions, 53 deletions
diff --git a/src/include/usr/initservice/initsvcreasoncodes.H b/src/include/usr/initservice/initsvcreasoncodes.H
index 31910bcef..29f73e253 100644
--- a/src/include/usr/initservice/initsvcreasoncodes.H
+++ b/src/include/usr/initservice/initsvcreasoncodes.H
@@ -77,6 +77,7 @@ enum InitServiceReasonCode
//termination_rc
SHUTDOWN_NOT_RECONFIG_LOOP = INITSVC_COMP_ID | 0x10,
ISTEP_SKIP_ATTEMPTED = INITSVC_COMP_ID | 0x11,
+ ISTEP_PROCESSING_DISABLED = INITSVC_COMP_ID | 0x12,
};
enum InitServiceUserDetailDataSubSection
diff --git a/src/include/usr/initservice/istepdispatcherif.H b/src/include/usr/initservice/istepdispatcherif.H
index 752f9ffff..1694c7942 100644
--- a/src/include/usr/initservice/istepdispatcherif.H
+++ b/src/include/usr/initservice/istepdispatcherif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -78,12 +78,16 @@ void stopIpl( void );
#ifdef CONFIG_BMC_IPMI
/**
- * @brief This function is to be used by external code to
- * initate a system reboot via IPMI commands
- *
- * @return Nothing
+ * @brief This function is to be used by external code to
+ * initiate a system reboot via IPMI commands
*/
void requestReboot( void );
+
+/**
+ * @brief This function is to be used by external code to
+ * initiate a system power off via IPMI commands
+ */
+void requestPowerOff( void );
#endif
/**
diff --git a/src/include/usr/ipmi/ipmiif.H b/src/include/usr/ipmi/ipmiif.H
index 09f0c4830..4dd5e7cbb 100644
--- a/src/include/usr/ipmi/ipmiif.H
+++ b/src/include/usr/ipmi/ipmiif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,13 +54,30 @@ namespace IPMI
MSG_STATE_GRACEFUL_SHUTDOWN,
- // initate a reboot request
- MSG_STATE_INITATE_POWER_CYCLE,
+ // initiate a reboot request
+ MSG_STATE_INITIATE_POWER_CYCLE,
// Used to check range. Leave as last.
- MSG_LAST_TYPE = MSG_STATE_INITATE_POWER_CYCLE,
+ MSG_LAST_TYPE = MSG_STATE_INITIATE_POWER_CYCLE,
};
+ /**
+ * @brief Returns whether IPMI message type is related to
+ * system shutdown/reboot or not
+ *
+ * @param[in] i_msgType IPMI message type in question
+ *
+ * @return bool True or false value indicating whether requested IPMI
+ * message type is related to system shutdown/reboot or not
+ */
+ inline bool validShutdownRebootMsgType(const msg_type i_msgType)
+ {
+ return ( (i_msgType == MSG_STATE_SHUTDOWN)
+ || (i_msgType == MSG_STATE_SHUTDOWN_SEL)
+ || (i_msgType == MSG_STATE_GRACEFUL_SHUTDOWN)
+ || (i_msgType == MSG_STATE_INITIATE_POWER_CYCLE));
+ }
+
// chassis power off request types
enum power_request_type
{
@@ -349,12 +366,17 @@ namespace IPMI
size_t max_buffer(void);
/**
- * Tells ipmirp to start a graceful reboot sequence
- *
+ * @brief Initiate a graceful reboot sequence via the IPMI resource
+ * provider
*/
void initiateReboot();
/**
+ * @brief Initiate a power off sequence via the IPMI resource provider
+ */
+ void initiatePowerOff();
+
+ /**
* Structure to return BMC/IPMI information in
*/
struct BmcInfo_t
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 2444b98ad..5edf4f835 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -655,6 +655,9 @@ errlHndl_t IStepDispatcher::executeAllISteps()
// possible
ERRORLOG::ErrlManager::callFlushErrorLogs();
+ // Quiesce new isteps, including external requests
+ (void)setStopIpl();
+
// Stop the IPL
stop();
}
@@ -1505,11 +1508,20 @@ void IStepDispatcher::handleShutdownMsg(msg_t * & io_pMsg)
#ifdef CONFIG_BMC_IPMI
void IStepDispatcher::requestReboot()
{
- // always stop dispatching isteps before calling for the reboot
- setStopIpl();
+ // Always stop dispatching isteps before calling for the reboot
+ (void)setStopIpl();
+
+ // Send a reboot message to the BMC
+ (void)IPMI::initiateReboot();
+}
+
+void IStepDispatcher::requestPowerOff()
+{
+ // Always stop dispatching isteps before calling for the power off
+ (void)setStopIpl();
- // send a reboot message to the BMC
- IPMI::initiateReboot();
+ // Send a power off message to the BMC
+ (void)IPMI::initiatePowerOff();
}
#endif
// ----------------------------------------------------------------------------
@@ -1744,21 +1756,42 @@ void IStepDispatcher::handleIStepRequestMsg(msg_t * & io_pMsg)
l_acceptMessages = iv_acceptIstepMessages;
mutex_unlock(&iv_mutex);
- if (l_acceptMessages)
+ // If istep dispatching has ceased, prevent new isteps from executing
+ if(iv_stopIpl == true)
+ {
+ /*@
+ * @errortype
+ * @reasoncode ISTEP_PROCESSING_DISABLED
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid ISTEP_INITSVC_MOD_ID
+ * @userdata1 Istep Requested
+ * @userdata2 Substep Requested
+ * @devdesc Istep processing has terminated due to normal shutdown
+ * activity, secure boot key transition, or terminating error
+ * @custdesc Node is no longer accepting istep requests
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ ISTEP_INITSVC_MOD_ID,
+ ISTEP_PROCESSING_DISABLED,
+ istep,
+ substep);
+ }
+ else if (l_acceptMessages)
{
err = doIstep (istep, substep, l_doReconfig);
}
else
{
/*@
- * @errortype
- * @reasoncode ISTEP_NON_MASTER_NODE_MSG
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid ISTEP_INITSVC_MOD_ID
- * @userdata1 Istep Requested
- * @userdata2 Substep Requested
- * @devdesc Istep messaged received by non-master node.
- */
+ * @errortype
+ * @reasoncode ISTEP_NON_MASTER_NODE_MSG
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid ISTEP_INITSVC_MOD_ID
+ * @userdata1 Istep Requested
+ * @userdata2 Substep Requested
+ * @devdesc Istep messaged received by non-master node.
+ */
err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
ISTEP_INITSVC_MOD_ID,
@@ -2236,9 +2269,15 @@ void requestReboot()
{
IStepDispatcher::getTheInstance().requestReboot();
}
+
+void requestPowerOff()
+{
+ IStepDispatcher::getTheInstance().requestPowerOff();
+}
#endif
void stopIpl()
{
+ // Disable the istep dispatcher
return IStepDispatcher::getTheInstance().setStopIpl();
}
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index cd3c26dcb..59e0fd45b 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -216,9 +216,14 @@ public:
void stop();
#ifdef CONFIG_BMC_IPMI
/**
- * @brief This function will trigger a reboot via ipmi commands
+ * @brief Trigger a reboot via IPMI commands
*/
void requestReboot();
+
+ /**
+ * @brief Trigger a power off via IPMI commands
+ */
+ void requestPowerOff();
#endif
/**
diff --git a/src/usr/ipmi/ipmirp.C b/src/usr/ipmi/ipmirp.C
index 4c5db3f19..6b1138783 100644
--- a/src/usr/ipmi/ipmirp.C
+++ b/src/usr/ipmi/ipmirp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -696,8 +696,8 @@ void IpmiRP::execute(void)
}
break;
- // begin a graceful reboot initated by us
- case IPMI::MSG_STATE_INITATE_POWER_CYCLE:
+ // begin a graceful reboot initiated by us
+ case IPMI::MSG_STATE_INITIATE_POWER_CYCLE:
{
msg_free(msg);
@@ -1078,15 +1078,27 @@ namespace IPMI
return err;
}
- ///
- /// @brief kick off a reboot
- ///
+ void initiateShutdownOrReboot(const IPMI::msg_type i_msgType)
+ {
+ const auto valid = IPMI::validShutdownRebootMsgType(i_msgType);
+ assert(valid,"BUG! IPMI message type of 0x%08X is not a valid shutdown "
+ "or reboot type",i_msgType);
+ static auto mq = Singleton<IpmiRP>::instance().msgQueue();
+ auto pMsg = msg_allocate();
+ assert(pMsg != nullptr,"BUG! msg_allocate returned nullptr.");
+ pMsg->type = i_msgType;
+ auto rc = msg_send(mq,pMsg);
+ assert(!rc,"BUG! msg_send failed with rc of %d",rc);
+ }
+
void initiateReboot()
{
- static msg_q_t mq = Singleton<IpmiRP>::instance().msgQueue();
- msg_t * msg = msg_allocate();
- msg->type = IPMI::MSG_STATE_INITATE_POWER_CYCLE;
- msg_send(mq, msg);
+ (void)initiateShutdownOrReboot(MSG_STATE_INITIATE_POWER_CYCLE);
+ }
+
+ void initiatePowerOff()
+ {
+ (void)initiateShutdownOrReboot(MSG_STATE_GRACEFUL_SHUTDOWN);
}
///
@@ -1163,4 +1175,4 @@ namespace IPMI
return l_info;
}
-};
+}; // End namespace IPMI
diff --git a/src/usr/ipmi/ipmirp.H b/src/usr/ipmi/ipmirp.H
index 9e8832555..0bbbaafb2 100644
--- a/src/usr/ipmi/ipmirp.H
+++ b/src/usr/ipmi/ipmirp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -267,4 +267,18 @@ class IpmiRP
IpmiRP(const IpmiRP&);
};
+namespace IPMI
+{
+ /**
+ * @brief Initiate generic IPMI shutdown/reboot request via the IPMI
+ * resource provider
+ *
+ * @param[in] i_msgType IPMI message type indicating the shutdown or reboot
+ * to request. Asserts if not a valid shutdown or reboot message type as
+ * determined by IPMI::validShutdownRebootMsgType().
+ */
+ void initiateShutdownOrReboot(IPMI::msg_type i_msgType);
+
+} // End IPMI namespace
+
#endif
diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C
index 7fe922427..ee116b14a 100644
--- a/src/usr/sbe/sbe_update.C
+++ b/src/usr/sbe/sbe_update.C
@@ -54,6 +54,8 @@
#include <sbeio/sbeioif.H>
#include <sbe/sbereasoncodes.H>
#include <sbe/sbe_update.H>
+#include <initservice/initsvcreasoncodes.H>
+
#ifdef CONFIG_BMC_IPMI
#include <ipmi/ipmisensor.H>
#include <ipmi/ipmiwatchdog.H>
@@ -481,8 +483,10 @@ namespace SBE
/**************************************************************/
/* Perform System Operation */
/**************************************************************/
- // Restart IPL if SBE Update requires it
- if ( l_restartNeeded == true )
+
+ // Restart IPL if SBE Update requires it or key transition occurred
+ if ( (l_restartNeeded == true)
+ || (g_do_hw_keys_hash_transition))
{
TRACFCOMP( g_trac_sbe,
INFO_MRK"updateProcessorSbeSeeproms(): Restart "
@@ -5037,25 +5041,58 @@ errlHndl_t sbeDoReboot( void )
#endif
#ifdef CONFIG_CONSOLE
- CONSOLE::displayf(SBE_COMP_NAME, "System Rebooting To "
- "Perform SBE Update\n");
- CONSOLE::flush();
+ if(g_do_hw_keys_hash_transition)
+ {
+ CONSOLE::displayf(SBE_COMP_NAME, "Performing Secure Boot key transition\n");
+ CONSOLE::displayf(SBE_COMP_NAME, "System will power off after completion\n");
+ CONSOLE::flush();
+ }
+ else
+ {
+ CONSOLE::displayf(SBE_COMP_NAME, "System Rebooting To "
+ "Perform SBE Update\n");
+ CONSOLE::flush();
+ }
#endif
#ifdef CONFIG_BMC_IPMI
- // initate a graceful power cycle
- TRACFCOMP( g_trac_sbe,"sbeDoReboot: "
- "requesting chassis power cycle");
- INITSERVICE::requestReboot();
+ if(g_do_hw_keys_hash_transition)
+ {
+ // Initiate a graceful power off
+ TRACFCOMP(g_trac_sbe,
+ INFO_MRK"sbeDoReboot(): Performing Secure Boot key transition. "
+ "Requesting power off");
+ INITSERVICE::requestPowerOff();
+ }
+ else
+ {
+ // Initiate a graceful power cycle
+ TRACFCOMP( g_trac_sbe,"sbeDoReboot: "
+ "requesting power cycle");
+ INITSERVICE::requestReboot();
+ }
#else //non-IPMI
- TRACFCOMP( g_trac_sbe,
- INFO_MRK"sbeDoReboot(): Calling "
- "INITSERVICE::doShutdown() with "
- "SBE_UPDATE_REQUEST_REIPL = 0x%X",
- SBE_UPDATE_REQUEST_REIPL );
- // shutdown/TI hostboot
- INITSERVICE::doShutdown(SBE_UPDATE_REQUEST_REIPL);
+ if(g_do_hw_keys_hash_transition)
+ {
+ TRACFCOMP(g_trac_sbe,
+ INFO_MRK"sbeDoReboot(): Performing Secure Boot key transition. "
+ "Calling INITSERVICE::doShutdown() with "
+ "SHUTDOWN_NOT_RECONFIG_LOOP = 0x%08X",
+ INITSERVICE::SHUTDOWN_NOT_RECONFIG_LOOP );
+ INITSERVICE::doShutdown(INITSERVICE::
+ SHUTDOWN_NOT_RECONFIG_LOOP);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_sbe,
+ INFO_MRK"sbeDoReboot(): Calling "
+ "INITSERVICE::doShutdown() with "
+ "SBE_UPDATE_REQUEST_REIPL = 0x%08X",
+ SBE_UPDATE_REQUEST_REIPL );
+ // shutdown/TI hostboot
+ INITSERVICE::doShutdown(SBE_UPDATE_REQUEST_REIPL);
+ }
#endif
}while(0);
OpenPOWER on IntegriCloud