[PATCH v9 2/7] powerpc/code-patching: Handle RWX patching initialisation error

Christophe Leroy christophe.leroy at csgroup.eu
Wed Nov 2 20:36:06 AEDT 2022



Le 25/10/2022 à 06:44, Benjamin Gray a écrit :
> Detect and abort __do_patch_instruction() when there is no text_poke_area,
> which implies there is no patching address. This allows patch_instruction()
> to fail gracefully and let the caller decide what to do, as opposed to
> the current behaviour of kernel panicking when the null pointer is
> dereferenced.

Is there any reason at all to have no text_poke_area ?

If that's the boot CPU, then it means we are really early in the boot 
process and will use raw_patch_instruction() directly. Or it means we 
don't have enough memory for the boot CPU, in which case you are going 
to have so many problems that it is not worth any effort.

If it is not the boot CPU, isn't there a way to not add a CPU for which 
the allocation has failed ? If text_area_cpu_up() returns an error, 
isn't the CPU deactivated ?



> 
> Signed-off-by: Benjamin Gray <bgray at linux.ibm.com>
> ---
> v9:	* New in v9
> ---
>   arch/powerpc/lib/code-patching.c | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> index ad0cf3108dd0..54e145247643 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -76,6 +76,7 @@ static int text_area_cpu_up(unsigned int cpu)
>   static int text_area_cpu_down(unsigned int cpu)
>   {
>   	free_vm_area(this_cpu_read(text_poke_area));
> +	this_cpu_write(text_poke_area, NULL);
>   	return 0;
>   }
>   
> @@ -151,11 +152,16 @@ static int __do_patch_instruction(u32 *addr, ppc_inst_t instr)
>   {
>   	int err;
>   	u32 *patch_addr;
> +	struct vm_struct *area;
>   	unsigned long text_poke_addr;
>   	pte_t *pte;
>   	unsigned long pfn = get_patch_pfn(addr);
>   
> -	text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr & PAGE_MASK;
> +	area = __this_cpu_read(text_poke_area);
> +	if (unlikely(!area))
> +		return -ENOMEM;
> +
> +	text_poke_addr = (unsigned long)area->addr & PAGE_MASK;
>   	patch_addr = (u32 *)(text_poke_addr + offset_in_page(addr));
>   
>   	pte = virt_to_kpte(text_poke_addr);


More information about the Linuxppc-dev mailing list