• Nicholas Piggin's avatar
    powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending · e485f6c7
    Nicholas Piggin authored
    If a synchronous interrupt (e.g., hash fault) is taken inside an
    irqs-disabled region which has MSR[EE]=1, then an asynchronous interrupt
    that is PACA_IRQ_MUST_HARD_MASK (e.g., PMI) is taken inside the
    synchronous interrupt handler, then the synchronous interrupt will
    return with MSR[EE]=1 and the asynchronous interrupt fires again.
    
    If the asynchronous interrupt is a PMI and the original context does not
    have PMIs disabled (only Linux IRQs), the asynchronous interrupt will
    fire despite having the PMI marked soft pending. This can confuse the
    perf code and cause warnings.
    
    This patch changes the interrupt return so that irqs-disabled MSR[EE]=1
    contexts will be returned to with MSR[EE]=0 if a PACA_IRQ_MUST_HARD_MASK
    interrupt has become pending in the meantime.
    
    The longer explanation for what happens:
    1. local_irq_disable()
    2. Hash fault interrupt fires, do_hash_fault handler runs
    3. interrupt_enter_prepare() sets IRQS_ALL_DISABLED
    4. interrupt_enter_prepare() sets MSR[EE]=1
    5. PMU interrupt fires, masked handler runs
    6. Masked handler marks PMI pending
    7. Masked handler returns with PACA_IRQ_HARD_DIS set, MSR[EE]=0
    8. do_hash_fault interrupt return handler runs
    9. interrupt_exit_kernel_prepare() clears PACA_IRQ_HARD_DIS
    10. interrupt returns with MSR[EE]=1
    11. PMU interrupt fires, perf handler runs
    
    Fixes: 4423eb5a ("powerpc/64/interrupt: make normal synchronous interrupts enable MSR[EE] if possible")
    Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20220926054305.2671436-4-npiggin@gmail.com
    e485f6c7
interrupt_64.S 16.4 KB