Skip to content

Commit 60073ea

Browse files
AlisonSchofieldsmb49
authored andcommitted
cxl/region: Avoid null pointer dereference in region lookup
BugLink: https://bugs.launchpad.net/bugs/2076435 [ Upstream commit 285f2a0 ] cxl_dpa_to_region() looks up a region based on a memdev and DPA. It wrongly assumes an endpoint found mapping the DPA is also of a fully assembled region. When not true it leads to a null pointer dereference looking up the region name. This appears during testing of region lookup after a failure to assemble a BIOS defined region or if the lookup raced with the assembly of the BIOS defined region. Failure to clean up BIOS defined regions that fail assembly is an issue in itself and a fix to that problem will alleviate some of the impact. It will not alleviate the race condition so let's harden this path. The behavior change is that the kernel oops due to a null pointer dereference is replaced with a dev_dbg() message noting that an endpoint was mapped. Additional comments are added so that future users of this function can more clearly understand what it provides. Fixes: 0a105ab ("cxl/memdev: Warn of poison inject or clear to a mapped region") Signed-off-by: Alison Schofield <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Dave Jiang <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Portia Stephens <[email protected]> Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent 325e0df commit 60073ea

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

drivers/cxl/core/region.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2519,22 +2519,33 @@ static int __cxl_dpa_to_region(struct device *dev, void *arg)
25192519
{
25202520
struct cxl_dpa_to_region_context *ctx = arg;
25212521
struct cxl_endpoint_decoder *cxled;
2522+
struct cxl_region *cxlr;
25222523
u64 dpa = ctx->dpa;
25232524

25242525
if (!is_endpoint_decoder(dev))
25252526
return 0;
25262527

25272528
cxled = to_cxl_endpoint_decoder(dev);
2528-
if (!cxled->dpa_res || !resource_size(cxled->dpa_res))
2529+
if (!cxled || !cxled->dpa_res || !resource_size(cxled->dpa_res))
25292530
return 0;
25302531

25312532
if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start)
25322533
return 0;
25332534

2534-
dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
2535-
dev_name(&cxled->cxld.region->dev));
2535+
/*
2536+
* Stop the region search (return 1) when an endpoint mapping is
2537+
* found. The region may not be fully constructed so offering
2538+
* the cxlr in the context structure is not guaranteed.
2539+
*/
2540+
cxlr = cxled->cxld.region;
2541+
if (cxlr)
2542+
dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
2543+
dev_name(&cxlr->dev));
2544+
else
2545+
dev_dbg(dev, "dpa:0x%llx mapped in endpoint:%s\n", dpa,
2546+
dev_name(dev));
25362547

2537-
ctx->cxlr = cxled->cxld.region;
2548+
ctx->cxlr = cxlr;
25382549

25392550
return 1;
25402551
}

0 commit comments

Comments
 (0)