[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: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Родитель
025306f309
Коммит
ff3da2e093
|
@ -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
|
||||
|
|
|
@ -143,7 +143,6 @@ void local_irq_restore(unsigned long en)
|
|||
*/
|
||||
if (local_paca->lppaca_ptr->int_dword.any_int)
|
||||
iseries_handle_interrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче