ct3d_reset() re-initializes the primary CCI through the call chain
cxl_device_register_init_t3() -> cxl_initialize_mailbox_t3() ->
cxl_init_cci(), but never calls cxl_destroy_cci() first. Each reset
cycle therefore leaks the old timer and leaves the old mutex
undestroyed while silently overwriting the CCI state.
Per CXL r4.0, the "Mailbox Interfaces Ready" bit in the Memory Device
Status register (Table 8-212) is set after a Conventional Reset or CXL
Reset once the device has re-initialized its mailbox interfaces. The
CCI is the software abstraction of these interfaces and must be properly
torn down before re-initialization.
The secondary CCIs (vdm_fm_owned_ld_mctp_cci, ld0_cci) already follow
the correct destroy-before-reinit pattern in the same function; apply
the same discipline to the primary CCI.
Also destroy the secondary CCIs in ct3_exit() where they were
previously leaked at device removal time. Guard the primary CCI
teardown there with the same .initialized check used for the secondary
CCIs: the primary CCI is only brought up from the reset path
(cxl_device_register_init_t3()), so a device that is unrealized before
its first reset would otherwise tear down a never-initialized CCI.
Fixes: cac36a8faffc ("hw/cxl/mbox: Pull the CCI definition out of the
CXLDeviceState")
Cc: [email protected]
Signed-off-by: Junjie Cao <[email protected]>
---
hw/mem/cxl_type3.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index cba05ec57d..4ac6eaa950 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1073,7 +1073,15 @@ static void ct3_exit(PCIDevice *pci_dev)
cxl_doe_cdat_release(cxl_cstate);
msix_uninit_exclusive_bar(pci_dev);
g_free(regs->special_ops);
- cxl_destroy_cci(&ct3d->cci);
+ if (ct3d->cci.initialized) {
+ cxl_destroy_cci(&ct3d->cci);
+ }
+ if (ct3d->vdm_fm_owned_ld_mctp_cci.initialized) {
+ cxl_destroy_cci(&ct3d->vdm_fm_owned_ld_mctp_cci);
+ }
+ if (ct3d->ld0_cci.initialized) {
+ cxl_destroy_cci(&ct3d->ld0_cci);
+ }
if (ct3d->dc.host_dc) {
cxl_destroy_dc_regions(ct3d);
address_space_destroy(&ct3d->dc.host_dc_as);
@@ -1328,6 +1336,9 @@ static void ct3d_reset(DeviceState *dev)
ct3d->flitmode);
cxl_component_register_init_common(reg_state, write_msk,
CXL2_TYPE3_DEVICE, ct3d->hdmdb);
+ if (ct3d->cci.initialized) {
+ cxl_destroy_cci(&ct3d->cci);
+ }
cxl_device_register_init_t3(ct3d, CXL_T3_MSIX_MBOX);
/*
--
2.43.0