All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] parisc: make interrupt and interruption stack allocation reentrant
@ 2013-05-20 16:42 John David Anglin
  0 siblings, 0 replies; only message in thread
From: John David Anglin @ 2013-05-20 16:42 UTC (permalink / raw)
  To: linux-parisc List; +Cc: Helge Deller, James E.J. Bottomley

[-- Attachment #1: Type: text/plain, Size: 1191 bytes --]

The get_stack_use_cr30 and get_stack_use_r30 macros allocate a stack  
frame for external
interrupts and interruptions requiring a stack frame.  They are  
currently not reentrant in that
they save register context before the stack is set or adjusted.

I have observed a number of system crashes where there was clear  
evidence of stack corruption
during interrupt processing, and as a result register corruption.   
Some interruptions can still occur
during interruption processing, however external interrupts are  
disabled and data TLB misses
don't occur for absolute accesses.  So, it's not entirely clear what  
triggers this issue.  Also, if an
interruption occurs when Q=0, it is generally not possible to recover  
as the shadowed registers
are not copied.

The attached patch reworks the get_stack_use_cr30 and  
get_stack_use_r30 macros to allocate
stack before doing register saves.  The new code is a couple of  
instructions shorter than the old
implementation.  Thus, it's an improvement even if it doesn't fully  
resolve the stack corruption
issue.  Based on limited testing, it improves SMP system stability.

Signed-off-by: John David Anglin  <dave.anglin@bell.net>
---


[-- Attachment #2: stack.d.3.txt --]
[-- Type: text/plain, Size: 1925 bytes --]

diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h
index 89fb400..0da8482 100644
--- a/arch/parisc/include/asm/assembly.h
+++ b/arch/parisc/include/asm/assembly.h
@@ -438,7 +438,6 @@
 	SAVE_SP  (%sr4, PT_SR4 (\regs))
 	SAVE_SP  (%sr5, PT_SR5 (\regs))
 	SAVE_SP  (%sr6, PT_SR6 (\regs))
-	SAVE_SP  (%sr7, PT_SR7 (\regs))
 
 	SAVE_CR  (%cr17, PT_IASQ0(\regs))
 	mtctl	 %r0,	%cr17
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index ae27cb6..e8f07dd 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -65,15 +65,11 @@
 	rsm	PSW_SM_I, %r0	/* barrier for "Relied upon Translation */
 	mtsp	%r0, %sr4
 	mtsp	%r0, %sr5
-	mfsp	%sr7, %r1
-	or,=    %r0,%r1,%r0	/* Only save sr7 in sr3 if sr7 != 0 */
-	mtsp	%r1, %sr3
+	mtsp	%r0, %sr6
 	tovirt_r1 %r29
 	load32	KERNEL_PSW, %r1
 
 	rsm     PSW_SM_QUIET,%r0	/* second "heavy weight" ctl op */
-	mtsp	%r0, %sr6
-	mtsp	%r0, %sr7
 	mtctl	%r0, %cr17	/* Clear IIASQ tail */
 	mtctl	%r0, %cr17	/* Clear IIASQ head */
 	mtctl	%r1, %ipsw
@@ -119,17 +115,20 @@
 
 	/* we save the registers in the task struct */
 
+	copy	%r30, %r17
 	mfctl   %cr30, %r1
+	ldo	THREAD_SZ_ALGN(%r1), %r30
+	mtsp	%r0,%sr7
+	mtsp	%r16,%sr3
 	tophys  %r1,%r9
 	LDREG	TI_TASK(%r9), %r1	/* thread_info -> task_struct */
 	tophys  %r1,%r9
 	ldo     TASK_REGS(%r9),%r9
-	STREG   %r30, PT_GR30(%r9)
+	STREG   %r17,PT_GR30(%r9)
 	STREG   %r29,PT_GR29(%r9)
 	STREG   %r26,PT_GR26(%r9)
+	STREG	%r16,PT_SR7(%r9)
 	copy    %r9,%r29
-	mfctl   %cr30, %r1
-	ldo	THREAD_SZ_ALGN(%r1), %r30
 	.endm
 
 	.macro  get_stack_use_r30
@@ -137,10 +136,12 @@
 	/* we put a struct pt_regs on the stack and save the registers there */
 
 	tophys  %r30,%r9
-	STREG   %r30,PT_GR30(%r9)
+	copy	%r30,%r1
 	ldo	PT_SZ_ALGN(%r30),%r30
+	STREG   %r1,PT_GR30(%r9)
 	STREG   %r29,PT_GR29(%r9)
 	STREG   %r26,PT_GR26(%r9)
+	STREG	%r16,PT_SR7(%r9)
 	copy    %r9,%r29
 	.endm
 

[-- Attachment #3: Type: text/plain, Size: 45 bytes --]



--
John David Anglin	dave.anglin@bell.net


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2013-05-20 16:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-20 16:42 [PATCH] parisc: make interrupt and interruption stack allocation reentrant John David Anglin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.