| From 21a741eb75f80397e5f7d3739e24d7d75e619011 Mon Sep 17 00:00:00 2001 |
| From: Nicholas Piggin <npiggin@gmail.com> |
| Date: Tue, 25 Jun 2024 23:40:47 +1000 |
| Subject: powerpc/pseries: Fix scv instruction crash with kexec |
| |
| From: Nicholas Piggin <npiggin@gmail.com> |
| |
| commit 21a741eb75f80397e5f7d3739e24d7d75e619011 upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| 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(-) |
| |
| --- a/arch/powerpc/kexec/core_64.c |
| +++ b/arch/powerpc/kexec/core_64.c |
| @@ -26,6 +26,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> |
| @@ -316,6 +317,16 @@ void default_machine_kexec(struct kimage |
| 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. |
| --- 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_sh |
| } 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); |
| -} |
| --- 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); |
| |
| --- a/arch/powerpc/platforms/pseries/setup.c |
| +++ b/arch/powerpc/platforms/pseries/setup.c |
| @@ -1149,7 +1149,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 |