diff options
author | Alistair Popple <alistair@popple.id.au> | 2014-09-15 10:58:08 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-10-01 14:25:26 +1000 |
commit | 7f414dbb7f7851eccbe98875b1a2cb155b592f3e (patch) | |
tree | fbc80310765c4ad1ef7be80bec7274e1dc3b47d9 /core/ipmi.c | |
parent | d3c3e88c3111ffc10eed29fbf8cc524b7a465cb2 (diff) | |
download | skiboot-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.c | 19 |
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) |