]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
powerpc/pseries: Fix scv instruction crash with kexec
authorNicholas Piggin <npiggin@gmail.com>
Tue, 25 Jun 2024 13:40:47 +0000 (23:40 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Jul 2024 10:51:18 +0000 (12:51 +0200)
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
arch/powerpc/platforms/pseries/kexec.c
arch/powerpc/platforms/pseries/pseries.h
arch/powerpc/platforms/pseries/setup.c

index 762e4d09aacfab4989f3cdd83b674970ae7e64cc..27254624f6389e536d896ea574c441fdf6ba2577 100644 (file)
@@ -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>
@@ -315,6 +316,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.
index 096d09ed89f673378626d6441e9fe94f45a99ba7..431be156ca9bb3138065ad6981607725d54efb7d 100644 (file)
@@ -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);
-}
index bba4ad192b0fe4edfe17dc334237b8930f56ec79..3968a6970fa81d6abbd39f89590baca68766af35 100644 (file)
@@ -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);
 
index 284a6fa04b0c27b8b0345986eff654a1ea4058db..b44de0f0822f0e0075e49766168f7ac6f7e73498 100644 (file)
@@ -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