[QUESTION] Understanding in-kernel irqchip (APLIC + IMSIC) behavior with multiple devices and interrupt handling

Samuele Paone s.paone at virtualopensystems.com
Tue Jan 7 08:36:21 PST 2025


Hello everyone,
I have a few questions regarding the in-kernel irqchip
implementation, specifically in the context of APLIC and IMSIC for
RISC-V:

1. **Behavior with Multiple Devices**: Does the current implementation
support the creation of a VM with both PCI devices (that use MSI) and
MMIO devices (that use wired interrupts)?
If such a scenario is not supported, how can I configure an MMIO
device to use MSI interrupts? Would it all boil down to some device
tree configuration
(i.e., the MMIO device tree node "interrupts" property referencing the
IMSIC rather than the APLIC directly)?

2. I find unclear how the variable `level` is used inside function
`kvm_riscv_aia_aplic_inject` in `arch/riscv/kvm/aia_aplic.c`

```
switch (irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK) {
case APLIC_SOURCECFG_SM_EDGE_RISE:
if (level && !(irqd->state & APLIC_IRQ_STATE_INPUT) &&
    !(irqd->state & APLIC_IRQ_STATE_PENDING))
irqd->state |= APLIC_IRQ_STATE_PENDING;
                level = 0;
break;
case APLIC_SOURCECFG_SM_EDGE_FALL:
if (!level && (irqd->state & APLIC_IRQ_STATE_INPUT) &&
    !(irqd->state & APLIC_IRQ_STATE_PENDING))
irqd->state |= APLIC_IRQ_STATE_PENDING;
break;
case APLIC_SOURCECFG_SM_LEVEL_HIGH:
if (level && !(irqd->state & APLIC_IRQ_STATE_PENDING))
irqd->state |= APLIC_IRQ_STATE_PENDING;
break;
case APLIC_SOURCECFG_SM_LEVEL_LOW:
if (!level && !(irqd->state & APLIC_IRQ_STATE_PENDING))
irqd->state |= APLIC_IRQ_STATE_PENDING;
break;
}

if (level)
irqd->state |= APLIC_IRQ_STATE_INPUT;
else
irqd->state &= ~APLIC_IRQ_STATE_INPUT;
```

Considering `edge_rise` interrupts, as far as I can see, the
APLIC_IRQ_STATE_INPUT is set only in the code above
 but prevents edge_rise interrupts from being set pending.
Moreover, in a system emulator implementation that uses in-kernel IRQCHIP and
IrqFd, this variable is hard-coded (`virt/kvm/eventfd.c` in function
`irqfd_wakeup` when it calls `kvm_arch_set_irq_inatomic`)
in the kernel as 1.

3. **MSI-only Support in the irqchip**: The in-kernel irqchip
documentation states that it only supports MSI. However, the RISC-V
hardware documentation mentions that APLIC can take wired interrupts
as input and convert them to MSI to forward to IMSIC. Could someone
clarify what is meant by "MSI-only" support in this context? Are there
specific constraints or implementation details that limit the irqchip
to only support MSI for virtualization?

4. **Device tree node differences**: How would a device tree node backed
by MSI interrupt differ from a device backed by a wired interrupt?

Samuele



More information about the kvm-riscv mailing list