@samitouri / QOSamiQemu / commits / 5fad2038aa

target/mips: Free mvp in unrealize

We allocate memory for cpu->mvp in mips_cpu_realizefn(), but we never free it, which causes memory leaks like this: Direct leak of 24 byte(s) in 2 object(s) allocated from: #0 0x5f9458e61c8d in calloc (/home/pm215/qemu/build/san/qemu-mips+0x4d8c8d) (BuildId: 4153e33b3d08657a71ce2a04a82d0c2954966d9c) #1 0x74761891a771 in g_malloc0 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x63771) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3) #2 0x5f94590687aa in mvp_init /home/pm215/qemu/build/san/../../target/mips/cpu-defs.c.inc:1037:16 #3 0x5f94590687aa in mips_cpu_realizefn /home/pm215/qemu/build/san/../../target/mips/cpu.c:489:5 #4 0x5f9459366a3a in device_set_realized /home/pm215/qemu/build/san/../../hw/core/qdev.c:523:13 #5 0x5f9459380a49 in property_set_bool /home/pm215/qemu/build/san/../../qom/object.c:2376:5 #6 0x5f945937bace in object_property_set /home/pm215/qemu/build/san/../../qom/object.c:1450:5 #7 0x5f945938816c in object_property_set_qobject /home/pm215/qemu/build/san/../../qom/qom-qobject.c:28:10 #8 0x5f94592cc100 in cpu_copy /home/pm215/qemu/build/san/../../linux-user/main.c:240:25 #9 0x5f9459309931 in do_syscall1 /home/pm215/qemu/build/san/../../linux-user/syscall.c #10 0x5f94593058d8 in do_syscall /home/pm215/qemu/build/san/../../linux-user/syscall.c:14422:15 #11 0x5f945905c73e in cpu_loop /home/pm215/qemu/build/san/../../linux-user/mips/cpu_loop.c:124:23 for linux-user, where each new guest thread is a new CPU object that we need to destroy on thread exit. Add an unrealize method which frees this memory. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260317175031.3035740-3-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Peter Maydell committed Mar 17, 2026 at 17:50 UTC 5fad2038aaffd27db456c6444027718695f8edc3
2 files changed +13
target/mips/cpu.c
+12
@@ -502,6 +502,16 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
502 mcc->parent_realize(dev, errp);
503 }
504
505 +static void mips_cpu_unrealizefn(DeviceState *dev)
506 +{
507 + MIPSCPU *cpu = MIPS_CPU(dev);
508 + MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
509 +
510 + g_free(cpu->mvp);
511 +
512 + mcc->parent_unrealize(dev);
513 +}
514 +
515 static void mips_cpu_initfn(Object *obj)
516 {
517 MIPSCPU *cpu = MIPS_CPU(obj);
@@ -606,6 +616,8 @@ static void mips_cpu_class_init(ObjectClass *c, const void *data)
616 device_class_set_props(dc, mips_cpu_properties);
617 device_class_set_parent_realize(dc, mips_cpu_realizefn,
618 &mcc->parent_realize);
619 + device_class_set_parent_unrealize(dc, mips_cpu_unrealizefn,
620 + &mcc->parent_unrealize);
621 resettable_class_set_parent_phases(rc, NULL, mips_cpu_reset_hold, NULL,
622 &mcc->parent_phases);
623
target/mips/cpu.h
+1
@@ -1225,6 +1225,7 @@ struct MIPSCPUClass {
1225 CPUClass parent_class;
1226
1227 DeviceRealize parent_realize;
1228 + DeviceUnrealize parent_unrealize;
1229 ResettablePhases parent_phases;
1230 const struct mips_def_t *cpu_def;
1231