Commit 0ddbce88c4 for qemu.org

commit 0ddbce88c45a7376a9fc948097d58195358ffec7
Author: Junjie Cao <junjie.cao@intel.com>
Date:   Mon Aug 31 10:23:02 2026 +0800

    hw/cxl: fix the CDAT DOE overlapping the Flex Bus DVSEC when sn= is set

    ct3_realize() adds the CDAT DOE at a fixed 0x190.  Since 8700ee15de the
    four DVSECs take 0x90 bytes, which from 0x100 ends exactly at 0x190.
    With sn= the Device Serial Number capability pushes the block to
    0x10c..0x19c, and the DOE, added later, overwrites the last 12 bytes of
    the Flex Bus Port DVSEC: Capability2, Control2 and Status2.  Nothing
    catches this -- pcie_add_capability() checks bounds, not overlap, and
    the chain still walks because the DVSEC's next pointer becomes 0x190,
    inside its own body.  Most cxl-type3 examples in
    docs/system/devices/cxl.rst set sn=.

    Derive the offset from the DVSEC block instead, as cxl_upstream.c
    already does.  Without sn= the layout is unchanged byte for byte; with
    sn= the DOE moves to 0x19c, below the AER capability at 0x200.  The
    type 3 device has no VMStateDescription, so its config space never
    reaches the migration stream.

    Fixes: 8700ee15de ("hw/cxl: Standardize all references on CXL r3.1 and minor updates")
    Signed-off-by: Junjie Cao <junjie.cao@intel.com>
    Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Message-ID: <20260831022302.406740-1-junjie.cao@intel.com>

diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 6f44770db6..a04dc74ecc 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -936,8 +936,8 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
     }

     /* DOE Initialization */
-    pcie_doe_init(pci_dev, &ct3d->doe_cdat, 0x190, doe_cdat_prot, true,
-                  CXL_T3_MSIX_PCIE_DOE_TABLE_ACCESS);
+    pcie_doe_init(pci_dev, &ct3d->doe_cdat, cxl_cstate->dvsec_offset,
+                  doe_cdat_prot, true, CXL_T3_MSIX_PCIE_DOE_TABLE_ACCESS);

     cxl_cstate->cdat.build_cdat_table = ct3_build_cdat_table;
     cxl_cstate->cdat.free_cdat_table = ct3_free_cdat_table;