On Sat, Mar 7, 2026 at 10:53 PM Peter Maydell <[email protected]> wrote:
>
> The riscv-iommu device makes various allocations in its
> instance_init method. These will leak when QMP inits an
> object of this type to introspect it, as can be seen if you
> run 'make check' with the address sanitizer enabled:
>
> Direct leak of 4096 byte(s) in 1 object(s) allocated from:
> #0 0x5d8415b6ed9d in calloc
> (/home/pm215/qemu/build/san/qemu-system-riscv32+0x1832d9d) (BuildId:
> fedcc313e48ba803d63837329c37fd609dd50849)
> #1 0x75c0502f1771 in g_malloc0
> (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x63771) (BuildId:
> 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
> #2 0x5d8416d09391 in riscv_iommu_instance_init
> /home/pm215/qemu/build/san/../../hw/riscv/riscv-iommu.c:2463:18
> #3 0x5d841710483f in object_initialize_with_type
> /home/pm215/qemu/build/san/../../qom/object.c:570:5
> #4 0x5d8417104ee9 in object_initialize
> /home/pm215/qemu/build/san/../../qom/object.c:578:5
> #5 0x5d8417104ee9 in object_initialize_child_with_propsv
> /home/pm215/qemu/build/san/../../qom/object.c:608:5
> #6 0x5d8417104db1 in object_initialize_child_with_props
> /home/pm215/qemu/build/san/../../qom/object.c:591:10
> #7 0x5d8417106506 in object_initialize_child_internal
> /home/pm215/qemu/build/san/../../qom/object.c:645:5
> #8 0x5d8416d16a12 in riscv_iommu_sys_init
> /home/pm215/qemu/build/san/../../hw/riscv/riscv-iommu-sys.c:199:5
> #9 0x5d841710483f in object_initialize_with_type
> /home/pm215/qemu/build/san/../../qom/object.c:570:5
> #10 0x5d841710661f in object_new_with_type
> /home/pm215/qemu/build/san/../../qom/object.c:774:5
> #11 0x5d841755d956 in qmp_device_list_properties
> /home/pm215/qemu/build/san/../../qom/qom-qmp-cmds.c:206:11
>
> (and other similar backtraces).
>
> Fix these by freeing the resources we allocate in instance_init in
> instance_finalize. In some cases we were freeing these in unrealize,
> and in some cases not at all.
>
> Signed-off-by: Peter Maydell <[email protected]>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> hw/riscv/riscv-iommu.c | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 98345b1280..225394ea83 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -2479,6 +2479,18 @@ static void riscv_iommu_instance_init(Object *obj)
> QLIST_INIT(&s->spaces);
> }
>
> +static void riscv_iommu_instance_finalize(Object *obj)
> +{
> + RISCVIOMMUState *s = RISCV_IOMMU(obj);
> +
> + g_free(s->regs_rw);
> + g_free(s->regs_ro);
> + g_free(s->regs_wc);
> +
> + g_hash_table_unref(s->ctx_cache);
> + g_hash_table_unref(s->iot_cache);
> +}
> +
> static void riscv_iommu_realize(DeviceState *dev, Error **errp)
> {
> RISCVIOMMUState *s = RISCV_IOMMU(dev);
> @@ -2597,9 +2609,6 @@ static void riscv_iommu_unrealize(DeviceState *dev)
> {
> RISCVIOMMUState *s = RISCV_IOMMU(dev);
>
> - g_hash_table_unref(s->iot_cache);
> - g_hash_table_unref(s->ctx_cache);
> -
> if (s->cap & RISCV_IOMMU_CAP_HPM) {
> g_hash_table_unref(s->hpm_event_ctr_map);
> timer_free(s->hpm_timer);
> @@ -2675,6 +2684,7 @@ static const TypeInfo riscv_iommu_info = {
> .parent = TYPE_DEVICE,
> .instance_size = sizeof(RISCVIOMMUState),
> .instance_init = riscv_iommu_instance_init,
> + .instance_finalize = riscv_iommu_instance_finalize,
> .class_init = riscv_iommu_class_init,
> };
>
> --
> 2.43.0
>
>