From: Manish Honap <[email protected]> The firmware decoder setup added later in this series commits only the pxb-cxl and device decoders, and cxl_cfmws_find_device() routes only to devfn 0 below a port. Refuse any other placement.
AI-used-for: code (prototype) Signed-off-by: Manish Honap <[email protected]> --- hw/mem/cxl_type2.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/mem/cxl_type2.c b/hw/mem/cxl_type2.c index 60f3f04679..ab89d332dc 100644 --- a/hw/mem/cxl_type2.c +++ b/hw/mem/cxl_type2.c @@ -11,6 +11,8 @@ #include "hw/core/qdev-properties.h" #include "hw/cxl/cxl.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/pcie_port.h" #include "migration/vmstate.h" #include "system/hostmem.h" @@ -22,6 +24,29 @@ static void clean_memory(PCIDevice *pci_dev) host_memory_backend_set_mapped(ct2d->hostvmem, false); } +/* + * The firmware decoder setup covers only the host bridge and the device, and + * cxl_cfmws_find_device() routes only to devfn 0 below a port. + */ +static bool cxl_type2_check_topology(PCIDevice *pci_dev, Error **errp) +{ + PCIDevice *rp = pci_get_bus(pci_dev)->parent_dev; + PCIDevice *host = rp ? pci_get_bus(rp)->parent_dev : NULL; + + if (!rp || !pci_is_cxl(rp) || + !object_dynamic_cast(OBJECT(rp), TYPE_PCIE_ROOT_PORT) || !host || + !object_dynamic_cast(OBJECT(host), TYPE_PXB_CXL_DEV)) { + error_setg(errp, "cxl-type2 must be directly below a CXL root port " + "of a pxb-cxl"); + return false; + } + if (pci_dev->devfn != 0) { + error_setg(errp, "cxl-type2 must be at slot 0, function 0"); + return false; + } + return true; +} + static bool setup_memory(PCIDevice *pci_dev, Error **errp) { CXLType2Dev *ct2d = CXL_TYPE2(pci_dev); @@ -190,7 +215,8 @@ static void setup_cxl_regs(PCIDevice *pci_dev) static void cxl_type2_realize(PCIDevice *pci_dev, Error **errp) { - if (!setup_memory(pci_dev, errp)) { + if (!cxl_type2_check_topology(pci_dev, errp) || + !setup_memory(pci_dev, errp)) { return; } -- 2.53.0
