[Skiboot] [PATCH 4/5] hw/phb3: add host sync notifier to trigger creset/CAPP disable on kexec

Andrew Donnellan andrew.donnellan at au1.ibm.com
Tue Dec 6 18:16:21 AEDT 2016


To support kexec in Linux, we need to trigger a creset to disable CAPP mode
on each PHB that has been attached to a CAPP.

Add a host sync notifier, phb3_host_sync_reset(), that will be triggered by
the opal_sync_host_reboot() call that Linux makes when "shutting down" a
powernv system (this includes bringing the system down to prepare it for
kexec). This notifier will trigger a creset only on PHBs that need it, and
will poll regularly until the creset completes.

This approach is somewhat hacky, as it's somewhat of an abuse of the host
sync notifier system (IMHO), but it seems the most obvious way to
ensure that the reset/CAPP disable occurs that will work with old kernel
versions and not require additional support on the kernel side.

Suggested-by: Stewart Smith <stewart at linux.vnet.ibm.com>
Signed-off-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
---
 hw/phb3.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+), 0 deletions(-)

diff --git a/hw/phb3.c b/hw/phb3.c
index 7a09759..83a3e6f 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -4526,6 +4526,34 @@ static bool phb3_calculate_windows(struct phb3 *p)
 	return true;
 }
 
+static bool phb3_host_sync_reset(void *data)
+{
+	struct phb3 *p = (struct phb3 *)data;
+	struct pci_slot *slot = p->phb.slot;
+	struct proc_chip *chip = get_chip(p->chip_id);
+	int64_t rc;
+
+	switch (slot->state) {
+	case PHB3_SLOT_NORMAL:
+		lock(&capi_lock);
+		rc = (chip->capp_phb3_attached_mask & (1 << p->index)) ?
+			OPAL_PHB_CAPI_MODE_CAPI :
+			OPAL_PHB_CAPI_MODE_PCIE;
+		unlock(&capi_lock);
+
+		if (rc == OPAL_PHB_CAPI_MODE_PCIE)
+			return true;
+
+		PHBINF(p, "PHB in CAPI mode, resetting\n");
+		p->flags &= ~PHB3_CAPP_RECOVERY;
+		phb3_creset(slot);
+		return false;
+	default:
+		rc = slot->ops.poll(slot);
+		return rc == OPAL_SUCCESS;
+	}
+}
+
 static void phb3_create(struct dt_node *np)
 {
 	const struct dt_property *prop;
@@ -4659,6 +4687,8 @@ static void phb3_create(struct dt_node *np)
 	/* Load capp microcode into capp unit */
 	capp_load_ucode(p);
 
+	opal_add_host_sync_notifier(phb3_host_sync_reset, p);
+
 	/* Platform additional setup */
 	if (platform.pci_setup_phb)
 		platform.pci_setup_phb(&p->phb, p->index);
-- 
git-series 0.8.7



More information about the Skiboot mailing list