aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2017-01-11 10:57:49 +0100
committerFelix Fietkau <nbd@nbd.name>2017-01-15 18:25:54 +0100
commit1708644f1915eb7587a904d81da0ef0b559d1567 (patch)
tree15fd746c87d428ef513ee95fc69ded44fbf7e2ea /target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch
parentb02636fcb4b16d437442f817a60a30e9b7ce4ed2 (diff)
downloadupstream-1708644f1915eb7587a904d81da0ef0b559d1567.tar.gz
upstream-1708644f1915eb7587a904d81da0ef0b559d1567.tar.bz2
upstream-1708644f1915eb7587a904d81da0ef0b559d1567.zip
kernel: backport MIPS changes introducing a separate IRQ stack
Prevents crashes when IRQs arrive when the current kernel stack context already contains deeply nested function calls, e.g. when stacking lots of network devices on top of each other Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch')
-rw-r--r--target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch42
1 files changed, 42 insertions, 0 deletions
diff --git a/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch b/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch
new file mode 100644
index 0000000000..513e904e52
--- /dev/null
+++ b/target/linux/generic/patches-4.4/062-02-MIPS-Stack-unwinding-while-on-IRQ-stack.patch
@@ -0,0 +1,42 @@
+From: Matt Redfearn <matt.redfearn@imgtec.com>
+Date: Mon, 19 Dec 2016 14:20:57 +0000
+Subject: [PATCH] MIPS: Stack unwinding while on IRQ stack
+
+Within unwind stack, check if the stack pointer being unwound is within
+the CPU's irq_stack and if so use that page rather than the task's stack
+page.
+
+Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
+---
+
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -32,6 +32,7 @@
+ #include <asm/cpu.h>
+ #include <asm/dsp.h>
+ #include <asm/fpu.h>
++#include <asm/irq.h>
+ #include <asm/msa.h>
+ #include <asm/pgtable.h>
+ #include <asm/mipsregs.h>
+@@ -507,7 +508,19 @@ EXPORT_SYMBOL(unwind_stack_by_address);
+ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+ unsigned long pc, unsigned long *ra)
+ {
+- unsigned long stack_page = (unsigned long)task_stack_page(task);
++ unsigned long stack_page = 0;
++ int cpu;
++
++ for_each_possible_cpu(cpu) {
++ if (on_irq_stack(cpu, *sp)) {
++ stack_page = (unsigned long)irq_stack[cpu];
++ break;
++ }
++ }
++
++ if (!stack_page)
++ stack_page = (unsigned long)task_stack_page(task);
++
+ return unwind_stack_by_address(stack_page, sp, pc, ra);
+ }
+ #endif