[PATCH] powerpc/pseries: Fix scv instruction crash with kexec

Michal Suchánek msuchanek at suse.de
Tue Jul 9 20:53:14 AEST 2024


Hello,

On Tue, Jun 25, 2024 at 11:40:47PM +1000, Nicholas Piggin wrote:
> kexec on pseries disables AIL (reloc_on_exc), required for scv
> instruction support, before other CPUs have been shut down. This means
> they can execute scv instructions after AIL is disabled, which causes an
> interrupt at an unexpected entry location that crashes the kernel.
> 
> Change the kexec sequence to disable AIL after other CPUs have been
> brought down.
> 
> As a refresher, the real-mode scv interrupt vector is 0x17000, and the
> fixed-location head code probably couldn't easily deal with implementing
> such high addresses so it was just decided not to support that interrupt
> at all.
> 
> Reported-by: Sourabh Jain <sourabhjain at linux.ibm.com>
> Fixes: 7fa95f9adaee7 ("powerpc/64s: system call support for scv/rfscv instructions")

looks like this is only broken by
commit 2ab2d5794f14 ("powerpc/kasan: Disable address sanitization in kexec paths")

This change reverts the kexec parts done in that commit.

That is the fix is 5.19+, not 5.9+

Thanks

Michal

> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
> ---
>  arch/powerpc/kexec/core_64.c             | 11 +++++++++++
>  arch/powerpc/platforms/pseries/kexec.c   |  8 --------
>  arch/powerpc/platforms/pseries/pseries.h |  1 -
>  arch/powerpc/platforms/pseries/setup.c   |  1 -
>  4 files changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
> index 85050be08a23..72b12bc10f90 100644
> --- a/arch/powerpc/kexec/core_64.c
> +++ b/arch/powerpc/kexec/core_64.c
> @@ -27,6 +27,7 @@
>  #include <asm/paca.h>
>  #include <asm/mmu.h>
>  #include <asm/sections.h>	/* _end */
> +#include <asm/setup.h>
>  #include <asm/smp.h>
>  #include <asm/hw_breakpoint.h>
>  #include <asm/svm.h>
> @@ -317,6 +318,16 @@ void default_machine_kexec(struct kimage *image)
>  	if (!kdump_in_progress())
>  		kexec_prepare_cpus();
>  
> +#ifdef CONFIG_PPC_PSERIES
> +	/*
> +	 * This must be done after other CPUs have shut down, otherwise they
> +	 * could execute the 'scv' instruction, which is not supported with
> +	 * reloc disabled (see configure_exceptions()).
> +	 */
> +	if (firmware_has_feature(FW_FEATURE_SET_MODE))
> +		pseries_disable_reloc_on_exc();
> +#endif
> +
>  	printk("kexec: Starting switchover sequence.\n");
>  
>  	/* switch to a staticly allocated stack.  Based on irq stack code.
> diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
> index 096d09ed89f6..431be156ca9b 100644
> --- a/arch/powerpc/platforms/pseries/kexec.c
> +++ b/arch/powerpc/platforms/pseries/kexec.c
> @@ -61,11 +61,3 @@ void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
>  	} else
>  		xics_kexec_teardown_cpu(secondary);
>  }
> -
> -void pseries_machine_kexec(struct kimage *image)
> -{
> -	if (firmware_has_feature(FW_FEATURE_SET_MODE))
> -		pseries_disable_reloc_on_exc();
> -
> -	default_machine_kexec(image);
> -}
> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
> index bba4ad192b0f..3968a6970fa8 100644
> --- a/arch/powerpc/platforms/pseries/pseries.h
> +++ b/arch/powerpc/platforms/pseries/pseries.h
> @@ -38,7 +38,6 @@ static inline void smp_init_pseries(void) { }
>  #endif
>  
>  extern void pseries_kexec_cpu_down(int crash_shutdown, int secondary);
> -void pseries_machine_kexec(struct kimage *image);
>  
>  extern void pSeries_final_fixup(void);
>  
> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
> index 284a6fa04b0c..b44de0f0822f 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -1159,7 +1159,6 @@ define_machine(pseries) {
>  	.machine_check_exception = pSeries_machine_check_exception,
>  	.machine_check_log_err	= pSeries_machine_check_log_err,
>  #ifdef CONFIG_KEXEC_CORE
> -	.machine_kexec          = pseries_machine_kexec,
>  	.kexec_cpu_down         = pseries_kexec_cpu_down,
>  #endif
>  #ifdef CONFIG_MEMORY_HOTPLUG
> -- 
> 2.45.1
> 


More information about the Linuxppc-dev mailing list