Skip to contentSkip to conversation

Patch "MIPS: IRQ Stack: Unwind IRQ stack onto task stack" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Oct 5, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

MIPS: IRQ Stack: Unwind IRQ stack onto task stack

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mips-irq-stack-unwind-irq-stack-onto-task-stack.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Thu Oct 5 10:49:14 CEST 2017

From: Matt Redfearn <[email protected]>
Date: Tue, 21 Mar 2017 14:52:25 +0000
Subject: MIPS: IRQ Stack: Unwind IRQ stack onto task stack

From: Matt Redfearn <[email protected]>

[ Upstream commit db8466c581cca1a08b505f1319c3ecd246f16fa8 ]

When the separate IRQ stack was introduced, stack unwinding only proceeded as far as the top of the IRQ stack, leading to kernel backtraces being less useful, lacking the trace of what was interrupted.

Fix this by providing a means for the kernel to unwind the IRQ stack onto the interrupted task stack. The processor state is saved to the kernel task stack on interrupt. The IRQ_STACK_START macro reserves an unsigned long at the top of the IRQ stack where the interrupted task stack pointer can be saved. After the active stack is switched to the IRQ stack, save the interrupted tasks stack pointer to the reserved location.

Fix the stack unwinding code to look for the frame being the top of the IRQ stack and if so get the next frame from the saved location. The existing test does not work with the separate stack since the ra is no longer pointed at ret_from_{irq,exception}.

The test to stop unwinding the stack 32 bytes from the top of a stack must be modified to allow unwinding to continue up to the location of the saved task stack pointer when on the IRQ stack. The low / high marks of the stack are set depending on whether the sp is on an irq stack or not.

Cc Paolo Bonzini <[email protected]>
Cc Marcin Nowakowski <[email protected]>
Cc Masanari Iida <[email protected]>
Cc Chris Metcalf <[email protected]>
Cc James Hogan <[email protected]>
Cc Paul Burton <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jason A. Donenfeld <[email protected]>
Cc Andrew Morton <[email protected]>

Patchwork: https://patchwork.linux-mips.org/patch/15788/

---
 arch/mips/include/asm/irq.h    |   15 ++++++++++
 arch/mips/kernel/asm-offsets.c |    1 
 arch/mips/kernel/genex.S       |    8 ++++-
 arch/mips/kernel/process.c     |   56 +++++++++++++++++++++++++++--------------
 4 files changed, 60 insertions(+), 20 deletions(-)
arch/mips/include/asm/irq.h +15 -0
@@ -18,9 +18,24 @@
 #include <irq.h>
 
 #define IRQ_STACK_SIZE			THREAD_SIZE
+#define IRQ_STACK_START			(IRQ_STACK_SIZE - sizeof(unsigned long))
 
 extern void *irq_stack[NR_CPUS];
 
+/*
+ * The highest address on the IRQ stack contains a dummy frame put down in
+ * genex.S (handle_int & except_vec_vi_handler) which is structured as follows:
+ *
+ *   top ------------
+ *       | task sp  | <- irq_stack[cpu] + IRQ_STACK_START
+ *       ------------
+ *       |          | <- First frame of IRQ context
+ *       ------------
+ *
+ * task sp holds a copy of the task stack pointer where the struct pt_regs
+ * from exception entry can be found.
+ */
+
 static inline bool on_irq_stack(int cpu, unsigned long sp)
 {
 	unsigned long low = (unsigned long)irq_stack[cpu];
arch/mips/kernel/asm-offsets.c +1 -0
@@ -102,6 +102,7 @@ void output_thread_info_defines(void)
 	DEFINE(_THREAD_SIZE, THREAD_SIZE);
 	DEFINE(_THREAD_MASK, THREAD_MASK);
 	DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
+	DEFINE(_IRQ_STACK_START, IRQ_STACK_START);
 	BLANK();
 }
 
arch/mips/kernel/genex.S +6 -2
@@ -216,9 +216,11 @@ NESTED(handle_int, PT_SIZE, sp)
 	beq	t0, t1, 2f
 
 	/* Switch to IRQ stack */
-	li	t1, _IRQ_STACK_SIZE
+	li	t1, _IRQ_STACK_START
 	PTR_ADD sp, t0, t1
 
+	/* Save task's sp on IRQ stack so that unwinding can follow it */
+	LONG_S	s1, 0(sp)
 2:
 	jal	plat_irq_dispatch
 
@@ -326,9 +328,11 @@ NESTED(except_vec_vi_handler, 0, sp)
 	beq	t0, t1, 2f
 
 	/* Switch to IRQ stack */
-	li	t1, _IRQ_STACK_SIZE
+	li	t1, _IRQ_STACK_START
 	PTR_ADD sp, t0, t1
 
+	/* Save task's sp on IRQ stack so that unwinding can follow it */
+	LONG_S	s1, 0(sp)
 2:
 	jalr	v0
 
arch/mips/kernel/process.c +38 -18

77 lines not on this page · raw message

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/mips-irq-stack-unwind-irq-stack-onto-task-stack.patch