• Thomas Gleixner's avatar
    x86/ioapic: Prevent inconsistent state when moving an interrupt · b446869e
    Thomas Gleixner authored
    [ Upstream commit df439342 ]
    
    There is an issue with threaded interrupts which are marked ONESHOT
    and using the fasteoi handler:
    
      if (IS_ONESHOT())
        mask_irq();
      ....
      cond_unmask_eoi_irq()
        chip->irq_eoi();
          if (setaffinity_pending) {
             mask_ioapic();
             ...
    	 move_affinity();
    	 unmask_ioapic();
          }
    
    So if setaffinity is pending the interrupt will be moved and then
    unconditionally unmasked at the ioapic level, which is wrong in two
    aspects:
    
     1) It should be kept masked up to the point where the threaded handler
        finished.
    
     2) The physical chip state and the software masked state are inconsistent
    
    Guard both the mask and the unmask with a check for the software masked
    state. If the line is marked masked then the ioapic line is also masked, so
    both mask_ioapic() and unmask_ioapic() can be skipped safely.
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Sebastian Siewior <bigeasy@linutronix.de>
    Fixes: 3aa551c9 ("genirq: add threaded interrupt handler support")
    Link: https://lkml.kernel.org/r/20191017101938.321393687@linutronix.deSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    b446869e
io_apic.c 77.6 KB