A subtle bug sneaked into iSeries recently. On this platform, we must not normally clear MSR:EE unless it's 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 a few exception entry/exit code path. 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 period 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 spurrious 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: Benjamin Herrenschmidt <[EMAIL PROTECTED]> -- arch/powerpc/kernel/head_64.S | 13 +++++++------ arch/powerpc/kernel/irq.c | 1 - 2 files changed, 7 insertions(+), 7 deletions(-) --- linux-work.orig/arch/powerpc/kernel/head_64.S 2008-04-02 15:47:20.000000000 +1100 +++ linux-work/arch/powerpc/kernel/head_64.S 2008-04-02 15:48:50.000000000 +1100 @@ -1387,12 +1387,14 @@ __secondary_start: #ifdef CONFIG_PPC_ISERIES BEGIN_FW_FTR_SECTION ori r4,r4,MSR_EE + li r8,1 + stb r8,PACAHARDIRQEN(r13) END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif BEGIN_FW_FTR_SECTION - stb r7,PACASOFTIRQEN(r13) stb r7,PACAHARDIRQEN(r13) END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) + stb r7,PACASOFTIRQEN(r13) mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 @@ -1520,15 +1522,14 @@ _INIT_GLOBAL(start_here_common) #ifdef CONFIG_PPC_ISERIES BEGIN_FW_FTR_SECTION mfmsr r5 - ori r5,r5,MSR_EE /* Hard Enabled */ + ori r5,r5,MSR_EE /* Hard Enabled on iSeries*/ mtmsrd r5 + li r5,1 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif -BEGIN_FW_FTR_SECTION - stb r5,PACAHARDIRQEN(r13) -END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) + stb r5,PACAHARDIRQEN(r13) /* Hard Disabled on others */ - bl .start_kernel + bl .start_kernel /* Not reached */ BUG_OPCODE Index: linux-work/arch/powerpc/kernel/irq.c =================================================================== --- linux-work.orig/arch/powerpc/kernel/irq.c 2008-04-02 15:46:34.000000000 +1100 +++ linux-work/arch/powerpc/kernel/irq.c 2008-04-02 15:46:37.000000000 +1100 @@ -143,7 +143,6 @@ void local_irq_restore(unsigned long en) */ if (local_paca->lppaca_ptr->int_dword.any_int) iseries_handle_interrupts(); - return; } /* _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev