On Wed, Apr 29, 2026 at 12:01:00AM +0800, Jim Shu wrote:
> According to the AIA spec ch4.7 ("Precise effects on interrupt-pending
> bits"), pending bit of APLIC should be set/cleared whenever the
> rectified input value is high/low in the both level-trigger mode
> and direct delivery mode.
>
> Currently, QEMU APLIC only clears the pending bit when interrupt is
> claimed in APLIC, but not clears it when the rectified input value is
> low. (e.g. IRQ source signal is low in the LEVEL_HIGH/Level1 mode).
> The software may receive an additional IRQ if the peripheral
> triggers one after the software clears the APLIC IRQ but before it
> clears the peripheral's IRQ.
>
> Thus, we also clear the pending bit via the rectified input value in the
> level-trigger mode.
>
> This change doesn't affect MSI delivery mode. Calling
> riscv_aplic_msi_irq_update() when IRQ pending is low will do nothing.
>
> Signed-off-by: Jim Shu <[email protected]>
Reviewed-by: Chao Liu <[email protected]>
Thanks,
Chao
> ---
> hw/intc/riscv_aplic.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
> index 8f700431114..791e0b01b96 100644
> --- a/hw/intc/riscv_aplic.c
> +++ b/hw/intc/riscv_aplic.c
> @@ -591,14 +591,14 @@ static void riscv_aplic_request(void *opaque, int irq,
> int level)
> }
> break;
> case APLIC_SOURCECFG_SM_LEVEL_HIGH:
> - if ((level > 0) && !(state & APLIC_ISTATE_PENDING)) {
> - riscv_aplic_set_pending_raw(aplic, irq, true);
> + if ((level > 0) != !!(state & APLIC_ISTATE_PENDING)) {
> + riscv_aplic_set_pending_raw(aplic, irq, level > 0);
> update = true;
> }
> break;
> case APLIC_SOURCECFG_SM_LEVEL_LOW:
> - if ((level <= 0) && !(state & APLIC_ISTATE_PENDING)) {
> - riscv_aplic_set_pending_raw(aplic, irq, true);
> + if ((level <= 0) != !!(state & APLIC_ISTATE_PENDING)) {
> + riscv_aplic_set_pending_raw(aplic, irq, level <= 0);
> update = true;
> }
> break;
> --
> 2.43.0
>