On Fri, 29 May 2026 at 12:17, Marc-André Lureau
<[email protected]> wrote:
>
> qemu_irq_intercept_in() saves original IRQ handlers by allocating
> new QOM objects, which are never freed. On a PC machine, this leaks
> IRQ objects (one per IOAPIC pin) on every qtest run.
>
> Rather than tracking allocations to free later, avoid them: add an
> "observer" field to IRQState, called by qemu_set_irq() after the
> real handler. Interception sets the observer instead of rewriting
> handlers, so there's nothing to save and nothing to leak.
>
> Fix qemu_notirq() to route through qemu_set_irq() so inverted IRQs
> trigger observers too. Drop the LSan suppression.
>
> Signed-off-by: Marc-André Lureau <[email protected]>
> ---
>  include/hw/core/irq.h         |  1 +
>  hw/core/irq.c                 | 10 +++++-----
>  system/qtest.c                |  3 ---
>  scripts/lsan_suppressions.txt |  8 --------
>  4 files changed, 6 insertions(+), 16 deletions(-)
>
> diff --git a/include/hw/core/irq.h b/include/hw/core/irq.h
> index 291fdd67df4..93d5710a73e 100644
> --- a/include/hw/core/irq.h
> +++ b/include/hw/core/irq.h
> @@ -14,6 +14,7 @@ struct IRQState {
>      qemu_irq_handler handler;
>      void *opaque;
>      int n;
> +    qemu_irq_handler observer;
>  };
>
>  void qemu_set_irq(qemu_irq irq, int level);
> diff --git a/hw/core/irq.c b/hw/core/irq.c
> index 106805e2417..fa11e9bc0aa 100644
> --- a/hw/core/irq.c
> +++ b/hw/core/irq.c
> @@ -32,6 +32,9 @@ void qemu_set_irq(qemu_irq irq, int level)
>          return;
>
>      irq->handler(irq->opaque, irq->n, level);
> +    if (unlikely(irq->observer)) {
> +        irq->observer(irq->opaque, irq->n, level);
> +    }
>  }

Hmm. "observer" semantics are probably nicer than "steal
the irq from the thing that would otherwise be connected to it",
but on the other hand this means that this purely test-relevant
thing is now in the code path for the common "signal an IRQ"
that we use everywhere...

-- PMM

Reply via email to