Re: [PATCH] irqchip/riscv-imsic: Fix IPI target CPU mapping for sparse hartid topology

From: Anup Patel

Date: Tue Jun 09 2026 - 04:07:48 EST


On Mon, Jun 8, 2026 at 5:29 PM Wenhui Fan <fanwenhui@xxxxxxxxxxx> wrote:
>
> When the system has sparse hartid topology (e.g., only hart0 and hart8
> are online), the current IMSIC driver incorrectly calculates the MSI
> MMIO offset for each CPU. This causes IPIs targeting hart8 to be
> misdirected to hart1.

The current DT-bindings handles sparse hartid perfectly fine. The
interrupts-extended DT property of IMSIC describes the arrangement
of IMSIC files and their mapping to HARTs.

It seems there is some issue with your interrupts-extended DT
property in the IMSIC DT-node. Please share your IMSIC DT node
over here and explain the problem you are facing based on that.

>
> The root cause is that in imsic_setup_state(), the MMIO offset is
> calculated using the parent interrupt index 'i' rather than the actual
> hartid:
> reloff = i * BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ;
>
> This assumes a contiguous hartid space, which is not guaranteed in all
> systems. When only hart0 and hart8 are online, the driver receives
> nr_parent_irqs=2, with i=0 for hart0 and i=1 for hart8.
>
> Using i=1 for hart8 results in using the wrong offset which is intended
> for hart1, and causes the MSI configured for hart8 to incorrectly access
> hart1's MSI page.
>
> Fix this by using the actual hartid for offset calculation:
> reloff = hartid * BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ;
>
> Fixes: 21a8f8a0eb35 ("irqchip: Add RISC-V incoming MSI controller early driver")
> Signed-off-by: Wenhui Fan <fanwenhui@xxxxxxxxxxx>
> ---
> drivers/irqchip/irq-riscv-imsic-state.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> index e3ed874d8..5f737ec36 100644
> --- a/drivers/irqchip/irq-riscv-imsic-state.c
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -894,7 +894,7 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque)
>
> /* Find MMIO location of MSI page */
> index = nr_mmios;
> - reloff = i * BIT(global->guest_index_bits) *
> + reloff = hartid * BIT(global->guest_index_bits) *
> IMSIC_MMIO_PAGE_SZ;

Using hartid to calculate the IMSIC MMIO offset does not algin
with the "interrupts-extended" DT property defined by the IMSIC
DT-bindings.
(Refer, Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml)

Clearly, there is something wrong with your DTS so NACK from
my side.

Regards,
Anup