cxl_init_cci() allocates a QEMUTimer via timer_new_ms() but
cxl_destroy_cci() never frees it. This leaks a timer object on every
device exit path and, more critically, on every device reset cycle since
the secondary CCIs (vdm_fm_owned_ld_mctp_cci, ld0_cci) are destroyed
and re-initialized each time ct3d_reset() runs.
Free the timer with timer_free(), which cancels any pending expiry via
timer_del() internally and tolerates a NULL pointer, then clear the
field so that a repeated timer_free() on the same CCI is a safe no-op.
(The function as a whole is not idempotent: it also calls
qemu_mutex_destroy(), which asserts on an already-destroyed mutex.
Callers must not invoke cxl_destroy_cci() twice; the .initialized guard
added in the next patch enforces that.)
Fixes: 98cbac128f1c ("hw/cxl: Support aborting background commands")
Cc: [email protected]
Signed-off-by: Junjie Cao <[email protected]>
---
hw/cxl/cxl-mailbox-utils.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 20e0b7e476..18a455e89c 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -4770,6 +4770,8 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max)
void cxl_destroy_cci(CXLCCI *cci)
{
+ timer_free(cci->bg.timer);
+ cci->bg.timer = NULL;
qemu_mutex_destroy(&cci->bg.lock);
cci->initialized = false;
}
--
2.43.0