aboutsummaryrefslogtreecommitdiff
path: root/core/ipmi.c
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2014-09-15 10:58:08 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-01 14:25:26 +1000
commit7f414dbb7f7851eccbe98875b1a2cb155b592f3e (patch)
treefbc80310765c4ad1ef7be80bec7274e1dc3b47d9 /core/ipmi.c
parentd3c3e88c3111ffc10eed29fbf8cc524b7a465cb2 (diff)
downloadskiboot-7f414dbb7f7851eccbe98875b1a2cb155b592f3e.zip
skiboot-7f414dbb7f7851eccbe98875b1a2cb155b592f3e.tar.gz
skiboot-7f414dbb7f7851eccbe98875b1a2cb155b592f3e.tar.bz2
ipmi/bt: Improve message validation and allow out-of-order command responses
This patch adds validation of the ipmi cmd and netfn numbers returned by the bmc. It also ensures the sequence number is correct by searching the outstanding message queue for the corresponding sequence number. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'core/ipmi.c')
-rw-r--r--core/ipmi.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/core/ipmi.c b/core/ipmi.c
index 67086d6..04c5eaa 100644
--- a/core/ipmi.c
+++ b/core/ipmi.c
@@ -66,15 +66,23 @@ int ipmi_queue_msg(struct ipmi_msg *msg)
/* Here we could choose which interface to use if we want to support
multiple interfaces. */
- /* We should also store the original message cmd/netfn here if we wish
- to validate it when we get the response. */
-
return msg->backend->queue_msg(msg);
}
-void ipmi_cmd_done(struct ipmi_msg *msg)
+void ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc, struct ipmi_msg *msg)
{
- if (msg->cc != IPMI_CC_NO_ERROR) {
+ msg->cc = cc;
+ if (msg->cmd != cmd) {
+ prerror("IPMI: Incorrect cmd 0x%02x in response\n", cmd);
+ cc = IPMI_ERR_UNSPECIFIED;
+ }
+
+ if (msg->netfn + 1 != netfn) {
+ prerror("IPMI: Incorrect netfn 0x%02x in response\n", netfn);
+ cc = IPMI_ERR_UNSPECIFIED;
+ }
+
+ if (cc != IPMI_CC_NO_ERROR) {
prerror("IPMI: Got error response 0x%02x\n", msg->cc);
if (msg->error)
@@ -84,7 +92,6 @@ void ipmi_cmd_done(struct ipmi_msg *msg)
/* At this point the message has should have been freed by the
completion functions. */
- msg = NULL;
}
void ipmi_register_backend(struct ipmi_backend *backend)