[Skiboot] [PATCH] ipmi: Check for ipmi backend presence before use

Alistair Popple alistair at popple.id.au
Tue Apr 14 13:36:03 AEST 2015


Not all ipmi related functions check for a valid backend before
attempting to use it. Under normal circumstances this should not
happen as the platform should always register an ipmi backend. However
a system should be able to boot without a functional ipmi backend,
which is sometimes the case during system bringup.

This patch adds presence checks for an ipmi backend before attempting
to use it, thus allowing a system with a non-functional backend to
boot without ipmi.

Signed-off-by: Alistair Popple <alistair at popple.id.au>
---
 core/ipmi.c        | 38 ++++++++++++++++++++++++++++++++++++++
 hw/ipmi/ipmi-fru.c |  2 ++
 2 files changed, 40 insertions(+)

diff --git a/core/ipmi.c b/core/ipmi.c
index 2f91101..9d91c26 100644
--- a/core/ipmi.c
+++ b/core/ipmi.c
@@ -31,6 +31,15 @@ static struct ipmi_msg *sync_msg = NULL;
 
 void ipmi_free_msg(struct ipmi_msg *msg)
 {
+	/* ipmi_free_msg frees messages allocated by the
+	 * backend. Without a backend we couldn't have allocated
+	 * messages to free (we don't support removing backends
+	 * yet). */
+	if (!ipmi_present()) {
+		prerror("IPMI: Trying to free message without backend\n");
+		return;
+	}
+
 	msg->backend->free_msg(msg);
 }
 
@@ -63,6 +72,9 @@ struct ipmi_msg *ipmi_mkmsg(int interface, uint32_t code,
 {
 	struct ipmi_msg *msg;
 
+	if (!ipmi_present())
+		return NULL;
+
 	msg = ipmi_backend->alloc_msg(req_size, resp_size);
 	if (!msg)
 		return NULL;
@@ -81,6 +93,14 @@ struct ipmi_msg *ipmi_mkmsg(int interface, uint32_t code,
 
 int ipmi_queue_msg_head(struct ipmi_msg *msg)
 {
+	if (!ipmi_present())
+		return OPAL_HARDWARE;
+
+	if (!msg) {
+		prerror("%s: Attempting to queue NULL message\n", __func__);
+		return OPAL_PARAMETER;
+	}
+
 	return msg->backend->queue_msg_head(msg);
 }
 
@@ -88,6 +108,13 @@ int ipmi_queue_msg(struct ipmi_msg *msg)
 {
 	/* Here we could choose which interface to use if we want to support
 	   multiple interfaces. */
+	if (!ipmi_present())
+		return OPAL_HARDWARE;
+
+	if (!msg) {
+		prerror("%s: Attempting to queue NULL message\n", __func__);
+		return OPAL_PARAMETER;
+	}
 
 	return msg->backend->queue_msg(msg);
 }
@@ -124,6 +151,14 @@ void ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc, struct ipmi_msg *msg)
 
 void ipmi_queue_msg_sync(struct ipmi_msg *msg)
 {
+	if (!ipmi_present())
+		return;
+
+	if (!msg) {
+		prerror("%s: Attempting to queue NULL message\n", __func__);
+		return;
+	}
+
 	lock(&sync_lock);
 	while (sync_msg);
 	sync_msg = msg;
@@ -177,6 +212,9 @@ void ipmi_sms_attention(void)
 {
 	struct ipmi_msg *msg;
 
+	if (!ipmi_present())
+		return;
+
 	/* todo: when we handle multiple IPMI interfaces, we'll need to
 	 * ensure that this message is associated with the appropriate
 	 * backend. */
diff --git a/hw/ipmi/ipmi-fru.c b/hw/ipmi/ipmi-fru.c
index be3ca90..ddcb3d6 100644
--- a/hw/ipmi/ipmi-fru.c
+++ b/hw/ipmi/ipmi-fru.c
@@ -213,6 +213,8 @@ static int fru_write(void)
 	 */
 	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_WRITE_FRU,
 			 fru_write_complete, NULL, NULL, FRU_DATA_SIZE + 5, 2);
+	if (!msg)
+		return OPAL_RESOURCE;
 
 	msg->data[0] = fru_dev_id;	/* FRU Device ID */
 	msg->data[1] = 0x0;		/* Offset LSB (we always write a new common header) */
-- 
1.8.3.2



More information about the Skiboot mailing list