[PATCH v3 5/7] hw/cxl: discard in-flight sanitize state on mailbox teardown

Junjie Cao <[email protected]>
Newsgroups gmane.comp.emulators.qemu.stable,gmane.comp.emulators.qemu
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.