linux/arch/x86/kernel/apic
Thomas Gleixner c1684f5035 x86/irq: Clear move_in_progress before sending cleanup IPI
send_cleanup_vector() fiddles with the old_domain mask unprotected because it
relies on the protection by the move_in_progress flag. But this is fatal, as
the flag is reset after the IPI has been sent. So a cpu which receives the IPI
can still see the flag set and therefor ignores the cleanup request. If no
other cleanup request happens then the vector stays stale on that cpu and in
case of an irq removal the vector still persists. That can lead to use after
free when the next cleanup IPI happens.

Protect the code with vector_lock and clear move_in_progress before sending
the IPI.

This does not plug the race which Joe reported because:

CPU0                          CPU1                      CPU2
lock_vector()
data->move_in_progress=0
sendIPI()                       
unlock_vector()
                              set_affinity()
                              assign_irq_vector()
                              lock_vector()             handle_IPI
                              move_in_progress = 1      lock_vector()
                              unlock_vector()
                                                        move_in_progress == 1

The full fix comes with a later patch.

Reported-and-tested-by: Joe Lawrence <joe.lawrence@stratus.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Borislav Petkov <bp@alien8.de>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Jeremiah Mahler <jmmahler@gmail.com>
Cc: andy.shevchenko@gmail.com
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: stable@vger.kernel.org #4.3+
Link: http://lkml.kernel.org/r/20151231160106.892412198@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2016-01-15 13:44:01 +01:00
..
apic_flat_64.c x86/apic: Use default send single IPI wrapper 2015-11-05 13:07:53 +01:00
apic_noop.c x86/apic: Implement single IPI for apic_noop 2015-11-05 13:07:53 +01:00
apic_numachip.c Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-01-11 15:37:06 -08:00
apic.c x86/apic: Introduce apic_extnmi command line parameter 2015-12-19 11:07:01 +01:00
bigsmp_32.c x86/apic: Wire up single IPI for bigsmp_apic 2015-11-05 13:07:52 +01:00
htirq.c x86: Constify irqdomain ops 2015-05-05 11:14:48 +02:00
hw_nmi.c nmi: x86: convert to generic nmi handler 2015-07-17 12:23:30 +01:00
io_apic.c x86/irq: Call chip->irq_set_affinity in proper context 2016-01-15 13:43:58 +01:00
ipi.c x86/apic: Provide default send single IPI wrapper 2015-11-05 13:07:53 +01:00
Makefile x86, irq: Move HT IRQ related code from io_apic.c into htirq.c 2014-12-16 14:08:17 +01:00
msi.c x86/irq: Export functions to allow MSI domains in modules 2015-12-20 12:40:49 +01:00
probe_32.c x86/apic: Use default send single IPI wrapper 2015-11-05 13:07:53 +01:00
probe_64.c x86/platform: Introduce APIC post-initialization callback 2012-06-06 09:06:19 +02:00
vector.c x86/irq: Clear move_in_progress before sending cleanup IPI 2016-01-15 13:44:01 +01:00
x2apic_cluster.c x86/apic: Implement single target IPI function for x2apic_cluster 2015-11-05 13:07:52 +01:00
x2apic_phys.c x86/apic: Implement single IPI for x2apic_phys 2015-11-05 13:07:53 +01:00
x2apic_uv_x.c x86/apic: Wire up single IPI for x2apic_uv 2015-11-05 13:07:53 +01:00