[PATCH] hw/misc/sifive_e_aon: Don't leak timer

Peter Maydell posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260309095129.1406506-1-peter.maydell@linaro.org
Maintainers: Alistair Francis <Alistair.Francis@wdc.com>, Palmer Dabbelt <palmer@dabbelt.com>
hw/misc/sifive_e_aon.c         | 16 ++++++++++++----
include/hw/misc/sifive_e_aon.h |  2 +-
2 files changed, 13 insertions(+), 5 deletions(-)
[PATCH] hw/misc/sifive_e_aon: Don't leak timer
Posted by Peter Maydell 1 month ago
The sifive_e_aon watchdog creates a timer with timer_new_ns() in its
instance_init method, but does not free it in instance_finalize.
This means that QMP introspection of the device leaks it:

Direct leak of 48 byte in 1 object allocated from:
    #0  in calloc
    #1  in g_malloc0
    #2  in timer_new_full /home/pm215/qemu/include/qemu/timer.h:520:21
    #3  in timer_new /home/pm215/qemu/include/qemu/timer.h:543:12
    #4  in timer_new_ns /home/pm215/qemu/include/qemu/timer.h:563:12
    #5  in sifive_e_aon_init /home/pm215/qemu/build/san/../../hw/misc/sifive_e_aon.c:286:21
    #6  in object_initialize_with_type /home/pm215/qemu/build/san/../../qom/object.c:570:5
    #7  in object_initialize /home/pm215/qemu/build/san/../../qom/object.c:578:5
    #8  in object_initialize_child_with_propsv /home/pm215/qemu/build/san/../../qom/object.c:608:5
    #9  in object_initialize_child_with_props /home/pm215/qemu/build/san/../../qom/object.c:591:10
    #10  in object_initialize_child_internal /home/pm215/qemu/build/san/../../qom/object.c:645:5
    #11  in object_initialize_with_type /home/pm215/qemu/build/san/../../qom/object.c:570:5
    #12  in object_new_with_type /home/pm215/qemu/build/san/../../qom/object.c:774:5
    #13  in qmp_device_list_properties /home/pm215/qemu/build/san/../../qom/qom-qmp-cmds.c:206:11

Allocating a separate QEMUTimer with timer_new() is not the preferred
interface (per the comments in include/qemu/timer.h); switch to an
inline struct initialized with timer_init(), which we can clean up
with timer_del() in finalize.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Incidentally I notice that this device doesn't have vmstate support,
which is unfortunate -- devices really ought to either support it
or else install a migration-blocker explaining why they can't.

 hw/misc/sifive_e_aon.c         | 16 ++++++++++++----
 include/hw/misc/sifive_e_aon.h |  2 +-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/misc/sifive_e_aon.c b/hw/misc/sifive_e_aon.c
index 0e82ae3758..e78f4f5672 100644
--- a/hw/misc/sifive_e_aon.c
+++ b/hw/misc/sifive_e_aon.c
@@ -94,9 +94,9 @@ static void sifive_e_aon_wdt_update_state(SiFiveEAONState *r)
         next += muldiv64((r->wdogcmp0 - wdogs) <<
                          FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, SCALE),
                          NANOSECONDS_PER_SECOND, r->wdogclk_freq);
-        timer_mod(r->wdog_timer, next);
+        timer_mod(&r->wdog_timer, next);
     } else {
-        timer_mod(r->wdog_timer, INT64_MAX);
+        timer_mod(&r->wdog_timer, INT64_MAX);
     }
 }
 
@@ -283,12 +283,19 @@ static void sifive_e_aon_init(Object *obj)
     sysbus_init_mmio(sbd, &r->mmio);
 
     /* watchdog timer */
-    r->wdog_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                 sifive_e_aon_wdt_expired_cb, r);
+    timer_init_ns(&r->wdog_timer, QEMU_CLOCK_VIRTUAL,
+                  sifive_e_aon_wdt_expired_cb, r);
     r->wdogclk_freq = SIFIVE_E_LFCLK_DEFAULT_FREQ;
     sysbus_init_irq(sbd, &r->wdog_irq);
 }
 
+static void sifive_e_aon_finalize(Object *obj)
+{
+    SiFiveEAONState *r = SIFIVE_E_AON(obj);
+
+    timer_del(&r->wdog_timer);
+}
+
 static const Property sifive_e_aon_properties[] = {
     DEFINE_PROP_UINT64("wdogclk-frequency", SiFiveEAONState, wdogclk_freq,
                        SIFIVE_E_LFCLK_DEFAULT_FREQ),
@@ -307,6 +314,7 @@ static const TypeInfo sifive_e_aon_info = {
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(SiFiveEAONState),
     .instance_init = sifive_e_aon_init,
+    .instance_finalize = sifive_e_aon_finalize,
     .class_init    = sifive_e_aon_class_init,
 };
 
diff --git a/include/hw/misc/sifive_e_aon.h b/include/hw/misc/sifive_e_aon.h
index efa2c3023f..e907aa7869 100644
--- a/include/hw/misc/sifive_e_aon.h
+++ b/include/hw/misc/sifive_e_aon.h
@@ -46,7 +46,7 @@ struct SiFiveEAONState {
     MemoryRegion mmio;
 
     /*< watchdog timer >*/
-    QEMUTimer *wdog_timer;
+    QEMUTimer wdog_timer;
     qemu_irq wdog_irq;
     uint64_t wdog_restart_time;
     uint64_t wdogclk_freq;
-- 
2.43.0
Re: [PATCH] hw/misc/sifive_e_aon: Don't leak timer
Posted by Philippe Mathieu-Daudé 1 month ago
On 9/3/26 10:51, Peter Maydell wrote:
> The sifive_e_aon watchdog creates a timer with timer_new_ns() in its
> instance_init method, but does not free it in instance_finalize.
> This means that QMP introspection of the device leaks it:
> 
> Direct leak of 48 byte in 1 object allocated from:
>      #0  in calloc
>      #1  in g_malloc0
>      #2  in timer_new_full /home/pm215/qemu/include/qemu/timer.h:520:21
>      #3  in timer_new /home/pm215/qemu/include/qemu/timer.h:543:12
>      #4  in timer_new_ns /home/pm215/qemu/include/qemu/timer.h:563:12
>      #5  in sifive_e_aon_init /home/pm215/qemu/build/san/../../hw/misc/sifive_e_aon.c:286:21
>      #6  in object_initialize_with_type /home/pm215/qemu/build/san/../../qom/object.c:570:5
>      #7  in object_initialize /home/pm215/qemu/build/san/../../qom/object.c:578:5
>      #8  in object_initialize_child_with_propsv /home/pm215/qemu/build/san/../../qom/object.c:608:5
>      #9  in object_initialize_child_with_props /home/pm215/qemu/build/san/../../qom/object.c:591:10
>      #10  in object_initialize_child_internal /home/pm215/qemu/build/san/../../qom/object.c:645:5
>      #11  in object_initialize_with_type /home/pm215/qemu/build/san/../../qom/object.c:570:5
>      #12  in object_new_with_type /home/pm215/qemu/build/san/../../qom/object.c:774:5
>      #13  in qmp_device_list_properties /home/pm215/qemu/build/san/../../qom/qom-qmp-cmds.c:206:11
> 
> Allocating a separate QEMUTimer with timer_new() is not the preferred
> interface (per the comments in include/qemu/timer.h); switch to an
> inline struct initialized with timer_init(), which we can clean up
> with timer_del() in finalize.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Incidentally I notice that this device doesn't have vmstate support,
> which is unfortunate -- devices really ought to either support it
> or else install a migration-blocker explaining why they can't.
> 
>   hw/misc/sifive_e_aon.c         | 16 ++++++++++++----
>   include/hw/misc/sifive_e_aon.h |  2 +-
>   2 files changed, 13 insertions(+), 5 deletions(-)

Patch queued via hw-misc, thanks.
Re: [PATCH] hw/misc/sifive_e_aon: Don't leak timer
Posted by Philippe Mathieu-Daudé 1 month ago
On 9/3/26 10:51, Peter Maydell wrote:
> The sifive_e_aon watchdog creates a timer with timer_new_ns() in its
> instance_init method, but does not free it in instance_finalize.
> This means that QMP introspection of the device leaks it:
> 
> Direct leak of 48 byte in 1 object allocated from:
>      #0  in calloc
>      #1  in g_malloc0
>      #2  in timer_new_full /home/pm215/qemu/include/qemu/timer.h:520:21
>      #3  in timer_new /home/pm215/qemu/include/qemu/timer.h:543:12
>      #4  in timer_new_ns /home/pm215/qemu/include/qemu/timer.h:563:12
>      #5  in sifive_e_aon_init /home/pm215/qemu/build/san/../../hw/misc/sifive_e_aon.c:286:21
>      #6  in object_initialize_with_type /home/pm215/qemu/build/san/../../qom/object.c:570:5
>      #7  in object_initialize /home/pm215/qemu/build/san/../../qom/object.c:578:5
>      #8  in object_initialize_child_with_propsv /home/pm215/qemu/build/san/../../qom/object.c:608:5
>      #9  in object_initialize_child_with_props /home/pm215/qemu/build/san/../../qom/object.c:591:10
>      #10  in object_initialize_child_internal /home/pm215/qemu/build/san/../../qom/object.c:645:5
>      #11  in object_initialize_with_type /home/pm215/qemu/build/san/../../qom/object.c:570:5
>      #12  in object_new_with_type /home/pm215/qemu/build/san/../../qom/object.c:774:5
>      #13  in qmp_device_list_properties /home/pm215/qemu/build/san/../../qom/qom-qmp-cmds.c:206:11
> 
> Allocating a separate QEMUTimer with timer_new() is not the preferred
> interface (per the comments in include/qemu/timer.h); switch to an
> inline struct initialized with timer_init(), which we can clean up
> with timer_del() in finalize.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Incidentally I notice that this device doesn't have vmstate support,
> which is unfortunate -- devices really ought to either support it
> or else install a migration-blocker explaining why they can't.
> 
>   hw/misc/sifive_e_aon.c         | 16 ++++++++++++----
>   include/hw/misc/sifive_e_aon.h |  2 +-
>   2 files changed, 13 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>