Commit ff3da2e0 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras

[POWERPC] Fix iSeries hard irq enabling regression

A subtle bug sneaked into iSeries recently.  On this platform, we must
not normally clear MSR:EE (the hardware external interrupt enable)
except for short periods of time.  Taking an interrupt while
soft-disabled doesn't cause us to clear it for example.

The iSeries kernel expects to mostly run with MSR:EE enabled at all
times except in a few exception entry/exit code paths.  Thus
local_irq_enable() doesn't check if it needs to hard-enable as it
expects this to be unnecessary on iSeries.

However, hard_irq_disable() _does_ cause MSR:EE to be cleared,
including on iSeries.  A call to it was recently added to the
context switch code, thus causing interrupts to become disabled
for a long periods of time, causing the iSeries watchdog to kick
in under some circumstances and other nasty things.

This patch fixes it by making local_irq_enable() properly re-enable
MSR:EE on iSeries.  It basically removes a return statement here
to make iSeries use the same code path as everybody else.  That does
mean that we might occasionally get spurious decrementer interrupts
but I don't think that matters.

Another option would have been to make hard_irq_disable() a nop
on iSeries but I didn't like it much, in case we have good reasons
to hard-disable.

Part of the patch is fixes to make sure the hard_enabled PACA field
is properly set on iSeries as it used not to be before, since it
was mostly unused.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 025306f3
...@@ -1387,12 +1387,14 @@ __secondary_start: ...@@ -1387,12 +1387,14 @@ __secondary_start:
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION BEGIN_FW_FTR_SECTION
ori r4,r4,MSR_EE ori r4,r4,MSR_EE
li r8,1
stb r8,PACAHARDIRQEN(r13)
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
BEGIN_FW_FTR_SECTION BEGIN_FW_FTR_SECTION
stb r7,PACASOFTIRQEN(r13)
stb r7,PACAHARDIRQEN(r13) stb r7,PACAHARDIRQEN(r13)
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
stb r7,PACASOFTIRQEN(r13)
mtspr SPRN_SRR0,r3 mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4 mtspr SPRN_SRR1,r4
...@@ -1520,15 +1522,14 @@ _INIT_GLOBAL(start_here_common) ...@@ -1520,15 +1522,14 @@ _INIT_GLOBAL(start_here_common)
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION BEGIN_FW_FTR_SECTION
mfmsr r5 mfmsr r5
ori r5,r5,MSR_EE /* Hard Enabled */ ori r5,r5,MSR_EE /* Hard Enabled on iSeries*/
mtmsrd r5 mtmsrd r5
li r5,1
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif #endif
BEGIN_FW_FTR_SECTION stb r5,PACAHARDIRQEN(r13) /* Hard Disabled on others */
stb r5,PACAHARDIRQEN(r13)
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
bl .start_kernel bl .start_kernel
/* Not reached */ /* Not reached */
BUG_OPCODE BUG_OPCODE
......
...@@ -143,7 +143,6 @@ void local_irq_restore(unsigned long en) ...@@ -143,7 +143,6 @@ void local_irq_restore(unsigned long en)
*/ */
if (local_paca->lppaca_ptr->int_dword.any_int) if (local_paca->lppaca_ptr->int_dword.any_int)
iseries_handle_interrupts(); iseries_handle_interrupts();
return;
} }
/* /*
......
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