[PATCH] ARM: MCPM: don't explode if invoked without being initialized first

Lorenzo Pieralisi lorenzo.pieralisi at arm.com
Tue Sep 24 04:51:02 EDT 2013


On Mon, Sep 23, 2013 at 08:24:34PM +0100, Nicolas Pitre wrote:
> 
> Currently mcpm_cpu_power_down() and mcpm_cpu_suspend() trigger BUG()
> if mcpm_platform_register() is not called beforehand.  This may occur
> for many reasons such as some incomplete device tree passed to the kernel
> or the like.
> 
> Let's be nicer to users and avoid killing the kernel if that happens by
> logging a warning and returning to the caller.  The mcpm_cpu_suspend()
> user is already set to deal with this situation, and so is cpu_die()
> invoking mcpm_cpu_die().
> 
> The problematic case would have been the B.L switcher's usage of
> mcpm_cpu_power_down(), however it has to call mcpm_cpu_power_up() first
> which is already set to catch an error resulting from a missing
> mcpm_platform_register() call.
> 
> Signed-off-by: Nicolas Pitre <nico at linaro.org>
> 
> diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c
> index 370236dd1a..3fd43f1fd2 100644
> --- a/arch/arm/common/mcpm_entry.c
> +++ b/arch/arm/common/mcpm_entry.c
> @@ -51,7 +51,8 @@ void mcpm_cpu_power_down(void)
>  {
>  	phys_reset_t phys_reset;
>  
> -	BUG_ON(!platform_ops);
> +	if (WARN_ON_ONCE(!platform_ops))
> +		return;
>  	BUG_ON(!irqs_disabled());

I think it should be:

if (WARN_ON_ONCE(!platform_ops || !platform_ops->power_down))
	return;

since even if platform_ops has been initialized we might still be end
up with a NULL function pointer.

Probably the test for the function pointer belongs in:

mcpm_platform_register()

>  
>  	/*
> @@ -93,7 +94,8 @@ void mcpm_cpu_suspend(u64 expected_residency)
>  {
>  	phys_reset_t phys_reset;
>  
> -	BUG_ON(!platform_ops);
> +	if (WARN_ON_ONCE(!platform_ops))
> +		return;

Ditto.

Thanks,
Lorenzo

>  	BUG_ON(!irqs_disabled());
>  
>  	/* Very similar to mcpm_cpu_power_down() */
> diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h
> index 0f7b7620e9..fc82a88f5b 100644
> --- a/arch/arm/include/asm/mcpm.h
> +++ b/arch/arm/include/asm/mcpm.h
> @@ -76,8 +76,11 @@ int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster);
>   *
>   * This must be called with interrupts disabled.
>   *
> - * This does not return.  Re-entry in the kernel is expected via
> - * mcpm_entry_point.
> + * On success this does not return.  Re-entry in the kernel is expected
> + * via mcpm_entry_point.
> + *
> + * This will return if mcpm_platform_register() has not been called
> + * previously in which case the caller should take appropriate action.
>   */
>  void mcpm_cpu_power_down(void);
>  
> @@ -98,8 +101,11 @@ void mcpm_cpu_power_down(void);
>   *
>   * This must be called with interrupts disabled.
>   *
> - * This does not return.  Re-entry in the kernel is expected via
> - * mcpm_entry_point.
> + * On success this does not return.  Re-entry in the kernel is expected
> + * via mcpm_entry_point.
> + *
> + * This will return if mcpm_platform_register() has not been called
> + * previously in which case the caller should take appropriate action.
>   */
>  void mcpm_cpu_suspend(u64 expected_residency);
>  
> 




More information about the linux-arm-kernel mailing list