mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
1708644f19
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>
43 lines
1.1 KiB
Diff
43 lines
1.1 KiB
Diff
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
|