[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