summaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2026-06-23 11:44:18 +0400
committerMarc-André Lureau <marcandre.lureau@redhat.com>2026-06-24 15:41:14 +0400
commit0457762e9e08be216567c33ca89ce7523a1213ba (patch)
tree4b570080187a5507ca90011f1a5027f6fac5a82e /system
parent5cac1d9c9394e633402ebe82e7ab1871b3ae2379 (diff)
downloadqemu-0457762e9e08be216567c33ca89ce7523a1213ba.tar.gz
qemu-0457762e9e08be216567c33ca89ce7523a1213ba.zip
irq: add per-IRQ observer to fix qemu_irq_intercept_in leak
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. Reviewed-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260623-b4-ui-v4-3-4656aec3398d@redhat.com>
Diffstat (limited to 'system')
-rw-r--r--system/qtest.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/system/qtest.c b/system/qtest.c
index fd37bcbfaa..cf30123917 100644
--- a/system/qtest.c
+++ b/system/qtest.c
@@ -326,9 +326,6 @@ void qtest_sendf(CharFrontend *chr, const char *fmt, ...)
static void qtest_irq_handler(void *opaque, int n, int level)
{
- qemu_irq old_irq = *(qemu_irq *)opaque;
- qemu_set_irq(old_irq, level);
-
if (irq_levels[n] != level) {
CharFrontend *chr = &qtest->qtest_chr;
irq_levels[n] = level;
@@ -421,7 +418,7 @@ static void qtest_process_command(CharFrontend *chr, gchar **words)
interception_succeeded = true;
}
} else {
- qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
+ qemu_irq_set_observer(ngl->in, qtest_irq_handler,
ngl->num_in);
interception_succeeded = true;
}