powerpc/pseries: Fix scv instruction crash with kexec
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. Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions") Cc: stable@vger.kernel.org # v5.9+ Reported-by: Sourabh Jain <sourabhjain@linux.ibm.com> Closes: https://lore.kernel.org/3b4b2943-49ad-4619-b195-bc416f1d1409@linux.ibm.com Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Tested-by: Gautam Menghani <gautam@linux.ibm.com> Tested-by: Sourabh Jain <sourabhjain@linux.ibm.com> Link: https://msgid.link/20240625134047.298759-1-npiggin@gmail.com Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
a1216e62d0
commit
21a741eb75
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user