summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJonathan Cameron <Jonathan.Cameron@huawei.com>2022-08-18 18:42:10 +0200
committerDan Williams <dan.j.williams@intel.com>2022-10-21 01:28:53 +0200
commit2816e24b0510e0c185c0c46acff1ce7aa4c4443f (patch)
treea9778e38a4b69218064b1e9e7b5ec830e56e74a6 /drivers
parentcxl/mbox: Add a check on input payload size (diff)
downloadlinux-2816e24b0510e0c185c0c46acff1ce7aa4c4443f.tar.xz
linux-2816e24b0510e0c185c0c46acff1ce7aa4c4443f.zip
cxl/region: Fix null pointer dereference due to pass through decoder commit
Not all decoders have a commit callback. The CXL specification allows a host bridge with a single root port to have no explicit HDM decoders. Currently the region driver assumes there are none. As such the CXL core creates a special pass through decoder instance without a commit callback. Prior to this patch, the ->commit() callback was called unconditionally. Thus a configuration with 1 Host Bridge, 1 Root Port, 1 switch with multiple downstream ports below which there are multiple CXL type 3 devices results in a situation where committing the region causes a null pointer dereference. Reported-by: Bobo WL <lmw.bobo@gmail.com> Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware") Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Vishal Verma <vishal.l.verma@intel.com> Link: https://lore.kernel.org/r/20220818164210.2084-1-Jonathan.Cameron@huawei.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cxl/core/region.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 401148016978..c49d9a5f1091 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -174,7 +174,8 @@ static int cxl_region_decode_commit(struct cxl_region *cxlr)
iter = to_cxl_port(iter->dev.parent)) {
cxl_rr = cxl_rr_load(iter, cxlr);
cxld = cxl_rr->decoder;
- rc = cxld->commit(cxld);
+ if (cxld->commit)
+ rc = cxld->commit(cxld);
if (rc)
break;
}