Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b63a2bbc authored by John David Anglin's avatar John David Anglin Committed by Helge Deller
Browse files

parisc: make interrupt and interruption stack allocation reentrant



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: default avatarJohn David Anglin <dave.anglin@bell.net>
Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent d0c3be80
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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
+10 −9
Original line number Diff line number Diff line
@@ -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