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
