If we ever get a value >= 31 from ffz(), we'd be invoking UB; in the > 31 case, probably assigning the same thread_mask to to multiple irqactions (at least on x86_64, where the shift count is implicitly truncated to 5 bits).
In practice, I think the bug is mostly harmless, since when we first get ffz == 31, the RHS is - ignoring UB - (int)(0x80000000), and sign-extension means that the 32nd irqaction just ends up eating the top 33 bits of thread_mask, so all subsequent __setup_irq calls would just end up hitting the -EBUSY branch. (AFAICT, no code seems to rely on ->thread_mask being a single bit; it's all whole-sale |= and &=). However, a sufficiently aggressive optimizer may use the UB of 1<<31 to decide that doesn't happen, and hence elide the sign-extension code, so that subsequent calls can indeed get ffz > 31. In any case, this is the right thing to do. Signed-off-by: Rasmus Villemoes <li...@rasmusvillemoes.dk> --- kernel/irq/manage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 4bff6a10ae8e..a1a448e1760d 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1305,7 +1305,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) * thread_mask assigned. See the loop above which or's * all existing action->thread_mask bits. */ - new->thread_mask = 1 << ffz(thread_mask); + new->thread_mask = 1UL << ffz(thread_mask); } else if (new->handler == irq_default_primary_handler && !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) { -- 2.11.0