summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Pakhomov <k.pakhomov@yadro.com>2018-11-06 19:17:51 +0300
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-03-25 16:23:31 +0000
commitdb5d9b04543dea74b81b97fbed4a680fc3adc171 (patch)
tree96d421e040605ddc0cefafdb7eebd7806d372bc7
parent3325024067487320abddbf0ffb5a528b1743122a (diff)
downloadphosphor-host-ipmid-db5d9b04543dea74b81b97fbed4a680fc3adc171.zip
phosphor-host-ipmid-db5d9b04543dea74b81b97fbed4a680fc3adc171.tar.gz
dcmihandler: Fix Get DCMI Capabilities command
Get DCMI Capabilities (Discover) command returned wrong values for parameters exceeding 1 byte length. Also added the check for SEL entries number range per DCMI specification. Tested: the condition for value limit check works properly. Change-Id: Iee0d75594067630bb6094d05533c87e3ad82807e Signed-off-by: Kirill Pakhomov <k.pakhomov@yadro.com>
-rw-r--r--dcmihandler.cpp23
-rw-r--r--dcmihandler.hpp2
2 files changed, 17 insertions, 8 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index e858416..cb14005 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -784,16 +784,23 @@ ipmi_ret_t getDCMICapabilities(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
// If the data is beyond first byte boundary, insert in a
// 16bit pattern for example number of SEL entries are represented
// in 12bits.
- if ((cap.length + cap.position) > 8)
+ if ((cap.length + cap.position) > dcmi::gByteBitSize)
{
- // Read the value corresponding to capability name and assign to
- // 16bit bitset.
- std::bitset<16> val(data.value(cap.name.c_str(), 0));
+ uint16_t val = data.value(cap.name.c_str(), 0);
+ // According to DCMI spec v1.5, max number of SEL entries is
+ // 4096, but bit 12b of DCMI capabilities Mandatory Platform
+ // Attributes field is reserved and therefore we can use only
+ // the provided 12 bits with maximum value of 4095.
+ // We're playing safe here by applying the mask
+ // to ensure that provided value will fit into 12 bits.
+ if (cap.length > dcmi::gByteBitSize)
+ {
+ val &= dcmi::gMaxSELEntriesMask;
+ }
val <<= cap.position;
- reinterpret_cast<uint16_t*>(
- responseData
- ->data)[(cap.bytePosition - 1) / sizeof(uint16_t)] |=
- val.to_ulong();
+ responseData->data[cap.bytePosition - 1] |=
+ static_cast<uint8_t>(val);
+ responseData->data[cap.bytePosition] |= val >> dcmi::gByteBitSize;
}
else
{
diff --git a/dcmihandler.hpp b/dcmihandler.hpp
index 8b16e3d..a188c25 100644
--- a/dcmihandler.hpp
+++ b/dcmihandler.hpp
@@ -58,6 +58,8 @@ static constexpr auto gDCMICapabilitiesConfig =
"/usr/share/ipmi-providers/dcmi_cap.json";
static constexpr auto gDCMIPowerMgmtCapability = "PowerManagement";
static constexpr auto gDCMIPowerMgmtSupported = 0x1;
+static constexpr auto gMaxSELEntriesMask = 0xFFF;
+static constexpr auto gByteBitSize = 8;
namespace assettag
{
OpenPOWER on IntegriCloud