]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl/pci: Convert PCIBIOS errors to errno on DVSEC config accesses
authorDave Jiang <dave.jiang@intel.com>
Thu, 4 Jun 2026 18:01:54 +0000 (11:01 -0700)
committerDave Jiang <dave.jiang@intel.com>
Thu, 4 Jun 2026 23:01:01 +0000 (16:01 -0700)
PCI config space accessors return positive PCIBIOS_* status codes on
failure that are positive integers. Several DVSEC accesses in the CXL
core propagated these raw values to callers that test for failure against
less than 0. Thus silently misinterpret the return value as success.

Convert the positive error values to negative errno values so the checks
are correct on error paths.

While the chances of a config access failure are low, fix for correctness
and to avoid confusion in the future when more DVSEC accesses are added.

Fixes: 14d788740774 ("cxl/mem: Consolidate CXL DVSEC Range enumeration in the core")
Fixes: ce17ad0d5498 ("cxl: Wait Memory_Info_Valid before access memory related info")
Reviewed-by: Richard Cheng <icheng@nvidia.com>
Reviewed-by: Jonathan Cameron <jic23@kernel.org>
Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Link: https://patch.msgid.link/20260604180154.1925149-3-dave.jiang@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/core/pci.c

index 43885c59a7f2461f1834cdfcec5eab9390415f86..e4338fd7e01b472132866c51cd0303da84983f9d 100644 (file)
@@ -89,7 +89,7 @@ static int cxl_dvsec_mem_range_valid(struct cxl_dev_state *cxlds, int id)
                                           d + PCI_DVSEC_CXL_RANGE_SIZE_LOW(id),
                                           &temp);
                if (rc)
-                       return rc;
+                       return pcibios_err_to_errno(rc);
 
                valid = FIELD_GET(PCI_DVSEC_CXL_MEM_INFO_VALID, temp);
                if (valid)
@@ -123,7 +123,7 @@ static int cxl_dvsec_mem_range_active(struct cxl_dev_state *cxlds, int id)
                rc = pci_read_config_dword(
                        pdev, d + PCI_DVSEC_CXL_RANGE_SIZE_LOW(id), &temp);
                if (rc)
-                       return rc;
+                       return pcibios_err_to_errno(rc);
 
                active = FIELD_GET(PCI_DVSEC_CXL_MEM_ACTIVE, temp);
                if (active)
@@ -156,7 +156,7 @@ int cxl_await_media_ready(struct cxl_dev_state *cxlds)
        rc = pci_read_config_word(pdev,
                                  d + PCI_DVSEC_CXL_CAP, &cap);
        if (rc)
-               return rc;
+               return pcibios_err_to_errno(rc);
 
        hdm_count = FIELD_GET(PCI_DVSEC_CXL_HDM_COUNT, cap);
        for (i = 0; i < hdm_count; i++) {
@@ -275,7 +275,7 @@ int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds,
 
        rc = pci_read_config_word(pdev, d + PCI_DVSEC_CXL_CAP, &cap);
        if (rc)
-               return rc;
+               return pcibios_err_to_errno(rc);
 
        if (!(cap & PCI_DVSEC_CXL_MEM_CAPABLE)) {
                dev_dbg(dev, "Not MEM Capable\n");
@@ -299,7 +299,7 @@ int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds,
         */
        rc = pci_read_config_word(pdev, d + PCI_DVSEC_CXL_CTRL, &ctrl);
        if (rc)
-               return rc;
+               return pcibios_err_to_errno(rc);
 
        info->mem_enabled = FIELD_GET(PCI_DVSEC_CXL_MEM_ENABLE, ctrl);
        if (!info->mem_enabled)
@@ -316,14 +316,14 @@ int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds,
                rc = pci_read_config_dword(
                        pdev, d + PCI_DVSEC_CXL_RANGE_SIZE_HIGH(i), &temp);
                if (rc)
-                       return rc;
+                       return pcibios_err_to_errno(rc);
 
                size = (u64)temp << 32;
 
                rc = pci_read_config_dword(
                        pdev, d + PCI_DVSEC_CXL_RANGE_SIZE_LOW(i), &temp);
                if (rc)
-                       return rc;
+                       return pcibios_err_to_errno(rc);
 
                size |= temp & PCI_DVSEC_CXL_MEM_SIZE_LOW;
                if (!size) {
@@ -333,14 +333,14 @@ int cxl_dvsec_rr_decode(struct cxl_dev_state *cxlds,
                rc = pci_read_config_dword(
                        pdev, d + PCI_DVSEC_CXL_RANGE_BASE_HIGH(i), &temp);
                if (rc)
-                       return rc;
+                       return pcibios_err_to_errno(rc);
 
                base = (u64)temp << 32;
 
                rc = pci_read_config_dword(
                        pdev, d + PCI_DVSEC_CXL_RANGE_BASE_LOW(i), &temp);
                if (rc)
-                       return rc;
+                       return pcibios_err_to_errno(rc);
 
                base |= temp & PCI_DVSEC_CXL_MEM_BASE_LOW;