Per CXL r4.0 Section 8.2.9.4, "Background commands do not continue to execute across Conventional Resets." If a Media Operations sanitize is in progress when the device is reset, the background timer is cancelled and freed via cxl_destroy_cci(), but the per-operation state (media_op_sanitize) is heap-allocated separately and would be leaked.
Free it from cxl_destroy_mailbox_t3(): the timer that advances the operation lives in the CCI torn down there, so the operation can never complete once the mailbox is gone; preserving the heap state has no benefit and would leak it the next time media_op_sanitize is assigned. Routing the discard through the mailbox teardown also covers device unrealize, where ct3_exit() previously leaked an in-flight sanitize. The completion path in __do_sanitize() frees the same state; factor the free into a cxl_discard_media_op_sanitize() helper used by both places, so the whole media_op_sanitize lifecycle now stays within cxl-mailbox-utils.c. Note that Section 8.2.10.9.5.1 additionally requires a device whose Sanitize was interrupted by reset to remain in the Media Disabled state until a successful Sanitize completes. That latch is not modelled here (reset re-enables media via memdev_reg_init_common()) and is left for future work; this patch only addresses the resource leak. Suggested-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Junjie Cao <[email protected]> --- hw/cxl/cxl-mailbox-utils.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index bc00fec9f8..cbd6ebf9fe 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -2636,6 +2636,12 @@ static int sanitize_range(CXLType3Dev *ct3d, uint64_t dpa_addr, size_t length, return address_space_set(as, dpa_addr, fill_value, length, mem_attrs); } +static void cxl_discard_media_op_sanitize(CXLType3Dev *ct3d) +{ + g_free(ct3d->media_op_sanitize); + ct3d->media_op_sanitize = NULL; +} + /* Perform the actual device zeroing */ static void __do_sanitize(CXLType3Dev *ct3d) { @@ -2653,8 +2659,7 @@ static void __do_sanitize(CXLType3Dev *ct3d) } } exit: - g_free(ct3d->media_op_sanitize); - ct3d->media_op_sanitize = NULL; + cxl_discard_media_op_sanitize(ct3d); return; } @@ -4848,6 +4853,12 @@ void cxl_destroy_mailbox_t3(CXLType3Dev *ct3d) if (ct3d->cci.initialized) { cxl_destroy_cci(&ct3d->cci); } + /* + * An in-flight Media Operations sanitize is only advanced by this CCI's + * background timer; with the CCI gone the operation can never complete, + * so its state would otherwise be leaked (CXL r4.0 Section 8.2.9.4). + */ + cxl_discard_media_op_sanitize(ct3d); } static const struct cxl_cmd cxl_cmd_set_t3_ld[256][256] = { -- 2.43.0
