powerpc/64s: Fix irq state management in runlatch functions
When irqs are soft-disabled, MSR[EE] is volatile and can change from 1 to 0 asynchronously (if a PACA_IRQ_MUST_HARD_MASK interrupt hits). So it can not be used to check hard IRQ enabled status, except to confirm it is disabled. ppc64_runlatch_on/off functions use MSR this way to decide whether to re-enable MSR[EE] after disabling it, which leads to MSR[EE] being enabled when it shouldn't be (when a PACA_IRQ_MUST_HARD_MASK had disabled it between reading the MSR and clearing EE). This has been tolerated in the kernel previously, and it doesn't seem to cause a problem, but it is unexpected and may trip warnings or cause other problems as we tighten up this state management. Fix this by only re-enabling if PACA_IRQ_HARD_DIS is clear. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20220926054305.2671436-5-npiggin@gmail.com
This commit is contained in:
parent
e485f6c751
commit
9524f2278f
@ -19,10 +19,9 @@ extern void __ppc64_runlatch_off(void);
|
||||
do { \
|
||||
if (cpu_has_feature(CPU_FTR_CTRL) && \
|
||||
test_thread_local_flags(_TLF_RUNLATCH)) { \
|
||||
unsigned long msr = mfmsr(); \
|
||||
__hard_irq_disable(); \
|
||||
__ppc64_runlatch_off(); \
|
||||
if (msr & MSR_EE) \
|
||||
if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) \
|
||||
__hard_irq_enable(); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -31,10 +30,9 @@ extern void __ppc64_runlatch_off(void);
|
||||
do { \
|
||||
if (cpu_has_feature(CPU_FTR_CTRL) && \
|
||||
!test_thread_local_flags(_TLF_RUNLATCH)) { \
|
||||
unsigned long msr = mfmsr(); \
|
||||
__hard_irq_disable(); \
|
||||
__ppc64_runlatch_on(); \
|
||||
if (msr & MSR_EE) \
|
||||
if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) \
|
||||
__hard_irq_enable(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
Loading…
Reference in New Issue
Block a user