[Skiboot] [PATCH v2] ipmi/power: Fix system reboot issue

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Sat Feb 16 02:22:23 AEDT 2019


Kernel makes reboot/shudown OPAL call for reboot/shutdown. Once kernel
gets response from OPAL it runs opal_poll_events() until firmware
handles the request.

On BMC based system, OPAL makes IPMI call (IPMI_CHASSIS_CONTROL) to
initiate system reboot/shutdown. At present OPAL queues IPMI messages
and return SUCESS to Host. If BMC is not ready to accept command (like
BMC reboot), then these message will fail. We have to manually
reboot/shutdown the system using BMC interface.

This patch adds logic to validate message return value. If message failed,
then it will resend the message. At some stage BMC will be ready to accept
message and handles IPMI message.

Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
---
Changes in v2:
  - Fixed use after free issue

-Vasant

 hw/ipmi/ipmi-power.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/hw/ipmi/ipmi-power.c b/hw/ipmi/ipmi-power.c
index f14a0c980..1d175dfb5 100644
--- a/hw/ipmi/ipmi-power.c
+++ b/hw/ipmi/ipmi-power.c
@@ -18,6 +18,28 @@
 #include <stdlib.h>
 #include <ipmi.h>
 #include <opal.h>
+#include <timebase.h>
+
+static void ipmi_chassis_control_complete(struct ipmi_msg *msg)
+{
+	uint8_t request = msg->data[0];
+	uint8_t cc = msg->cc;
+
+	ipmi_free_msg(msg);
+	if (cc == IPMI_CC_NO_ERROR)
+		return;
+
+	prlog(PR_INFO, "IPMI: Chassis control request failed. "
+	      "request=0x%02x, rc=0x%02x\n", request, cc);
+
+	/* Relax a bit before resending command */
+	time_wait_nopoll(100);
+
+	if (ipmi_chassis_control(request)) {
+		prlog(PR_INFO, "IPMI: Failed to resend chassis control "
+		      "request [0x%02x]\n", request);
+	}
+}
 
 int ipmi_chassis_control(uint8_t request)
 {
@@ -29,10 +51,13 @@ int ipmi_chassis_control(uint8_t request)
 	if (request > IPMI_CHASSIS_SOFT_SHUTDOWN)
 		return OPAL_PARAMETER;
 
-	msg = ipmi_mkmsg_simple(IPMI_CHASSIS_CONTROL, &request,
-				sizeof(request));
+	msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_CHASSIS_CONTROL,
+			 ipmi_chassis_control_complete, NULL,
+			 &request, sizeof(request), 0);
 	if (!msg)
 		return OPAL_HARDWARE;
+	/* Set msg->error callback function */
+	msg->error = ipmi_chassis_control_complete;
 
 	prlog(PR_INFO, "IPMI: sending chassis control request 0x%02x\n",
 			request);
-- 
2.14.3



More information about the Skiboot mailing list