Commit f6175f5b authored by Tomoki Sekiyama's avatar Tomoki Sekiyama Committed by Ingo Molnar

x86/ioapic: Fix NULL pointer dereference on CPU hotplug after disabling irqs

In current Linux, percpu variable `vector_irq' is not cleared on
offlined cpus while disabling devices' irqs. If the cpu that has
the disabled irqs in vector_irq is hotplugged,
__setup_vector_irq() hits invalid irq vector and may crash.

This bug can be reproduced as following;

  # echo 0 > /sys/devices/system/cpu/cpu7/online
  # modprobe -r some_driver_using_interrupts      # vector_irq@cpu7 uncleared
  # echo 1 > /sys/devices/system/cpu/cpu7/online  # kernel may crash

This patch fixes this bug by clearing vector_irq in
__clear_irq_vector() even if the cpu is offlined.
Signed-off-by: default avatarTomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: yrl.pp-manager.tt@hitachi.com
Cc: ltc-kernel@ml.yrl.intra.hitachi.co.jp
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Alexander Gordeev <agordeev@redhat.com>
Link: http://lkml.kernel.org/r/4FC340BE.7080101@hitachi.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 55c844a4
...@@ -1195,7 +1195,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) ...@@ -1195,7 +1195,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
BUG_ON(!cfg->vector); BUG_ON(!cfg->vector);
vector = cfg->vector; vector = cfg->vector;
for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) for_each_cpu(cpu, cfg->domain)
per_cpu(vector_irq, cpu)[vector] = -1; per_cpu(vector_irq, cpu)[vector] = -1;
cfg->vector = 0; cfg->vector = 0;
...@@ -1203,7 +1203,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) ...@@ -1203,7 +1203,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
if (likely(!cfg->move_in_progress)) if (likely(!cfg->move_in_progress))
return; return;
for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { for_each_cpu(cpu, cfg->old_domain) {
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
vector++) { vector++) {
if (per_cpu(vector_irq, cpu)[vector] != irq) if (per_cpu(vector_irq, cpu)[vector] != irq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment