[PATCH] powerpc/lib: fix book3s/32 boot failure due to code patching

Michael Neuling mikey at neuling.org
Tue Oct 2 09:19:50 AEST 2018


On Mon, 2018-10-01 at 12:21 +0000, Christophe Leroy wrote:
> Commit 51c3c62b58b3 ("powerpc: Avoid code patching freed init
> sections") accesses 'init_mem_is_free' flag too early, before the
> kernel is relocated. This provokes early boot failure (before the
> console is active).
> 
> As it is not necessary to do this verification that early, this
> patch moves the test into patch_instruction() instead of
> __patch_instruction().
> 
> This modification also has the advantage of avoiding unnecessary
> remappings.
> 
> Fixes: 51c3c62b58b3 ("powerpc: Avoid code patching freed init sections")
> Signed-off-by: Christophe Leroy <christophe.leroy at c-s.fr>

Thanks

Acked-by: Michael Neuling <mikey at neuling.org>

The original patch was also marked for stable so we should do the same here.

Cc: stable at vger.kernel.org # 4.13+

> ---
>  arch/powerpc/lib/code-patching.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 6ae2777c220d..5ffee298745f 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -28,12 +28,6 @@ static int __patch_instruction(unsigned int *exec_addr,
> unsigned int instr,
>  {
>  	int err;
>  
> -	/* Make sure we aren't patching a freed init section */
> -	if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
> -		pr_debug("Skipping init section patching addr: 0x%px\n",
> exec_addr);
> -		return 0;
> -	}
> -
>  	__put_user_size(instr, patch_addr, 4, err);
>  	if (err)
>  		return err;
> @@ -148,7 +142,7 @@ static inline int unmap_patch_area(unsigned long addr)
>  	return 0;
>  }
>  
> -int patch_instruction(unsigned int *addr, unsigned int instr)
> +static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>  {
>  	int err;
>  	unsigned int *patch_addr = NULL;
> @@ -188,12 +182,22 @@ int patch_instruction(unsigned int *addr, unsigned int
> instr)
>  }
>  #else /* !CONFIG_STRICT_KERNEL_RWX */
>  
> -int patch_instruction(unsigned int *addr, unsigned int instr)
> +static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>  {
>  	return raw_patch_instruction(addr, instr);
>  }
>  
>  #endif /* CONFIG_STRICT_KERNEL_RWX */
> +
> +int patch_instruction(unsigned int *addr, unsigned int instr)
> +{
> +	/* Make sure we aren't patching a freed init section */
> +	if (init_mem_is_free && init_section_contains(addr, 4)) {
> +		pr_debug("Skipping init section patching addr: 0x%px\n", addr);
> +		return 0;
> +	}
> +	return do_patch_instruction(addr, instr);
> +}
>  NOKPROBE_SYMBOL(patch_instruction);
>  
>  int patch_branch(unsigned int *addr, unsigned long target, int flags)


More information about the Linuxppc-dev mailing list