• Mika Westerberg's avatar
    x86/irq: Prevent force migration of irqs which are not in the vector domain · db91aa79
    Mika Westerberg authored
    When a CPU is about to be offlined we call fixup_irqs() that resets IRQ
    affinities related to the CPU in question. The same thing is also done when
    the system is suspended to S-states like S3 (mem).
    
    For each IRQ we try to complete any on-going move regardless whether the
    IRQ is actually part of x86_vector_domain. For each IRQ descriptor we fetch
    its chip_data, assume it is of type struct apic_chip_data and manipulate it
    by clearing old_domain mask etc. For irq_chips that are not part of the
    x86_vector_domain, like those created by various GPIO drivers, will find
    their chip_data being changed unexpectly.
    
    Below is an example where GPIO chip owned by pinctrl-sunrisepoint.c gets
    corrupted after resume:
    
      # cat /sys/kernel/debug/gpio
      gpiochip0: GPIOs 360-511, parent: platform/INT344B:00, INT344B:00:
       gpio-511 (                    |sysfs               ) in  hi
    
      # rtcwake -s10 -mmem
      <10 seconds passes>
    
      # cat /sys/kernel/debug/gpio
      gpiochip0: GPIOs 360-511, parent: platform/INT344B:00, INT344B:00:
       gpio-511 (                    |sysfs               ) in  ?
    
    Note '?' in the output. It means the struct gpio_chip ->get function is
    NULL whereas before suspend it was there.
    
    Fix this by first checking that the IRQ belongs to x86_vector_domain before
    we try to use the chip_data as struct apic_chip_data.
    Reported-and-tested-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
    Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
    Cc: stable@vger.kernel.org # 4.4+
    Link: http://lkml.kernel.org/r/20161003101708.34795-1-mika.westerberg@linux.intel.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    db91aa79
vector.c 25.2 KB