hw/misc/sifive_e_aon: Don't leak timer
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>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20260309095129.1406506-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
committed by
Philippe Mathieu-Daudé
parent
8a16a38f3d
commit
ac9dde499e
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user