diff --git a/srcpkgs/linux5.10/patches/page-poison-fix.patch b/srcpkgs/linux5.10/patches/page-poison-fix.patch deleted file mode 100644 index d319dfec824..00000000000 --- a/srcpkgs/linux5.10/patches/page-poison-fix.patch +++ /dev/null @@ -1,58 +0,0 @@ -This breaks page poisoning on some architectures. The commit is not -very useful by itself, so revert it until a real fix is upstream. - -From 0cbb20875a8607653f02d799fd4b75a34d1b6636 Mon Sep 17 00:00:00 2001 -From: q66 -Date: Mon, 25 Jan 2021 02:59:47 +0100 -Subject: [PATCH] Revert "mm/page_poison.c: replace bool variable with static - key" - -This reverts commit 11c9c7edae06da789abfdeefe5123162a3f1c7dc. ---- - mm/page_poison.c | 20 +++++--------------- - 1 file changed, 5 insertions(+), 15 deletions(-) - -diff --git a/mm/page_poison.c b/mm/page_poison.c -index ae0482c..34b9181 100644 ---- a/mm/page_poison.c -+++ b/mm/page_poison.c -@@ -8,23 +8,13 @@ - #include - #include - --static DEFINE_STATIC_KEY_FALSE_RO(want_page_poisoning); -+static bool want_page_poisoning __read_mostly; - - static int __init early_page_poison_param(char *buf) - { -- int ret; -- bool tmp; -- -- ret = strtobool(buf, &tmp); -- if (ret) -- return ret; -- -- if (tmp) -- static_branch_enable(&want_page_poisoning); -- else -- static_branch_disable(&want_page_poisoning); -- -- return 0; -+ if (!buf) -+ return -EINVAL; -+ return strtobool(buf, &want_page_poisoning); - } - early_param("page_poison", early_page_poison_param); - -@@ -41,7 +31,7 @@ bool page_poisoning_enabled(void) - * Page poisoning is debug page alloc for some arches. If - * either of those options are enabled, enable poisoning. - */ -- return (static_branch_unlikely(&want_page_poisoning) || -+ return (want_page_poisoning || - (!IS_ENABLED(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) && - debug_pagealloc_enabled())); - } --- -2.30.0 - diff --git a/srcpkgs/linux5.10/patches/ppc-stack-traces-early-boot.patch b/srcpkgs/linux5.10/patches/ppc-stack-traces-early-boot.patch new file mode 100644 index 00000000000..08b250113f3 --- /dev/null +++ b/srcpkgs/linux5.10/patches/ppc-stack-traces-early-boot.patch @@ -0,0 +1,37 @@ +From 0ecf6a9e47d825b7dddfebca738386b809e59a94 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 3 Feb 2021 00:02:06 +1100 +Subject: powerpc/64: Make stack tracing work during very early boot + +If we try to stack trace very early during boot, either due to a +WARN/BUG or manual dump_stack(), we will oops in +valid_emergency_stack() when we try to dereference the paca_ptrs +array. + +The fix is simple, we just return false if paca_ptrs isn't allocated +yet. The stack pointer definitely isn't part of any emergency stack +because we haven't allocated any yet. + +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20210202130207.1303975-1-mpe@ellerman.id.au +--- + arch/powerpc/kernel/process.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c +index 8520ed5ae144d..e296440e9d16a 100644 +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -2047,6 +2047,9 @@ static inline int valid_emergency_stack(unsigned long sp, struct task_struct *p, + unsigned long stack_page; + unsigned long cpu = task_cpu(p); + ++ if (!paca_ptrs) ++ return 0; ++ + stack_page = (unsigned long)paca_ptrs[cpu]->emergency_sp - THREAD_SIZE; + if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) + return 1; +-- +cgit 1.2.3-1.el7 + diff --git a/srcpkgs/linux5.10/patches/ppc64le-fix-static-keys.patch b/srcpkgs/linux5.10/patches/ppc64le-fix-static-keys.patch new file mode 100644 index 00000000000..d48f4039581 --- /dev/null +++ b/srcpkgs/linux5.10/patches/ppc64le-fix-static-keys.patch @@ -0,0 +1,140 @@ +From e7eb919057c3450cdd9d335e4a23a4da8da58db4 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 3 Feb 2021 00:02:07 +1100 +Subject: [PATCH] powerpc/64s: Handle program checks in wrong endian during + early boot + +There's a short window during boot where although the kernel is +running little endian, any exceptions will cause the CPU to switch +back to big endian. This situation persists until we call +configure_exceptions(), which calls either the hypervisor or OPAL to +configure the CPU so that exceptions will be taken in little +endian (via HID0[HILE]). + +We don't intend to take exceptions during early boot, but one way we +sometimes do is via a WARN/BUG etc. Those all boil down to a trap +instruction, which will cause a program check exception. + +The first instruction of the program check handler is an mtsprg, which +when executed in the wrong endian is an lhzu with a ~3GB displacement +from r3. The content of r3 is random, so that becomes a load from some +random location, and depending on the system (installed RAM etc.) can +easily lead to a checkstop, or an infinitely recursive page fault. +That prevents whatever the WARN/BUG was complaining about being +printed to the console, and the user just sees a dead system. + +We can fix it by having a trampoline at the beginning of the program +check handler that detects we are in the wrong endian, and flips us +back to the correct endian. + +We can't flip MSR[LE] using mtmsr (alas), so we have to use rfid. That +requires backing up SRR0/1 as well as a GPR. To do that we use +SPRG0/2/3 (SPRG1 is already used for the paca). SPRG3 is user +readable, but this trampoline is only active very early in boot, and +SPRG3 will be reinitialised in vdso_getcpu_init() before userspace +starts. + +With this trampoline in place we can survive a WARN early in boot and +print a stack trace, which is eventually printed to the console once +the console is up, eg: + + [83565.758545] kexec_core: Starting new kernel + [ 0.000000] ------------[ cut here ]------------ + [ 0.000000] static_key_enable_cpuslocked(): static key '0xc000000000ea6160' used before call to jump_label_init() + [ 0.000000] WARNING: CPU: 0 PID: 0 at kernel/jump_label.c:166 static_key_enable_cpuslocked+0xfc/0x120 + [ 0.000000] Modules linked in: + [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.10.0-gcc-8.2.0-dirty #618 + [ 0.000000] NIP: c0000000002fd46c LR: c0000000002fd468 CTR: c000000000170660 + [ 0.000000] REGS: c000000001227940 TRAP: 0700 Not tainted (5.10.0-gcc-8.2.0-dirty) + [ 0.000000] MSR: 9000000002823003 CR: 24882422 XER: 20040000 + [ 0.000000] CFAR: 0000000000000730 IRQMASK: 1 + [ 0.000000] GPR00: c0000000002fd468 c000000001227bd0 c000000001228300 0000000000000065 + [ 0.000000] GPR04: 0000000000000001 0000000000000065 c0000000010cf970 000000000000000d + [ 0.000000] GPR08: 0000000000000000 0000000000000000 0000000000000000 c00000000122763f + [ 0.000000] GPR12: 0000000000002000 c000000000f8a980 0000000000000000 0000000000000000 + [ 0.000000] GPR16: 0000000000000000 0000000000000000 c000000000f88c8e c000000000f88c9a + [ 0.000000] GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + [ 0.000000] GPR24: 0000000000000000 c000000000dea3a8 0000000000000000 c000000000f35114 + [ 0.000000] GPR28: 0000002800000000 c000000000f88c9a c000000000f88c8e c000000000ea6160 + [ 0.000000] NIP [c0000000002fd46c] static_key_enable_cpuslocked+0xfc/0x120 + [ 0.000000] LR [c0000000002fd468] static_key_enable_cpuslocked+0xf8/0x120 + [ 0.000000] Call Trace: + [ 0.000000] [c000000001227bd0] [c0000000002fd468] static_key_enable_cpuslocked+0xf8/0x120 (unreliable) + [ 0.000000] [c000000001227c40] [c0000000002fd4c0] static_key_enable+0x30/0x50 + [ 0.000000] [c000000001227c70] [c000000000f6629c] early_page_poison_param+0x58/0x9c + [ 0.000000] [c000000001227cb0] [c000000000f351b8] do_early_param+0xa4/0x10c + [ 0.000000] [c000000001227d30] [c00000000011e020] parse_args+0x270/0x5e0 + [ 0.000000] [c000000001227e20] [c000000000f35864] parse_early_options+0x48/0x5c + [ 0.000000] [c000000001227e40] [c000000000f358d0] parse_early_param+0x58/0x84 + [ 0.000000] [c000000001227e70] [c000000000f3a368] early_init_devtree+0xc4/0x490 + [ 0.000000] [c000000001227f10] [c000000000f3bca0] early_setup+0xc8/0x1c8 + [ 0.000000] [c000000001227f90] [000000000000c320] 0xc320 + [ 0.000000] Instruction dump: + [ 0.000000] 4bfffddd 7c2004ac 39200001 913f0000 4bffffb8 7c651b78 3c82ffac 3c62ffc0 + [ 0.000000] 38841b00 3863f310 4bdf03a5 60000000 <0fe00000> 4bffff38 60000000 60000000 + [ 0.000000] random: get_random_bytes called from print_oops_end_marker+0x40/0x80 with crng_init=0 + [ 0.000000] ---[ end trace 0000000000000000 ]--- + [ 0.000000] dt-cpu-ftrs: setup for ISA 3000 + +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20210202130207.1303975-2-mpe@ellerman.id.au +--- + arch/powerpc/kernel/exceptions-64s.S | 45 ++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + +diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S +index b3793f982b2be..c51c436d5845f 100644 +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -1630,6 +1630,51 @@ INT_DEFINE_BEGIN(program_check) + INT_DEFINE_END(program_check) + + EXC_REAL_BEGIN(program_check, 0x700, 0x100) ++ ++#ifdef CONFIG_CPU_LITTLE_ENDIAN ++ /* ++ * There's a short window during boot where although the kernel is ++ * running little endian, any exceptions will cause the CPU to switch ++ * back to big endian. For example a WARN() boils down to a trap ++ * instruction, which will cause a program check, and we end up here but ++ * with the CPU in big endian mode. The first instruction of the program ++ * check handler (in GEN_INT_ENTRY below) is an mtsprg, which when ++ * executed in the wrong endian is an lhzu with a ~3GB displacement from ++ * r3. The content of r3 is random, so that is a load from some random ++ * location, and depending on the system can easily lead to a checkstop, ++ * or an infinitely recursive page fault. ++ * ++ * So to handle that case we have a trampoline here that can detect we ++ * are in the wrong endian and flip us back to the correct endian. We ++ * can't flip MSR[LE] using mtmsr, so we have to use rfid. That requires ++ * backing up SRR0/1 as well as a GPR. To do that we use SPRG0/2/3, as ++ * SPRG1 is already used for the paca. SPRG3 is user readable, but this ++ * trampoline is only active very early in boot, and SPRG3 will be ++ * reinitialised in vdso_getcpu_init() before userspace starts. ++ */ ++BEGIN_FTR_SECTION ++ tdi 0,0,0x48 // Trap never, or in reverse endian: b . + 8 ++ b 1f // Skip trampoline if endian is correct ++ .long 0xa643707d // mtsprg 0, r11 Backup r11 ++ .long 0xa6027a7d // mfsrr0 r11 ++ .long 0xa643727d // mtsprg 2, r11 Backup SRR0 in SPRG2 ++ .long 0xa6027b7d // mfsrr1 r11 ++ .long 0xa643737d // mtsprg 3, r11 Backup SRR1 in SPRG3 ++ .long 0xa600607d // mfmsr r11 ++ .long 0x01006b69 // xori r11, r11, 1 Invert MSR[LE] ++ .long 0xa6037b7d // mtsrr1 r11 ++ .long 0x34076039 // li r11, 0x734 ++ .long 0xa6037a7d // mtsrr0 r11 ++ .long 0x2400004c // rfid ++ mfsprg r11, 3 ++ mtsrr1 r11 // Restore SRR1 ++ mfsprg r11, 2 ++ mtsrr0 r11 // Restore SRR0 ++ mfsprg r11, 0 // Restore r11 ++1: ++END_FTR_SECTION(0, 1) // nop out after boot ++#endif /* CONFIG_CPU_LITTLE_ENDIAN */ ++ + GEN_INT_ENTRY program_check, virt=0 + EXC_REAL_END(program_check, 0x700, 0x100) + EXC_VIRT_BEGIN(program_check, 0x4700, 0x100)