[Skiboot] [PATCH] opal/fsp: Fix opal boot failure on systems with redundant FSP

Mahesh Salgaonkar mahesh at linux.ibm.com
Mon Mar 17 15:00:03 AEDT 2025


On systems with redundant FSP, opal detects primary/backup FSPs.
However, it ends up considering Backup FSP as active_fsp and starts
mailbox communication with it. This causes opal to send IPL messages to
backup FSP instead of primary. Since primary FSP never receives IPL
messages from OPAL, it assumes that opal failed to boot and enters into
termination state.

The active_fsp is set during fsp_update_links_states() function which is
invoked during boot, through fsp_create_fsp(), as well as reset/reload,
through fsp_reinit_fsp(). During the boot, when 2 FSPs are detected by
opal, fsp_update_links_states() sets the last one as active_fsp which
may not be primary FSP.

Fix this issue by detecting/setting primary FSP as active_fsp during
opal boot.

Signed-off-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
---
 hw/fsp/fsp.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index 2fd9e5f057..3e1fa38920 100644
--- a/hw/fsp/fsp.c
+++ b/hw/fsp/fsp.c
@@ -76,6 +76,7 @@ struct fsp {
 	unsigned int		iopath_count;
 	int			active_iopath;	/* -1: no active IO path */
 	struct fsp_iopath	iopath[FSP_MAX_IOPATH];
+	bool			primary;
 };
 
 enum ipl_state {
@@ -1959,7 +1960,7 @@ static void fsp_update_links_states(struct fsp *fsp)
 	}
 
 	if (fsp->active_iopath >= 0) {
-		if (!active_fsp || (active_fsp != fsp))
+		if (active_fsp && (active_fsp != fsp))
 			active_fsp = fsp;
 
 		fsp_inbound_off = 0;
@@ -2003,8 +2004,12 @@ static void fsp_create_fsp(struct dt_node *fsp_node)
 	fsp->index = index;
 	fsp->active_iopath = -1;
 
+	if (dt_find_property(fsp_node, "primary"))
+		fsp->primary = true;
+
 	count = linksprop->len / 4;
-	prlog(PR_DEBUG, "FSP #%d: Found %d IO PATH\n", index, count);
+	prlog(PR_DEBUG, "FSP #%d: Found %d IO PATH %s\n", index, count,
+			fsp->primary ? "(Primary FSP)" : "");
 	if (count > FSP_MAX_IOPATH) {
 		prerror("FSP #%d: WARNING, limited to %d IO PATH\n",
 			index, FSP_MAX_IOPATH);
@@ -2073,6 +2078,16 @@ int fsp_fatal_msg(struct fsp_msg *msg)
 	return rc;
 }
 
+static void fsp_init_set_active(void)
+{
+	struct fsp *fsp;
+
+	/* Mark primary FSP as active fsp during boot */
+	for (fsp = first_fsp; fsp; fsp = fsp->link)
+		if (fsp->primary)
+			active_fsp = fsp;
+}
+
 static bool fsp_init_one(const char *compat)
 {
 	struct dt_node *fsp_node;
@@ -2104,6 +2119,7 @@ static bool fsp_init_one(const char *compat)
 		/* Create the FSP data structure */
 		fsp_create_fsp(fsp_node);
 	}
+	fsp_init_set_active();
 
 	return inited;
 }
-- 
2.48.1



More information about the Skiboot mailing list