• Michael Ellerman's avatar
    powerpc/powernv: Make opal_event_shutdown() callable from IRQ context · c6baa077
    Michael Ellerman authored
    In opal_event_shutdown() we free all the IRQs hanging off the
    opal_event_irqchip. However it's not safe to do so if we're called
    from IRQ context, because free_irq() wants to synchronise versus IRQ
    context. This can lead to warnings and a stuck system.
    
    For example from sysrq-b:
    
      Trying to free IRQ 17 from IRQ context!
      ------------[ cut here ]------------
      WARNING: CPU: 0 PID: 0 at kernel/irq/manage.c:1461 __free_irq+0x398/0x8d0
      ...
      NIP __free_irq+0x398/0x8d0
      LR __free_irq+0x394/0x8d0
      Call Trace:
        __free_irq+0x394/0x8d0 (unreliable)
        free_irq+0xa4/0x140
        opal_event_shutdown+0x128/0x180
        opal_shutdown+0x1c/0xb0
        pnv_shutdown+0x20/0x40
        machine_restart+0x38/0x90
        emergency_restart+0x28/0x40
        sysrq_handle_reboot+0x24/0x40
        __handle_sysrq+0x198/0x590
        hvc_poll+0x48c/0x8c0
        hvc_handle_interrupt+0x1c/0x50
        __handle_irq_event_percpu+0xe8/0x6e0
        handle_irq_event_percpu+0x34/0xe0
        handle_irq_event+0xc4/0x210
        handle_level_irq+0x250/0x770
        generic_handle_irq+0x5c/0xa0
        opal_handle_events+0x11c/0x240
        opal_interrupt+0x38/0x50
        __handle_irq_event_percpu+0xe8/0x6e0
        handle_irq_event_percpu+0x34/0xe0
        handle_irq_event+0xc4/0x210
        handle_fasteoi_irq+0x174/0xa10
        generic_handle_irq+0x5c/0xa0
        __do_irq+0xbc/0x4e0
        call_do_irq+0x14/0x24
        do_IRQ+0x18c/0x540
        hardware_interrupt_common+0x158/0x180
    
    We can avoid that by using disable_irq_nosync() rather than
    free_irq(). Although it doesn't fully free the IRQ, it should be
    sufficient when we're shutting down, particularly in an emergency.
    
    Add an in_interrupt() check and use free_irq() when we're shutting
    down normally. It's probably OK to use disable_irq_nosync() in that
    case too, but for now it's safer to leave that behaviour as-is.
    
    Fixes: 9f0fd049 ("powerpc/powernv: Add a virtual irqchip for opal events")
    Reported-by: default avatarAnton Blanchard <anton@samba.org>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    c6baa077
opal-irqchip.c 7.8 KB