PHAL: Set HardwareIsolation policy before start the host
- The HardwareIsolation (aka guard) policy is used to prevent
the HardwareIsolation functionality during the boot of the host
by the user.
- In this patch, using that policy flag to ignore the isolated hardware
records to apply during the start of the host from the BMC context.
- By default, it will be set as "true" before starting the host to boot
if the HardwareIsolation policy is not present or failed to read that
policy.
- Created the error log with procedure callout if failed to read
the HardwareIsolation policy.
Tested:
- Verified the HWAS_STATE of the isolated hardware, is not applied when
the HardwareIsolation policy is enabled.
- Verified the HWAS_STATE of the isolated hardware, is applied when
the HardwareIsolation policy is disabled.
- Verified the HWAS_STATE of the isolated hardware, is applied when
the HardwareIsolation policy is not present.
- PEL for the third test case.
```
{
"Private Header": {
"Section Version": "1",
"Sub-section type": "0",
"Created by": "0x3000",
...
"User Header": {
"Section Version": "1",
"Sub-section type": "0",
"Log Committed by": "0x2000",
"Subsystem": "CEC Hardware",
"Event Scope": "Entire Platform",
"Event Severity": "Unrecoverable Error",
"Event Type": "Not Applicable",
"Action Flags": [
"Service Action Required",
"Report Externally",
"HMC Call Home"
],
"Host Transmission": "Not Sent",
"HMC Transmission": "Not Sent"
},
...
"Primary SRC": {
"Section Version": "1",
"Sub-section type": "1",
"Created by": "0x3000",
...
"Error Details": {
"Message": "Failure occured during boot process"
},
"Valid Word Count": "0x09",
"Reference Code": "BD503001",
...
"Callout Section": {
"Callout Count": "1",
"Callouts": [{
"FRU Type": "Maintenance Procedure Required",
"Priority": "Medium Priority",
"Procedure": "BMC0001"
}]
}
...
"User Data 1": {
"Section Version": "1",
"Sub-section type": "1",
"Created by": "0x2000",
"REASON_FOR_PEL": "Failed to read the HardwareIsolation policy from the path [/xyz/openbmc_project/hardware_isolation/allow_hw_isolation] interface [xyz.openbmc_project.Object.Enable]. Continuing with default mode(allow_hw_isolation)",
"_PID": "681"
},
"User Data 2": {
"Section Version": "1",
"Sub-section type": "1",
"Created by": "0x2000",
"Data": [
{
"Priority": "M",
"Procedure": "BMC0001"
}
]
}
}
```
Signed-off-by: Ramesh Iyyar <rameshi1@in.ibm.com>
Change-Id: I2d7e33ad1e6af69b150d6637619c17db5b9a7151
diff --git a/procedures/phal/start_host.cpp b/procedures/phal/start_host.cpp
index db323ca..01cada9 100644
--- a/procedures/phal/start_host.cpp
+++ b/procedures/phal/start_host.cpp
@@ -14,6 +14,7 @@
#include <libekb.H>
#include <ext_interface.hpp>
+#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <registration.hpp>
@@ -169,6 +170,114 @@
}
/**
+ * @brief Helper function to create error log (aka PEL) with
+ * procedure callout for the hardware isolation policy
+ * settings failures.
+ *
+ * @param[in] procedureCode - The procedure code to include in the callout
+ * @param[in] priority - The priority for the procedure callout
+ * @param[in] additionalData - The additional data to include in the error log
+ *
+ * @return void
+ */
+static void
+ createPELForHwIsolationSettingsErr(const std::string& procedureCode,
+ const std::string& priority,
+ const pel::FFDCData& additionalData)
+{
+ try
+ {
+ using json = nlohmann::json;
+
+ json jsonCalloutDataList;
+ jsonCalloutDataList = json::array();
+ json jsonCalloutData;
+ jsonCalloutData["Procedure"] = procedureCode;
+ jsonCalloutData["Priority"] = priority;
+ jsonCalloutDataList.emplace_back(jsonCalloutData);
+
+ openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot",
+ jsonCalloutDataList, additionalData);
+ }
+ catch (const std::exception& e)
+ {
+ // Don't throw exception since the caller might call in the error path
+ // and even we should allow the hardware isolation by default.
+ log<level::ERR>(
+ fmt::format("Exception [{}], failed to create the error log "
+ "for the hardware isolation policy settings failures.",
+ e.what())
+ .c_str());
+ }
+}
+
+/**
+ * @brief Helper function to decide the hardware isolation (aka guard)
+ *
+ * @return xyz.openbmc_project.Object.Enable::Enabled value on success
+ * true on failure since hardware isolation feature should be
+ * enabled by default.
+ */
+static bool allowHwIsolation()
+{
+ bool allowHwIsolation{true};
+
+ constexpr auto hwIsolationPolicyObjPath =
+ "/xyz/openbmc_project/hardware_isolation/allow_hw_isolation";
+ constexpr auto hwIsolationPolicyIface = "xyz.openbmc_project.Object.Enable";
+
+ try
+ {
+ auto bus = sdbusplus::bus::new_default();
+
+ std::string service = util::getService(bus, hwIsolationPolicyObjPath,
+ hwIsolationPolicyIface);
+
+ auto method =
+ bus.new_method_call(service.c_str(), hwIsolationPolicyObjPath,
+ "org.freedesktop.DBus.Properties", "Get");
+ method.append(hwIsolationPolicyIface, "Enabled");
+
+ auto reply = bus.call(method);
+
+ std::variant<bool> resp;
+
+ reply.read(resp);
+
+ if (const bool* enabledPropVal = std::get_if<bool>(&resp))
+ {
+ allowHwIsolation = *enabledPropVal;
+ }
+ else
+ {
+ const auto trace{fmt::format(
+ "Failed to read the HardwareIsolation policy "
+ "from the path [{}] interface [{}]. Continuing with "
+ "default mode(allow_hw_isolation)",
+ hwIsolationPolicyObjPath, hwIsolationPolicyIface)};
+
+ log<level::ERR>(trace.c_str());
+ createPELForHwIsolationSettingsErr("BMC0001", "M",
+ {{"REASON_FOR_PEL", trace}});
+ }
+ }
+ catch (const sdbusplus::exception::exception& e)
+ {
+ const auto trace{fmt::format(
+ "Exception [{}] to get the HardwareIsolation policy "
+ "from the path [{}] interface [{}]. Continuing with "
+ "default mode (allow_hw_isolation)",
+ e.what(), hwIsolationPolicyObjPath, hwIsolationPolicyIface)};
+
+ log<level::ERR>(trace.c_str());
+ createPELForHwIsolationSettingsErr("BMC0001", "M",
+ {{"REASON_FOR_PEL", trace}});
+ }
+
+ return allowHwIsolation;
+}
+
+/**
* @brief Starts the self boot engine on POWER processor position 0
* to kick off a boot.
* @return void
@@ -179,6 +288,17 @@
{
phal_init();
ipl_set_type(iplType);
+
+ /**
+ * Don't apply guard records if the HardwareIsolation (aka guard)
+ * the policy is disabled (false). By default, libipl will apply
+ * guard records.
+ */
+ if (!allowHwIsolation())
+ {
+ ipl_disable_guard();
+ }
+
if (iplType == IPL_TYPE_NORMAL)
{
// Update SEEPROM side only for NORMAL boot