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

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
...@@ -438,7 +438,6 @@ ...@@ -438,7 +438,6 @@
SAVE_SP (%sr4, PT_SR4 (\regs)) SAVE_SP (%sr4, PT_SR4 (\regs))
SAVE_SP (%sr5, PT_SR5 (\regs)) SAVE_SP (%sr5, PT_SR5 (\regs))
SAVE_SP (%sr6, PT_SR6 (\regs)) SAVE_SP (%sr6, PT_SR6 (\regs))
SAVE_SP (%sr7, PT_SR7 (\regs))
SAVE_CR (%cr17, PT_IASQ0(\regs)) SAVE_CR (%cr17, PT_IASQ0(\regs))
mtctl %r0, %cr17 mtctl %r0, %cr17
......
...@@ -65,15 +65,11 @@ ...@@ -65,15 +65,11 @@
rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */
mtsp %r0, %sr4 mtsp %r0, %sr4
mtsp %r0, %sr5 mtsp %r0, %sr5
mfsp %sr7, %r1 mtsp %r0, %sr6
or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
mtsp %r1, %sr3
tovirt_r1 %r29 tovirt_r1 %r29
load32 KERNEL_PSW, %r1 load32 KERNEL_PSW, %r1
rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ 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 tail */
mtctl %r0, %cr17 /* Clear IIASQ head */ mtctl %r0, %cr17 /* Clear IIASQ head */
mtctl %r1, %ipsw mtctl %r1, %ipsw
...@@ -119,17 +115,20 @@ ...@@ -119,17 +115,20 @@
/* we save the registers in the task struct */ /* we save the registers in the task struct */
copy %r30, %r17
mfctl %cr30, %r1 mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30
mtsp %r0,%sr7
mtsp %r16,%sr3
tophys %r1,%r9 tophys %r1,%r9
LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */ LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */
tophys %r1,%r9 tophys %r1,%r9
ldo TASK_REGS(%r9),%r9 ldo TASK_REGS(%r9),%r9
STREG %r30, PT_GR30(%r9) STREG %r17,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9) STREG %r29,PT_GR29(%r9)
STREG %r26,PT_GR26(%r9) STREG %r26,PT_GR26(%r9)
STREG %r16,PT_SR7(%r9)
copy %r9,%r29 copy %r9,%r29
mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30
.endm .endm
.macro get_stack_use_r30 .macro get_stack_use_r30
...@@ -137,10 +136,12 @@ ...@@ -137,10 +136,12 @@
/* we put a struct pt_regs on the stack and save the registers there */ /* we put a struct pt_regs on the stack and save the registers there */
tophys %r30,%r9 tophys %r30,%r9
STREG %r30,PT_GR30(%r9) copy %r30,%r1
ldo PT_SZ_ALGN(%r30),%r30 ldo PT_SZ_ALGN(%r30),%r30
STREG %r1,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9) STREG %r29,PT_GR29(%r9)
STREG %r26,PT_GR26(%r9) STREG %r26,PT_GR26(%r9)
STREG %r16,PT_SR7(%r9)
copy %r9,%r29 copy %r9,%r29
.endm .endm
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment