mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
parent
306eb5a38d
commit
ffc661c99f
|
@ -1289,7 +1289,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)) {
|
||||
|
|
Loading…
Reference in New Issue