[PATCH] irqchip/bcm2712-mip: Fix multi-MSI allocation for non-power-of-two counts

From: Nicolai Buchwitz

Date: Thu Nov 12 2026 - 08:03:49 EST


ilog2() rounds down, so a request for three vectors reserves only two
slots and the third can overlap another allocation. The alignment is
also applied to the bitmap index and ignores the msi_offset that is
added to the message data.

Reserve exactly the requested number of slots and align the start of
the message data block to the vector count rounded up to a power of
two.

Fixes: 32c6c054661a ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Nicolai Buchwitz <nb@xxxxxxxxxxx>
---
Found this while working on a series that uses all 20 MIP1 outputs on
BCM2712. Even though I can reproduce this on a custom Raspberry Pi CM5
based board, I'm not aware of any bug reports regarding this (yet).

The fix has been tested on Raspberry Pi CM5.
---
drivers/irqchip/irq-bcm2712-mip.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c
index 06a6ab6270ad3..a0f45df0e4c87 100644
--- a/drivers/irqchip/irq-bcm2712-mip.c
+++ b/drivers/irqchip/irq-bcm2712-mip.c
@@ -71,15 +71,24 @@ static struct irq_chip mip_middle_irq_chip = {

static int mip_alloc_hwirq(struct mip_priv *mip, unsigned int nr_irqs)
{
+ unsigned long hwirq;
+
guard(spinlock)(&mip->lock);
- return bitmap_find_free_region(mip->bitmap, mip->num_msis, ilog2(nr_irqs));
+ hwirq = bitmap_find_next_zero_area_off(mip->bitmap, mip->num_msis, 0,
+ nr_irqs, roundup_pow_of_two(nr_irqs) - 1,
+ mip->msi_offset);
+ if (hwirq >= mip->num_msis)
+ return -ENOSPC;
+
+ bitmap_set(mip->bitmap, hwirq, nr_irqs);
+ return hwirq;
}

static void mip_free_hwirq(struct mip_priv *mip, unsigned int hwirq,
unsigned int nr_irqs)
{
guard(spinlock)(&mip->lock);
- bitmap_release_region(mip->bitmap, hwirq, ilog2(nr_irqs));
+ bitmap_clear(mip->bitmap, hwirq, nr_irqs);
}

static int mip_middle_domain_alloc(struct irq_domain *domain, unsigned int virq,

---
base-commit: 9d66f26fefacebfeed15de31c1123451a17ff119
change-id: 20261107-bcm2712-mip-msi-align-6632f7c96019

Best regards,
--
Nicolai Buchwitz <nb@xxxxxxxxxxx>