Skip to content

Commit ffc661c

Browse files
VillemoesKAGA-KOKO
authored andcommitted
genirq: Fix type of shifting literal 1 in __setup_irq()
If ffz() ever returns a value >= 31 then the following shift is undefined behaviour because the literal 1 which gets shifted is treated as signed integer. In practice, the bug is probably harmless, since the first undefined shift count is 31 which results - ignoring UB - in (int)(0x80000000). This gets sign extended so bit 32-63 will be set as well and all subsequent __setup_irq() calls would just end up hitting the -EBUSY branch. 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, the right thing to do is to make the literal 1UL. [ tglx: For this to happen a single interrupt would have to be shared by 32 devices. Hardware like that does not exist and would have way more problems than that. ] Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lkml.kernel.org/r/20171030213548.16831-1-linux@rasmusvillemoes.dk
1 parent 306eb5a commit ffc661c

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

kernel/irq/manage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
12891289
* thread_mask assigned. See the loop above which or's
12901290
* all existing action->thread_mask bits.
12911291
*/
1292-
new->thread_mask = 1 << ffz(thread_mask);
1292+
new->thread_mask = 1UL << ffz(thread_mask);
12931293

12941294
} else if (new->handler == irq_default_primary_handler &&
12951295
!(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) {

0 commit comments

Comments
 (0)