Messages in this thread Patch in this message | | | From | Robert Richter <> | Subject | [PATCH v3 5/9] cxl/pci: Only register RCDs with device 0, function 0 as CXL memory device | Date | Wed, 9 Nov 2022 11:40:55 +0100 |
| |
The Device 0, Function 0 DVSEC controls the CXL functionality of the entire device. Add a check to prevent registration of any other PCI device on the bus as a CXL memory device.
Signed-off-by: Robert Richter <rrichter@amd.com> --- drivers/cxl/pci.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index faeb5d9d7a7a..cc4f206f24b3 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -428,11 +428,26 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) } } +static int check_restricted_device(struct pci_dev *pdev, u16 pcie_dvsec) +{ + if (pci_pcie_type(pdev) != PCI_EXP_TYPE_RC_END) + return 0; /* no RCD */ + + if (pdev->devfn == PCI_DEVFN(0, 0) && pcie_dvsec) + return 0; /* ok */ + + dev_warn(&pdev->dev, "Skipping RCD: devfn=0x%02x dvsec=%u\n", + pdev->devfn, pcie_dvsec); + + return -ENODEV; +} + static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct cxl_register_map map; struct cxl_memdev *cxlmd; struct cxl_dev_state *cxlds; + u16 pcie_dvsec; int rc; /* @@ -442,6 +457,13 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) BUILD_BUG_ON(offsetof(struct cxl_regs, memdev) != offsetof(struct cxl_regs, device_regs.memdev)); + pcie_dvsec = pci_find_dvsec_capability( + pdev, PCI_DVSEC_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE); + + rc = check_restricted_device(pdev, pcie_dvsec); + if (rc) + return rc; + rc = pcim_enable_device(pdev); if (rc) return rc; @@ -451,8 +473,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return PTR_ERR(cxlds); cxlds->serial = pci_get_dsn(pdev); - cxlds->cxl_dvsec = pci_find_dvsec_capability( - pdev, PCI_DVSEC_VENDOR_ID_CXL, CXL_DVSEC_PCIE_DEVICE); + cxlds->cxl_dvsec = pcie_dvsec; if (!cxlds->cxl_dvsec) dev_warn(&pdev->dev, "Device DVSEC not present, skip CXL.mem init\n"); -- 2.30.2
| |