From 87a65e63bac789bca0607e0b4ab09d62517b95e7 Mon Sep 17 00:00:00 2001 From: Ed Tanous Date: Wed, 29 May 2019 10:29:58 -0700 Subject: Update to internal Signed-off-by: Ed Tanous --- ...-Implement-IPMI-Master-Write-Read-command.patch | 351 --------------------- 1 file changed, 351 deletions(-) delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0048-Implement-IPMI-Master-Write-Read-command.patch (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0048-Implement-IPMI-Master-Write-Read-command.patch') diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0048-Implement-IPMI-Master-Write-Read-command.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0048-Implement-IPMI-Master-Write-Read-command.patch deleted file mode 100644 index 542c4f667..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0048-Implement-IPMI-Master-Write-Read-command.patch +++ /dev/null @@ -1,351 +0,0 @@ -From a8d7429b7bd9dea33d59c6e83f17372e77fe6145 Mon Sep 17 00:00:00 2001 -From: Yong Li -Date: Fri, 21 Sep 2018 09:21:14 +0800 -Subject: [PATCH] Implement IPMI Master Write-Read command - -This command can be used for low-level I2C/SMBus write, read, or write-read -accesses to the IPMB or private busses behind a management controller. - -The command can also be used for providing low-level access to devices -that provide an SMBus slave interface. - -Signed-off-by: Yong Li ---- - apphandler.cpp | 276 +++++++++++++++++++++++++++++++++++++- - apphandler.hpp | 1 + - host-ipmid-whitelist.conf | 1 + - 3 files changed, 274 insertions(+), 4 deletions(-) - -diff --git a/apphandler.cpp b/apphandler.cpp -index 15965ca..d8fb23d 100644 ---- a/apphandler.cpp -+++ b/apphandler.cpp -@@ -1,6 +1,19 @@ -+#include "apphandler.hpp" -+ -+#include "app/watchdog.hpp" -+#include "sys_info_param.hpp" -+#include "transporthandler.hpp" -+ - #include -+#include -+#include - #include -+#include -+#include - #include -+#include -+#include -+#include - #include - #include - -@@ -41,6 +54,8 @@ constexpr auto bmc_guid_interface = "xyz.openbmc_project.Common.UUID"; - constexpr auto bmc_guid_property = "UUID"; - constexpr auto bmc_guid_len = 16; - -+static constexpr uint8_t maxIPMIWriteReadSize = 144; -+ - static constexpr auto redundancyIntf = - "xyz.openbmc_project.Software.RedundancyPriority"; - static constexpr auto versionIntf = "xyz.openbmc_project.Software.Version"; -@@ -59,6 +74,47 @@ using BMC = sdbusplus::xyz::openbmc_project::State::server::BMC; - namespace fs = std::filesystem; - namespace variant_ns = sdbusplus::message::variant_ns; - -+// Offset in get device id command. -+typedef struct -+{ -+ uint8_t id; -+ uint8_t revision; -+ uint8_t fw[2]; -+ uint8_t ipmi_ver; -+ uint8_t addn_dev_support; -+ uint8_t manuf_id[3]; -+ uint8_t prod_id[2]; -+ uint8_t aux[4]; -+} __attribute__((packed)) ipmi_device_id_t; -+ -+typedef struct -+{ -+ uint8_t busId; -+ uint8_t slaveAddr; -+ uint8_t readCount; -+} __attribute__((packed)) ipmiI2cRwReq; -+ -+typedef struct -+{ -+ uint8_t busId; -+ uint8_t slaveAddr; -+ std::vector data; -+} ipmiMasterRwWhitelist; -+ -+static std::vector& getWhiteList() -+{ -+ static std::vector rwWhiteList; -+ return rwWhiteList; -+} -+ -+static constexpr const char* whiteListFilename = -+ "/usr/share/ipmi-providers/master_write_read_white_list.json"; -+ -+static constexpr const char* filtersStr = "filters"; -+static constexpr const char* busIdStr = "busId"; -+static constexpr const char* slaveAddrStr = "slaveAddr"; -+static constexpr const char* cmdStr = "command"; -+ - /** - * @brief Returns the Version info from primary s/w object - * -@@ -1022,6 +1078,192 @@ writeResponse: - return IPMI_CC_OK; - } - -+static int loadI2CWhiteList() -+{ -+ nlohmann::json data = nullptr; -+ std::ifstream jsonFile(whiteListFilename); -+ -+ if (!jsonFile.good()) -+ { -+ log("whitelist file not found!"); -+ return -1; -+ } -+ -+ try -+ { -+ data = nlohmann::json::parse(jsonFile, nullptr, false); -+ } -+ catch (nlohmann::json::parse_error& e) -+ { -+ log("Corrupted whitelist config file", -+ entry("MSG: %s", e.what())); -+ return -1; -+ } -+ -+ try -+ { -+ unsigned int i = 0; -+ nlohmann::json filters = data[filtersStr].get(); -+ getWhiteList().resize(filters.size()); -+ -+ for (const auto& it : filters.items()) -+ { -+ nlohmann::json filter = it.value(); -+ if (filter.is_null()) -+ { -+ log("Incorrect filter"); -+ return -1; -+ } -+ -+ getWhiteList()[i].busId = -+ std::stoul(filter[busIdStr].get(), nullptr, 16); -+ -+ getWhiteList()[i].slaveAddr = std::stoul( -+ filter[slaveAddrStr].get(), nullptr, 16); -+ -+ std::string command = filter[cmdStr].get(); -+ -+ log("IPMI I2C whitelist ", entry("INDEX=%d", i), -+ entry("BUS=%d", getWhiteList()[i].busId), -+ entry("ADDR=0x%x", getWhiteList()[i].slaveAddr), -+ entry("LEN=0x%x", command.length()), -+ entry("COMMAND=[%s]", command.c_str())); -+ -+ // convert data string -+ std::istringstream iss(command); -+ std::string token; -+ while (std::getline(iss, token, ' ')) -+ { -+ log("IPMI I2C command\n", -+ entry("TOKEN=%s", token.c_str())); -+ getWhiteList()[i].data.emplace_back( -+ std::stoul(token, nullptr, 16)); -+ } -+ i++; -+ } -+ } -+ catch (std::exception& e) -+ { -+ log("unexpected exception", entry("ERROR=%s", e.what())); -+ return -1; -+ } -+ return 0; -+} -+ -+ipmi_ret_t ipmiMasterWriteRead(ipmi_netfn_t netfn, ipmi_cmd_t cmd, -+ ipmi_request_t request, ipmi_response_t response, -+ ipmi_data_len_t data_len, ipmi_context_t context) -+{ -+ bool foundInList = false; -+ int ret = 0; -+ i2c_rdwr_ioctl_data msgRdwr = {0}; -+ i2c_msg i2cmsg[2] = {0}; -+ ipmiI2cRwReq* reqi2c = reinterpret_cast(request); -+ -+ if (*data_len <= sizeof(ipmiI2cRwReq)) -+ { -+ log("Failed in request", entry("LEN=%d", *data_len)); -+ *data_len = 0; -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ if (reqi2c->readCount > maxIPMIWriteReadSize) -+ { -+ log("Failed in request", entry("R=%d", reqi2c->readCount)); -+ *data_len = 0; -+ return IPMI_CC_PARM_OUT_OF_RANGE; -+ } -+ -+ uint8_t* resptr = reinterpret_cast(response); -+ uint8_t busId = (reqi2c->busId & 0xFF) >> 1; -+ // Convert the I2C address from 7-bit format -+ uint8_t i2cAddr = reqi2c->slaveAddr >> 1; -+ size_t writeCount = *data_len - sizeof(ipmiI2cRwReq); -+ -+ log( -+ "INPUT: ", entry("LEN=%d", *data_len), entry("ID=0x%x", busId), -+ entry("ADDR=0x%x", reqi2c->slaveAddr), entry("R=%d", reqi2c->readCount), -+ entry("W=%d", writeCount)); -+ -+ *data_len = 0; -+ -+ std::vector inBuf(reqi2c->readCount); -+ std::vector outBuf(writeCount); -+ uint8_t* reqptr = reinterpret_cast(request); -+ -+ reqptr += sizeof(ipmiI2cRwReq); -+ std::copy(reqptr, reqptr + writeCount, outBuf.begin()); -+ -+ log("checking list ", -+ entry("SIZE=%d", getWhiteList().size())); -+ // command whitelist checking -+ for (unsigned int i = 0; i < getWhiteList().size(); i++) -+ { -+ // TODO add wildchard/regex support -+ if ((busId == getWhiteList()[i].busId) && -+ (i2cAddr == getWhiteList()[i].slaveAddr) && -+ (outBuf == getWhiteList()[i].data)) -+ { -+ log("In whitelist"); -+ foundInList = true; -+ break; -+ } -+ } -+ -+ if (!foundInList) -+ { -+ log("Request blocked!", entry("BUS=%d", busId), -+ entry("ADDR=0x%x", reqi2c->slaveAddr)); -+ return IPMI_CC_INVALID_FIELD_REQUEST; -+ } -+ -+ log("IPMI Master WriteRead ", entry("BUS=%d", busId), -+ entry("ADDR=0x%x", reqi2c->slaveAddr), -+ entry("R=%d", reqi2c->readCount), -+ entry("W=%d", writeCount)); -+ -+ std::string i2cBus = "/dev/i2c-" + std::to_string(busId); -+ -+ int i2cDev = ::open(i2cBus.c_str(), O_RDWR | O_CLOEXEC); -+ if (i2cDev < 0) -+ { -+ log("Failed in opening i2c device", -+ entry("BUS=%s", i2cBus.c_str())); -+ return IPMI_CC_UNSPECIFIED_ERROR; -+ } -+ -+ // write message -+ i2cmsg[0].addr = i2cAddr; -+ i2cmsg[0].flags = 0x00; -+ i2cmsg[0].len = writeCount; -+ i2cmsg[0].buf = outBuf.data(); -+ -+ // read message -+ i2cmsg[1].addr = i2cAddr; -+ i2cmsg[1].flags = I2C_M_RD; -+ i2cmsg[1].len = reqi2c->readCount; -+ i2cmsg[1].buf = inBuf.data(); -+ -+ msgRdwr.msgs = i2cmsg; -+ msgRdwr.nmsgs = 2; -+ -+ ret = ::ioctl(i2cDev, I2C_RDWR, &msgRdwr); -+ ::close(i2cDev); -+ -+ // TODO add completion code support -+ if (ret < 0) -+ { -+ log("RDWR ioctl error", entry("RET=%d", ret)); -+ return IPMI_CC_UNSPECIFIED_ERROR; -+ } -+ -+ *data_len = msgRdwr.msgs[1].len; -+ std::copy(msgRdwr.msgs[1].buf, msgRdwr.msgs[1].buf + msgRdwr.msgs[1].len, -+ resptr); -+ -+ return IPMI_CC_OK; -+} -+ - void register_netfn_app_functions() - { - // -@@ -1063,6 +1306,31 @@ void register_netfn_app_functions() - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_ACPI, NULL, - ipmi_app_get_acpi_power_state, PRIVILEGE_ADMIN); - -+// TODO: Below code and associated api's need to be removed later. -+// Its commented for now to avoid merge conflicts with upstream -+// changes and smooth upstream upgrades. -+#if 0 -+>>>>>>> IPMI Channel commands implementation -+ // -+ ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL, -+ ipmi_get_channel_access, PRIVILEGE_USER); -+ -+ // -+ ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_INFO, NULL, -+ ipmi_app_channel_info, PRIVILEGE_USER); -+#endif -+ -+ int ret = loadI2CWhiteList(); -+ log("i2c white list is loaded", entry("RET=%d", ret), -+ entry("SIZE=%d", getWhiteList().size())); -+ if (ret == 0) -+ { -+ log("Register Master RW command"); -+ // -+ ipmi_register_callback(NETFUN_APP, IPMI_CMD_MASTER_WRITE_READ, NULL, -+ ipmiMasterWriteRead, PRIVILEGE_OPERATOR); -+ } -+ - // - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SYS_GUID, NULL, - ipmi_app_get_sys_guid, PRIVILEGE_USER); -diff --git a/apphandler.hpp b/apphandler.hpp -index d4dd8e8..f9e5c59 100644 ---- a/apphandler.hpp -+++ b/apphandler.hpp -@@ -19,6 +19,7 @@ enum ipmi_netfn_app_cmds - IPMI_CMD_SET_CHAN_ACCESS = 0x40, - IPMI_CMD_GET_CHANNEL_ACCESS = 0x41, - IPMI_CMD_GET_CHAN_INFO = 0x42, -+ IPMI_CMD_MASTER_WRITE_READ = 0x52, - IPMI_CMD_GET_CHAN_CIPHER_SUITES = 0x54, - IPMI_CMD_SET_SYSTEM_INFO = 0x58, - IPMI_CMD_GET_SYSTEM_INFO = 0x59, -diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf -index 49ff7b0..1ae79fd 100644 ---- a/host-ipmid-whitelist.conf -+++ b/host-ipmid-whitelist.conf -@@ -27,6 +27,7 @@ - 0x06:0x37 //: - 0x06:0x42 //: - 0x06:0x4E //: -+0x06:0x52 //: - 0x06:0x54 //: - 0x0A:0x10 //: - 0x0A:0x11 //: --- -2.17.1 - -- cgit v1.2.3