Instead of looping over each irq and checking against the irq array bounds, adjust the bounds before looping.
The old code will not free any irq if the irq + count is above irq_virq_count because the test in the loop is testing irq + count instead of irq + i. This code checks the limits to avoid unsigned integer overflows. Signed-off-by: Milton Miller <milt...@bga.com> --- I am not aware of any call sites where the difference matters; I prepared the refactor while continuing work on the irq host extraction and noticed the logic error during the code movement. Index: work.git/arch/powerpc/kernel/irq.c =================================================================== --- work.git.orig/arch/powerpc/kernel/irq.c 2011-05-24 21:15:55.350096024 -0500 +++ work.git/arch/powerpc/kernel/irq.c 2011-05-24 21:17:16.000097884 -0500 @@ -1007,14 +1007,23 @@ void irq_free_virt(unsigned int virq, un WARN_ON (virq < NUM_ISA_INTERRUPTS); WARN_ON (count == 0 || (virq + count) > irq_virq_count); + if (virq < NUM_ISA_INTERRUPTS) { + if (virq + count < NUM_ISA_INTERRUPTS) + return; + count =- NUM_ISA_INTERRUPTS - virq; + virq = NUM_ISA_INTERRUPTS; + } + + if (count > irq_virq_count || virq > irq_virq_count - count) { + if (virq > irq_virq_count) + return; + count = irq_virq_count - virq; + } + raw_spin_lock_irqsave(&irq_big_lock, flags); for (i = virq; i < (virq + count); i++) { struct irq_host *host; - if (i < NUM_ISA_INTERRUPTS || - (virq + count) > irq_virq_count) - continue; - host = irq_map[i].host; irq_map[i].hwirq = host->inval_irq; smp_wmb(); _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev