[Skiboot] [PATCH 4/5] hw/phb3: add host sync notifier to trigger creset/CAPP disable on kexec
Frederic Barrat
fbarrat at linux.vnet.ibm.com
Fri Jan 13 00:31:54 AEDT 2017
Le 06/12/2016 à 08:16, Andrew Donnellan a écrit :
> 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;
> + }
> +}
> +
So it apparently relies on the kernel looping (in opal_shutdown()),
which may be worth a comment...
Fred
More information about the Skiboot
mailing list